Documentation > Administration > Phase 9 Stabilization

Phase 9 Stabilization — Release Notes

What changed in v2.1.0.0. Phase 9 is a polish-and-fix release that follows the Phase 8 (v2.0.0.0) Foundation Features drop — no new endpoints, no schema migrations, focused on UX, a high-impact bug fix, and bundle / test-coverage cleanups.

What's new in v2.1.0.0

  • Scrollable nav and action bars — the top main menu, Settings tabs, and the Hosts-page action bar now pan with prev/next arrows when the viewport is too narrow to show every item, and labels like OS Upgrades never break across two lines.
  • Report branding fix — Phase 8.7 introduced org branding for generated reports, but the OSS report endpoint was constructing the Pro+ generators without the ORM models reference, which silently disabled the branding lookup at render time. Reports now carry the configured logo, company name, and header text as designed.
  • Frontend bundle split — the Vite build now splits vendor code into discrete chunks (React, MUI core, MUI DataGrid, MUI Charts, MUI Icons, i18next, axios, react-icons, Emotion). The main app chunk dropped from roughly 829 KB to 571 KB, and the build no longer trips the 700 KB chunk-size warning.
  • Test-coverage push — 83 new endpoint-coverage tests added for previously thin areas (diagnostics, host account management, antivirus status / defaults, firewall status, third-party repos, user preferences, reports, secrets, Graylog integration, scripts, host monitoring, OpenTelemetry, packages-operations, queue, host hostname, host Graylog).
  • Lint / scan clean — Pylint 10.00/10, ESLint 0 errors, SonarQube scan passes. No skipped tests in the suite.

UI: Scrollable Navigation

Three places previously wrapped or hid items when the viewport got narrow:

  1. Top main menu (Dashboard / Hosts / Updates / OS Upgrades / ...) — items used to wrap mid-label (e.g. OS Upgrades would split across two lines). The menu is now wrapped in a ScrollableNavList that keeps every label on one line and exposes left/right scroll arrows when overflow occurs.
  2. Settings tabs (Integrations / Access Groups / Update Profiles / ...) — the MUI Tabs component is now configured with variant="scrollable" scrollButtons="auto" allowScrollButtonsMobile, matching the in-app HostDetail tab strip.
  3. Hosts-page action bar (Approve Selected / Reboot / Update Agent / ...) — the bottom button row now uses ScrollableButtonBar, which forces white-space: nowrap on every MuiButton child and shows MUI-styled scroll arrows on overflow.

Behavior is identical across desktop and mobile: arrows hide when the row fits, appear with a fade when it doesn't, and the focus order skips hidden arrows so keyboard navigation stays clean.

Bug fix: Report branding now appears on generated reports

If you uploaded a logo or saved a company name under Settings → Report Branding after Phase 8.7 shipped and didn't see it on subsequent reports, this is the fix. Background:

  • Phase 8.7's Pro+ reporting_engine looks up the ReportBranding singleton via the ORM at render time, which requires it to receive the models module from the OSS endpoint code that constructs the generators.
  • The OSS endpoint code (backend/api/reports/endpoints.py) was instantiating HtmlReportGeneratorImpl, HostsReportGeneratorImpl, and UsersReportGeneratorImpl without passing models=, so the engine's branding lookup silently no-op'd.
  • v2.1.0.0 passes models=models to all three generator constructors. Both the /view/... (HTML) and /generate/... (PDF) endpoints now render with branding when a row exists in report_branding.

No action required for upgraders. Existing branding rows render automatically after upgrade. If you previously worked around the issue by re-uploading the logo, you can remove the duplicate row with the existing Delete Logo action.

Bug fix: Audit-log report used the wrong generator

A latent bug in the same endpoint module routed GET /api/reports/generate/audit-log to HostsReportGeneratorImpl.generate_audit_log_report, which doesn't exist. The route now correctly calls UsersReportGeneratorImpl.generate_audit_log_report. The HTML /view/audit-log path was unaffected.

Performance: Frontend bundle

The Vite config (frontend/vite.config.ts) now uses an id-based manualChunks function that aggressively splits anything in node_modules into discrete vendor buckets:

  • vendor-react — React, ReactDOM, React Router
  • vendor-mui-data-grid — MUI X DataGrid
  • vendor-mui-charts — MUI X Charts
  • vendor-mui-icons — Material-UI icons
  • vendor-mui — MUI core (material, system, styled-engine, lab, utils, private-theming)
  • vendor-i18n — i18next + react-i18next
  • vendor-axios, vendor-icons, vendor-emotion
  • vendor — everything else from node_modules

Result: the main index-*.js chunk is now ~571 KB (down from ~829 KB), and re-deploys don't bust caches for unchanged vendor code. The 700 KB chunk-size warning no longer trips during build.

Quality: Lint, tests, SonarQube

The Phase 9 closeout enforces a "100% clean" bar:

  • Pylint — 10.00/10 across the whole backend and agent codebase.
  • ESLint — 0 errors, 0 warnings on the frontend (--max-warnings 0).
  • Backend tests — 4441 pytest cases, all passing. Coverage 76% (the 80% target was aspirational; SonarQube has no hard coverage gate, and the residual gap is concentrated in startup-lifecycle and Graylog/Grafana integration paths that need a live external service to exercise meaningfully).
  • Agent tests — 93% coverage, exceeds the 80% Phase 9 target.
  • Frontend tests — Vitest passes with the new ResizeObserver polyfill in setupTests.ts (jsdom doesn't ship one and the new ScrollableNavList / ScrollableButtonBar components instantiate one inside useEffect).
  • SonarQubemake sonarqube-scan reports EXECUTION SUCCESS. No new issues introduced.

Migration notes

None. v2.1.0.0 ships zero schema changes: no new tables, no new columns, no Alembic migrations. The upgrade is a drop-in replacement of the server binaries and frontend bundle. Agents do not need to be re-deployed.

If you are upgrading from a release older than v2.0.0.0, follow the Phase 8 operator guide first to understand the Foundation Features and any Phase 8 schema migrations they introduced.

Troubleshooting

"My report still doesn't show branding after upgrading"

  1. Verify a branding row exists: Settings → Report Branding should show your logo / company name. If the form is empty, the singleton was never persisted — fill it in and save.
  2. Confirm the Pro+ reporting_engine module loaded successfully. Without it, OSS deployments return 402 from /api/reports/generate/... and /api/reports/view/...; the branding lookup is a Pro+ codepath.
  3. Hard-refresh your browser cache on the report-viewer page — the in-page iframe can serve a cached pre-fix HTML.
  4. Re-generate one report and inspect the audit_log row: a successful render writes an entry whose details JSON includes {"branding_applied": true}.

"My nav arrows don't appear even though items are clipped"

  1. The arrows only render when the inner scroller's scrollWidth exceeds its clientWidth. If the nav is fitting via word-wrap (older versions), browser zoom can mask overflow — set zoom to 100% and confirm.
  2. Verify your browser supports ResizeObserver (every supported browser does — IE11 isn't a target).
  3. If the arrows render but never become enabled, check the browser console for CSS errors against scrollnav / ScrollableButtonBar rules.

"Frontend bundle build is slow / fails"

  1. The new manualChunks only runs at build time and adds <1 s to the Vite build — if it fails, the most common cause is a stale node_modules; rm -rf frontend/node_modules && npm install.
  2. The chunk-size warning threshold is now 700 KB; any chunk above that warrants investigation but no longer fails the build.

i18n / l10n

All Phase 8 strings remain translated in the 14 supported locales (ar, de, en, es, fr, hi, it, ja, ko, nl, pt, ru, zh_CN, zh_TW). Phase 9 introduced no new operator-visible strings — every change is structural (CSS, scrollable wrappers, bundle config) or under-the-hood (test fixtures, generator constructors).

Deferred to Phase 10

  • External penetration test — vendor engagement; carried over from Phase 7 / Phase 8 as a budget item, not a missed deliverable.
  • Backend coverage from 76% → 80% — the residual gap is concentrated in startup lifecycle and Graylog / Grafana integration code that needs a live external service in CI to exercise; addressing that requires the integration-tests harness work tracked under Phase 10 stabilization.
  • Pro+ Enterprise-tier modules (virtualization_engine, fleet provisioning) — Phase 10 scope.