[Features]
- The frontend no longer uses @ngrx. Every page, list and wizard now reads its data through signal-native services, and the legacy ngrx list framework, router-store, auth/session/dashboard/endpoint/create-app/deploy slices and the schema-only entity catalog are gone. This ran as a long series of waves (#5308 through #5428) covering CF, Kubernetes, Helm, autoscaler, git and core, and the store package is now a fraction of its former size.
- Every dialog is movable by default (#5645), and setup wizards consistently offer Cancel (#5522). The Add Route stepper was redesigned (#5312).
- An endpoint whose token has expired is now a first-class state with one-click recovery, rather than presenting as a generic connection failure (#5636). Connect and disconnect show transient states, endpoint dialogs are modeless, and CF section navigation was fixed alongside them (#5642).
- Sorting uses a tokenized natural comparison with a match-case toggle, so
cf1sorts beforecf2beforecf10(#5368). - Bulk operations returned across CF. Lists and cards support selection (#5382, #5665), routes can be deleted or unmapped in bulk and roles managed for several users at once (#5444), and the full set of CF bulk operations is restored with guard tests behind it (#5664). A bulk delete now reports the real settled outcome of each item with live progress rather than an optimistic summary (#5680).
- All CF entity deletes route through one chokepoint (#5406), which made a blocked-delete state with classified reasons possible (#5407).
- Work has begun on the Stratos Theme Builder (
tools/stb), a build-time theming tool that harvests the running console's styling into a typed facet model and edits it with a live preview and export (#5396, #5503, #5508 through #5546). It is a work in progress and is not ready to be used. It is a developer tool rather than part of the shipped console, and is listed here to record the work, not to invite use. - Starred endpoints show on Home regardless of connection state — a starred endpoint that is down renders as a Disconnected card instead of disappearing (#5601).
- The application detail page merged Instances into Summary, reworked the scaling controls and added live instance telemetry (#5427).
- Service keys and route service bindings are supported end to end (#4301, #4302) — native Jetstream handlers (#5460) plus the Service Keys (#5461) and Route Services (#5462) pages, with busy states, a per-instance key-count column and count cells anchored to the list they came from (#5470, #5472, #5473).
- Service instance parameter editing works against the full OSBAPI schema again (#5495), plan parameters can be previewed from the marketplace Plans tab (#5497), and the service instance detail page gained parameters, credentials and uniform linking (#5500). Bind-existing options now render from v3 rows (#5617) and the service instance dashboard link is back (#5491).
- The CF Users surface was rebuilt on the CF v3 role APIs. There is a selection-driven action bar for Manage Roles and Remove across the CF, organization and space pages (#5475), an Add User dialog that either associates an existing user or sends an invite (#5478), a multi-organization role-assignment widget with
space_supportersupport and a role registry (#5479), and faster role loading with a view toggle, mixed-role summaries and links from role cells (#5480). - Colors are normalized onto semantic theme tokens (#5494, #5496) expressed in OKLCH (#5649), and the remaining light-only placeholder and chart colors now adapt to the dark theme (#5498). The interface face is IBM Plex Sans with stylistic alternates enabled for a dotted zero and simple a/g (#5641, #5654).
- The login page takes its branding from company-config, covering the error strip, inputs, notice and show/hide toggles (#5504).
- Release notes now accumulate as per-PR fragments in
changelog.d/, are assembled into the annotated release tag body atmake stamp tag, published from the tag bymake publish, and cleared bymake sweepafter each release. - Jetstream can send a Content-Security-Policy header, opt-in through
CONSOLE_CSP(#5688). It is off by default; operators who enable it should read the CSP section of the docs first, since a policy that is too strict will break console features.
[BugFixes]
- A stepper's
onEnteris delivered after the activating render rather than before it (#5604), and the variable-editor dialog no longer closes when the editor is resized (#5487). - Registering an endpoint surfaces the new GUID so the connect step can use it (#5355), first connect falls back to the last-used username (#5384), a native CF endpoint error is classified as unreachable or auth in the banner (#5385), and the reconnect action in the snackbar opens the connect dialog (#5631).
- The "All" page size works again in signal-list (#5576), and every app-table consumer now runs on signal-list rather than the retired legacy list framework (#5402, #5405).
- Deploying an application from GitHub or GitLab works again: Source Config is applied, private repositories authenticate, and an expired token is re-validated rather than silently failing (#5707). File-upload deploy was restored during the signal migration (#5379, #5380), route host/domain/path overrides take effect (#5425), the source/commit picker UX was reworked (#5424), and a failed source fetch now surfaces as a deploy failure instead of an empty wizard (#5623).
- Favourite and recent entries refresh their display names again after the signal migration, and null metadata no longer breaks the card (#5426, #5430).
- Switching application tabs no longer remounts the page and refetches environment variables every time (#5519, #5526), and starting an unstaged application reports the real CF error instead of a generic failure (#5520, #5525).
- Fixed a login redirect loop, and app deletion no longer leaves orphaned routes and bindings behind (#5697). The SSO message banner strips URL lures before rendering (#5681), SSO
nosplashis honored for unauthenticated visitors (#5678), and the login background is sized correctly (#5582). - When more than one registered endpoint shares a URL, a banner now says so — on CF, Kubernetes and Helm endpoints and in both pickers (#5534, #5698, #5699).
- Fixed an app-wide denial of Stratos-level permissions caused by the permission checker contract (#5574), so administrative affordances appear for the users entitled to them.
- CF errors are classified correctly and transient list failures retry instead of surfacing as a hard error (#5580), and the user profile is fetched on first subscription (#5575).
- List paging state is now scope-aware everywhere: navigating to a different data set (another org's spaces, a space tab after wall browsing, another app's tabs) resets to page 1, returning to the same one keeps your place, page position is no longer restored across sessions, and every pager clamps to its last page so stale state can never render an empty page over a non-empty list.
- Space-scoped tab headers now report the scope's own count: the space Applications tab showed the endpoint-wide total (82 on a 1-app space), and the space Services / User Services headers tracked the filter box instead of the space.
- Entering a name filter jumps to page 1 of the results and erasing it returns to the page you were on; the space summary page's Applications and Routes tiles now show the space's real counts (they were 0 for every space).
- The home page's header controls now line up: the Favorites/Connected/All pill sat 3px high at the top and 7px low at the bottom against the card layout chooser, and the divider between them is a rule rather than a "|" character whose size followed the header font. Screen reader users get three fixes in the same row — the sort toggle is no longer announced as one of the "which endpoints to show" choices, the card layout button has a name instead of being an unlabelled icon and now reports whether its menu is open, and the layout options no longer all announce as selected.
[Chores]
- Upgraded to Angular 22 and TypeScript 6.0, having first landed the Angular 21 upgrade (#5304, #5445). Strict null checks (#5448) and
strictTemplates(#5622) are now on across the frontend packages, and the ESLint warning backlog that the upgrades exposed was cleared (#5455). - The frontend moved to Tailwind CSS v4 (#5354), and the component stylesheet count fell from 280 to 128 as SCSS gave way to utilities (#5357, and the batched
:hostmigrations that followed). There is a Tailwind v4 usage guide in the docs (#5541). - Routine dependency updates across the frontend, Jetstream modules and the website throughout the cycle, including the Go toolchain moving to 1.26 (#5465), the test toolchain to Node 26 and Bun 1.3.14 (#5393), and Dependabot switching to the bun ecosystem (#5646).
- Jetstream tracks the upstream
fivetwenty-io/capi/v3client and no longer carries a fork replace (#5451, #5502). Along the way it picked up typed includes, quota contract fixes, isolation segments, quota-delete jobs and an empty-202 recovery path for managed service instance updates (#5432, #5442, #5443, #5449, #5482). - Name-uniqueness checks migrated off the CF v2 API (#5591), and a v3-only CF now sources its auth endpoints from the root links when
/v2/infois absent (#5464). - Required status checks now report on every pull request, including ones that touch only
tools/stbor only docs, which previously left PRs waiting forever on a check that never ran (#5527, #5529, #5564, #5566, #5567). Bun caching and lockfile handling in CI were fixed (#5543), and the CF vitest async leaks behind an intermittent gate hang were tracked down (#5671). - End-to-end tests run in tiers with impact-based selection and make dispatch (#5653). Playwright selectors were modernized for the Tailwind frontend (#5615), the
data-testcontract is complete and guarded by a ratchet (#5648, #5650), and the harness reliability fixes were driven by measured failure classes rather than guesses (#5655, #5568). - The documentation website is now Docusaurus 3.10 with Tailwind (#5551),
website/docsanddocs/were merged into one tree (#5547), and the site publishes to GitHub Pages (#5586). Docs are linted against a GFM subset (#5548), and there are offline booklets with mermaid diagrams and GFM alerts (#5583). - The release lifecycle is owned by make: tag, publish, unpublish and untag (#5684), a CF-pushable zip is published (#5659), and the all-in-one image is thin with a CGO-free pure-Go sqlite driver (#5662). Backend plugins are generated before every build (#5587),
makemust be run from the repository root (#5563), andversion.mkwas split into a vendorable core (#5656). Korifi build and release targets exist but are not usable until Korifi auth lands (#5584). - Monaco is lazy-loaded and bundled through the Angular build as ESM, and assets were right-sized, with load diagnostics added to measure it (#5560, #5651). Per-space enrichment is skipped on the prewarm drain when nothing consumes it (#5614), and endpoint catalogs the endpoint has already loaded are no longer refetched (#5700).
- Adopted zizmor, osv-scanner, gitleaks and CodeQL as standing scanners (#5616), added a golangci-lint gate and expanded the audit tooling (#5633), and added a dependency-archival audit target (#5683).
- Added a modern Concourse pipeline (
ci/) — gate, nightly audit, and tag-triggered release jobs as thinmakecallers — plus a shared CI tools image (ghcr.io/cloudfoundry/stratos-ci) consumed by both Concourse and GitHub Actions. - go-cfenv updated to v1.19.0, removing the archived
mitchellh/mapstructureandjoefitzgerald/rainbow-reporterfrom Jetstream's dependency graph. go-cfenv was the only path to archived mapstructure in the build, and its oldgo 1.11directive was also leaking test-only dependencies into Jetstream's module graph.
[Security Updates]
- Jetstream gained SSRF and path-traversal guards, and its build-chain dependencies were patched (#5624). The remaining high and medium CodeQL alerts were resolved (#5629) and the outstanding Dependabot alerts cleared (#5630).
- The unmaintained
mholt/archiver/v3was replaced withmholt/archives(#5620).