Strata 1.0 exit criteria
Analog's opt-in Standard Schema v1 input methods are additive experimental APIs. The bounded JSON and safe client-input response contract has local Node, workerd and packed-consumer fixture evidence; this does not certify M3 or Strata 1.0. See the validation evidence.
The 0.10.0 candidate adds bounded, opt-in URL-encoded form validation. Its unit suite, real Node production, Analog dev, local workerd fixture and packed consumer pass; hosted CI and deployed qualification remain open. Its 1 MiB byte limit and 10,000-field cap, strict malformed-encoding response and body-reader ownership do not provide CSRF protection. See the form evidence.
The 0.11.0 Analog candidate adds configuration-preflight protection for Strata-owned equivalent
route templates on Nitro/H3 v1. It does not detect undeclared native route collisions, roll back
arbitrary router.add() failures, or cover Nitro syntax outside the supported shape grammar. This
candidate alone does not close M3; see the registration integrity evidence.
The same candidate replaces Release's push-to-main trigger with an exact-CI
workflow_run gate for issue #117. This is not a release-safety closure until
the merged workflow has been observed handling the hosted success, failure,
cancelled, pending and stale-main transitions; see the verification evidence
and remaining live checks in the form report.
Analog's opt-in request guards are also experimental. They delegate identity
verification and authorization to the application and do not qualify
production authentication, tenant isolation, CSRF handling or real application
adoption. Request-scoped interceptors are now implemented experimentally,
with their own ordering and next() contract; they do not provide
authentication, cancellation qualification or production tracing. See the
guard report and
interceptor report.
The 0.5.0 candidate adds safe typed application HTTP errors and native JSON / 204 helpers with local Node, workerd and external packed-consumer evidence. It does not qualify a production authentication policy, a deployed runtime, cancellation through the current Nitro adapters, streamed-response cleanup or real-application adoption. These checks do not complete M3 or Strata 1.0; see the HTTP contract report.
The 0.8.0 candidate adds an opt-in Server Components build identity and bounded recovery for deployment skew (local Node and workerd evidence only; no deployed run, no hosted-CI record when written). The "version-skew behavior" item below stays open: protocol stability and a deployed qualification are not shown. M4 and M5 are not marked complete.
The 0.10.0 Server Components candidate adds provideStrataHydrationObserver() for an immutable, privacy-safe
terminal observation of Strata's per-host commit attempt. Evidence levels and remaining qualification gaps are
recorded in the candidate report. This does not
complete M4 or Strata 1.0 and does not monitor Angular after the host transaction.
The 0.8.0 candidate adds an opt-in onRequestSettled request observation (safe route/outcome/cleanup/duration
facts, exactly once after cleanup, streams at a supported terminal outcome, isolated from the response).
Implemented, unit tested, locally integrated (Node, dev, local workerd) and packed-consumer qualified; not
hosted-CI qualified when written, not deployed, not adopted. It does not observe client disconnect and does not
complete M3 or Strata 1.0 (report). Publishing is still not gated
on CI (issue #117).
The 0.9.0 candidate adds opt-in validateHeaders(schema) (Standard Schema v1, safe source: "headers" 400, cleanup-first,
observed as input-rejected). Implemented, unit tested, locally integrated and packed-consumer type-qualified; not
hosted-CI qualified, deployed or adopted. It does not complete M3 or Strata 1.0, and #117 still blocks a safe publish
(report).
The 0.7.0 candidate adds streamResponse(), an opt-in streaming lifetime for the request cleanup scope, and
executes a real compiled Analog serverFn next to Strata in the fixture. Locally integrated on Node (production
and dev) and local workerd, and packed-consumer qualified on Node and workerd; not hosted-CI qualified at the time
of writing, not deployed, not adopted. Still NO-GO: client-disconnect cancellation through the pinned Nitro
adapters (no abort signal reaches the body, so a streamed body must be finite), incremental delivery on the
Cloudflare Pages preset (the body is buffered), a client-visible failure signal after a body fails mid-stream on
either runtime, and serverFn on workerd (Angular JIT). It does not complete M3 or Strata 1.0
(report).
The 0.6.0 candidate adds an opt-in HTTP routing and API boundary (JSON 404, 405 with Allow, derived
HEAD, opt-in OPTIONS) with local Node, workerd and packed-consumer evidence. It is not an authentication,
CORS or CSRF policy, did not exercise a real Analog server function (the 0.7.0 report now does), and does not qualify a deployed runtime;
it does not complete M3 or Strata 1.0 (report).
Current status: none of these production gates is certified. This checklist is authoritative for release readiness. Fill each item with evidence for one release candidate and its qualified compatibility matrix; do not check it based on intent or a demonstration.
Framework
- Stable documented public API with supported member/inheritance/registration semantics.
- Controllers, request inputs, validation, safe errors, providers/lifetimes and authorization are usable in real applications; the chosen guard/interceptor execution model is tested.
- Angular/Analog integration and consumer compilation pass development and production checks through the documented supported extension points. The 2026-10-20 DI HTTP composition report qualifies the internal fixture on Node; the minimal external packed Node profile is only partially qualified (report). The full packed validation/failure/bundle matrix, shared SSR/controller DI, real application adoption and the known workerd JIT limitation remain open, so this release gate stays unticked.
-
Strata uses no legacy decorators, parameter decorators,
emitDecoratorMetadataorreflect-metadata; compiler coexistence with Angular is demonstrated. - Core remains independent of H3/Angular/Nitro; packages each have an owned responsibility.
- Native H3 routes and escape hatches coexist; internal RPC remains compatible with Analog server functions.
Server Components
The 0.11.0 candidate adds bounded browser hydration preflight (128 owned client boundaries and 1 MiB aggregate serialized payload UTF-8 per host). This is an incremental defensive bound and does not close the M4 gate. Runtime and packed-consumer evidence is tracked in the candidate report; no M4/1.0 certification is claimed from this change.
The 0.12.0 candidate adds runtime client reference identity validation (expected versus actual selector, conflicting selector ownership). It narrows an M4 integrity gap and does not close M4; see the candidate report.
The 0.13.0 test-only follow-up qualifies an unknown client-reference selector refusal in real Chromium on Nitro Node and local workerd and reruns the packed 0.13.0 consumer. It does not qualify malformed descriptors in-browser, installed-package selector conflicts, warm optimizer cache transitions, performance or deployment. It adds no production API or version bump and does not complete M4, M5 or Strata 1.0; see the browser integrity report.
- Actual server/client graph split, including compiled implementation/template code.
- Server implementation excluded from every browser chunk, asset and public source map.
-
Server-only dependencies excluded transitively; direct, re-exported and dynamic illegal
imports fail closed with useful diagnostics.
Evidence so far (not certified): the private package's
import "@strata-sc/server-components/server-only"assertion fails real production builds for direct, dynamicimport(),@defer-lazy, barrel, chained-barrel,?rawand?urlbrowser imports, each with a diagnostic naming the module, the importer, the reason (with the re-export chain) and the fix; a legal Server Component → marked repository build and a shared module imported by both a marked module and an island build. A synthetic canary and the marked modules are present in the Node SSR/Nitro and Worker server graphs and absent from browser JS, assets and source maps, with plugin-off positive controls (fixture, www and Relay; see STATE, "Server-only modules"). Not ticked: no release candidate; the dev server is qualified for Analog's default configuration (report: live firewall, regeneration, fail-closed recovery) but that is not a release certification; aliased re-exports (Vite aliases, tsconfig paths, index files) are followed by the pre-scan and a package module that asserts server-only fails the client build, with the importer and import chain the bundler knows (0.6 candidate, report); package re-exports are not crawled, a package that leaks without asserting is not detected; in dev, pre-bundled package modules that assert are refused by the optimizer firewall (0.9 candidate, report) but the importer above an optimizer entry is unavailable, a warm cache survives an in-place edit, and a failed first optimizer run endsvitedev; local Node and workerd only. - Normal interactive Angular descendants are shipped and hydrated without shipping the server parent; DOM reuse and exactly-once events are asserted.
-
Initial SSR, direct URL loading and server-side service access work with request isolation.
Evidence so far (not certified): Angular's public
REQUEST_CONTEXTprovider seam is qualified narrowly for buffered Server Component SSR on Nitro node-server and local workerd with 24 overlapping alpha/beta requests in both orders (request-context report); this does not qualify tenant isolation, authorization, Router navigation or streaming. The follow-up service-isolation fixture uses distinct synthetic alpha/beta private values, explicit allow-listed identity resolution, shared parent/child service-instance evidence, failure/recovery checks and the same Node/workerd overlap gate (isolation report). -
One navigation strategy is explicitly selected, documented and production-safe. Explicit
document navigation is supported through
StrataDocumentLink,StrataDocumentNavigatorandstrataDocumentNavigationGuard(report), still a full reload, not seamless SPA navigation; unguarded Router activation is still the empty surrogate. Unsupported client subtree hydration is not advertised and Strata 1.0 remains unqualified. -
Ordinary/incremental hydration and
@defercoexist under documented composition rules, including nested/interacting boundaries and clear errors for unsupported shapes. Evidence so far (not certified):@deferinside a[strataClient]component is Angular-owned and qualified forhydrate on interaction(lazy chunk on the trigger, event replay, DOM reuse) andhydrate on viewport, under a server-owned child, on local Node and workerd, with bundle evidence and Relay dogfood; every@deferin a server-owned template fails the build with a shape-specific diagnostic (see STATE, "Server Components and Angular@defer"). Still open: other hydrate triggers, defer inside an island nested in another island's subtree, Angular Router navigation into such a route, Analog'sngServerModeSSR define (app-level workaround), and a deployed environment. - Serialization value set, limits, escaping, boundary identity and version-skew behavior are stable and tested. Services, arbitrary closures and secrets cannot cross implicitly. Evidence so far (not certified): preview protocols v1 and v2 cover flat primitives and bounded structured JSON respectively (see STATE, "Client boundary protocol v2" and its research report). Still open: the protocol is experimental, production support is unqualified, and this increment does not close the remaining M4/M5 gates.
-
Render, serialization, navigation and hydration failures have tested safe behavior; any
streaming mode defines failure after headers, or streaming is explicitly unsupported.
Evidence so far (not certified; box left unticked): for the preview, buffered-SSR and
document-navigation contract only,
pnpm test:server-component-failures(Node and local workerd, report) pins render, serialization, preflight, commit rollback, sibling-host isolation and navigation/Back/re-entry failures with oneErrorHandlerreport each and no retry; streaming is explicitly unsupported (not qualified). Still open: a Server Component render error answers HTTP 200 (empty outlet or half-rendered component) with no supported general Strata seam to change it. The narrow consumer-owned expected-service recovery fixture passes HTTP 503/no-store on Node and local workerd, but is not a general fallback API and does not close this criterion (report). The 0.7 candidate adds a build-time production compilation gate and class-labelled SSR integrity assertions (an HTTP 200 alone no longer passes a qualification), so a missing compilation, the one observed cause of an HTTP 200 shell, is stopped before deployment; it does not change the status of any other render error (report). Router navigation into a Server Component subtree is NO-GO, the complete Analog deployment is unqualified (Server Components alone: narrow Cloudflare Pages GO, see the deployed report) (dev/HMR is qualified for Analog's default configuration, see the dev report), and release-candidate evidence is absent. -
Authorization, direct payload access if present, tenant/cache isolation, error redaction and
code/data-leak negative tests pass. Passing graph checks alone does not satisfy this item.
Evidence so far (not certified): synthetic-canary leak qualification of server-owned data
on HTML, headers, boundary payload, hydrated DOM, network, browser output, source maps,
secret-bearing production errors and build diagnostics, with a PUBLIC positive control and a
server-graph positive control, on Node and local workerd
(report,
pnpm test:server-component-security). Still open, and why this stays unchecked: authorization, tenant and cache isolation, broader request-context lifecycle contracts, origin/CSRF rules, log redaction and a real deployed environment. A follow-up fixture now provides narrow synthetic authorization evidence (pnpm test:server-component-authorization) with an opaque HttpOnly test cookie, server-side ownership checks before repository access, 401/403/404 no-store responses, Node/workerd overlap and browser navigation (report). It does not qualify production authentication, sessions, tenant-aware caching or this 1.0 item.
Deployment
- Production fixture with controllers/services and Server Components deployed successfully.
- Supported Node version and actual built server entry point validated.
-
Cloudflare deployment validated with the complete Analog SSR/component path; Workers execution,
deployment shape, Nitro preset, compatibility date/flags and bindings are recorded.
Evidence so far (not certified; box left unticked): the published
@strata-sc/server-components@0.1.0builds for Cloudflare Pages in an external app and passes the full verifier on local workerd (preset, compatibility date and flags recorded in the report). The real deployment to the isolatedstrata-sc-qualificationproject is QUALIFIED for Server Components only (GO, narrow): the fifth deployment (Actions run 38243892864,mainat2c3f495c, 2026-10-12) passed the whole verifier from a GitHub runner with 0 failed checks (readiness, SSR, protocol v1/v2, hydration, interaction, document navigation, confidentiality, 5/10/25 request smoke). The first four runs failed and are kept in the report. This item also asks for the complete Analog SSR/controller path and bindings, which the external fixture does not cover, so it stays unticked. -
Resource use, cold start, concurrent requests, cancellation and cleanup measured; agreed
service and bundle budgets pass on each claimed runtime.
- Partial evidence only (2026-10-16): bundle-size and warm HTTP/SSR baseline on Node and local workerd. Cold start, Worker memory, cancellation/cleanup and deployed latency are NOT MEASURED; budgets are unenforced proposals. Not closed.
- Scaling evidence (2026-10-16): one versus three distinct islands on local and GitHub-hosted runners; the Server Components browser overhead did not grow, the PR #86 candidate budgets are still unenforced proposals and the server budget lacks a controller/provider-count dimension. Still not closed.
- Release/rollback procedure tested, including client assets from an older deployment.
Quality and distribution
- Unit, adapter, Angular/Analog integration, SSR, browser hydration and navigation tests pass.
- Production bundle assertions and adversarial leak detectors include positive controls.
- Small explicit compatibility matrix with exact tested tuples, engine/peer ranges and CI links.
-
Published candidate installs cleanly outside the workspace; exports, declarations, dependency
rewriting and documented consumer build instructions work. Evidence for
@strata-sc/server-componentsonly (core/analogare covered bytest:package-consumer; not a 1.0 claim):@strata-sc/server-components@0.1.0is on npm (next→0.1.0) and the registry consumer (pnpm test:server-component-registry-consumer, rerunnable via the "Verify published Server Components" workflow) passes against it: freshnpm installof the exact version outside the workspace, real non-symlink install, no workspace resolution, production build, graph isolation, SSR, protocol v1/v2, hydration, one interaction and the server-only firewall (report). The packed-tarball consumer stays GO, with declarations qualified under TypeScript 6.0.3 and 5.9.2 and consumer setup documented in the package README (report). External Angular package islands are a separate experimental candidate: their partial-compiled tarball fixture exists, but its npm install/AOT/runtime gate has not passed, so arbitrary package components are not a 1.0 capability (report).pnpm test:full-stack-package-consumeradds one app using all three packed packages together (controller API + hydrated island + Server Component, Node and local workerd; report). It is a fixture: it does not close real-application adoption, deployment, shared controller/SSR DI or this gate.pnpm test:full-stack-deployed-cloudflareand the manualfull-stack-deployed-cloudflare.ymladd the machinery to deploy that same app (source-packed candidate) to the isolatedstrata-fullstack-qualificationproject; locally it passes the Cloudflare build and a workerd rehearsal. The real deployment was dispatched twice on 2026-10-15 and both runs are NO-GO (second run: all functional checks passed publicly, the concurrency smoke had one anomaly), so the complete-path deployment gates above stay unticked (report). A later manual run on a diagnostic branch (38741663534) passed every check for that source-packed fixture; the anomaly's cause remains unconfirmed and a fixture pass does not close the criterion (report). - SemVer, prerelease handling, deprecation and migration policy documented; upgrades exercised.
- Public documentation, examples, error diagnostics and native H3 escape-hatch guidance complete.
- Architectural/security blockers in RISKS have evidence-backed dispositions; no unresolved requirement is relabeled unsupported merely to pass the release audit.
Real-world proof
- At least one real application uses the production path: controllers/services, strict Server Components, interactive descendants and selected navigation strategy.
- Prefer ForgeCMS after controlled fixtures pass; if replaced, record suitability and equivalent coverage. Strata has no dependency on that application's APIs or schema.
- Record consumer revision, installed candidate, deployment, automated e2e/bundle evidence, actual operational use and agreed observation objectives/results. A fixture alone is not enough.
- Consumer migration and rollback verified; material issues resolved and evidence rerun.
Release record
At M5 create a dated release evidence record linking each item to tests, CI artifacts, deployment results and consumer evidence, including candidate digest and exact tuple. Astra records its architectural review and maintainers record the release decision. Do not create a fictional completed release record now. Any unchecked required item keeps Strata below 1.0.