docs: define runtime integrity refactor design
This commit is contained in:
@@ -0,0 +1,171 @@
|
|||||||
|
# Runtime Integrity Refactor Design
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Apply the repository-wide refactoring review without discarding the current
|
||||||
|
uncommitted implementation snapshot. The program closes release and boot
|
||||||
|
fail-open paths first, then makes runtime ownership explicit, and finally
|
||||||
|
consolidates tooling and large adapter modules.
|
||||||
|
|
||||||
|
## Chosen approach
|
||||||
|
|
||||||
|
Use a phased compatibility migration.
|
||||||
|
|
||||||
|
- Rejected: a big-bang V2-only rewrite. It removes legacy code quickly but
|
||||||
|
combines artifact, boot, HTTP, cache, and worker changes into one unsafe
|
||||||
|
release.
|
||||||
|
- Rejected: patch only the currently failing verifier. It makes one gate green
|
||||||
|
while leaving cross-version boot acceptance, schema drift, and duplicate
|
||||||
|
execution contracts intact.
|
||||||
|
- Chosen: introduce explicit V1/V2 discriminated contracts, route every writer
|
||||||
|
and reader through them, migrate production execution onto one registry, and
|
||||||
|
remove legacy bridges only after each vertical is covered by tests.
|
||||||
|
|
||||||
|
## Program boundaries
|
||||||
|
|
||||||
|
The work is split into independently testable sub-projects.
|
||||||
|
|
||||||
|
1. Release artifact integrity
|
||||||
|
- One executable schema for release, runtime-config, and build artifacts.
|
||||||
|
- Version-specific token projection.
|
||||||
|
- Real build-to-verification integration coverage.
|
||||||
|
2. Boot protocol integrity
|
||||||
|
- Exact supported version selection.
|
||||||
|
- V1/V1 and V2/V2 pairing only.
|
||||||
|
- Mandatory V2 contract-set verification and HTTP(S) endpoint policy.
|
||||||
|
3. Scope-owned server state and HTTP contract execution
|
||||||
|
- A scope generation owns QueryClient, mutations, optimistic state, and
|
||||||
|
cross-context resources.
|
||||||
|
- The composed external-contract registry is the only executable HTTP
|
||||||
|
registry.
|
||||||
|
4. Optional runtime and Service Worker lifecycle
|
||||||
|
- Generation-fenced start/stop.
|
||||||
|
- Nonce-based activation/reset acknowledgements.
|
||||||
|
- Bounded install streams and one verified rollback revision.
|
||||||
|
5. Quality infrastructure
|
||||||
|
- Typed subprocess results, bounded CI steps, generated artifact schemas,
|
||||||
|
one authoritative architecture analyzer, and representative coverage.
|
||||||
|
6. Adapter hardening and decomposition
|
||||||
|
- Shared bounded-body and worker-RPC primitives.
|
||||||
|
- IndexedDB singleflight.
|
||||||
|
- Route-policy closure, invalidation tuple identity, and focused extraction
|
||||||
|
from the largest adapter runtimes.
|
||||||
|
|
||||||
|
## Release artifact architecture
|
||||||
|
|
||||||
|
`scripts/contracts/release-artifacts.ts` owns Zod schemas for Release Manifest
|
||||||
|
V1/V2, Runtime Config V1/V2, and Build Manifest V1. Writers parse before writing;
|
||||||
|
readers parse before comparing. JSON Schema files are generated views and never
|
||||||
|
an independent source of truth.
|
||||||
|
|
||||||
|
`projectReleaseTokens(document)` maps a parsed artifact into comparison tokens.
|
||||||
|
V1 projects the legacy API contract version. V2 projects
|
||||||
|
`contractSet.setDigest` as `contractSetDigest` and never requires the removed
|
||||||
|
scalar. Token comparison receives projected values, not arbitrary records.
|
||||||
|
|
||||||
|
## Boot protocol architecture
|
||||||
|
|
||||||
|
The version selector accepts only `"1"` and `"2.0"`. Parsing preserves the
|
||||||
|
versioned shape through manifest loading:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
type BootProtocol =
|
||||||
|
| { kind: "V1"; config: RuntimeConfigV1; manifest: ReleaseManifestV1 }
|
||||||
|
| { kind: "V2"; config: RuntimeConfigV2; manifest: ReleaseManifestV2 };
|
||||||
|
```
|
||||||
|
|
||||||
|
Mixed pairs fail before application composition. V2 requires a contract set and
|
||||||
|
verifies it exactly once. Endpoint protocols are `http:` or `https:` in local
|
||||||
|
and development, and `https:` elsewhere.
|
||||||
|
|
||||||
|
## Scope and execution ownership
|
||||||
|
|
||||||
|
A `ScopeGenerationBundle` owns every resource capable of retaining account data:
|
||||||
|
QueryClient, mutation admission, optimistic layers, cross-context invalidation,
|
||||||
|
and optional closers. Transition order is fixed:
|
||||||
|
|
||||||
|
1. publish FENCED and render only the transition surface;
|
||||||
|
2. close query and mutation admission;
|
||||||
|
3. abort in-flight work and roll back optimistic layers;
|
||||||
|
4. detach providers and close scoped transports;
|
||||||
|
5. clear and dispose the old QueryClient;
|
||||||
|
6. construct and mount a new bundle;
|
||||||
|
7. publish READY.
|
||||||
|
|
||||||
|
Mandatory cleanup failure remains terminal/FENCED. It never publishes READY.
|
||||||
|
|
||||||
|
The composed contract-contribution registry becomes the only HTTP operation
|
||||||
|
registry. Feature gateways resolve installed operations and map executor
|
||||||
|
outcomes; they do not carry parallel schemas or retry definitions.
|
||||||
|
|
||||||
|
## Optional runtime and worker lifecycle
|
||||||
|
|
||||||
|
Optional hosts use explicit lifecycle states plus a generation token. Every
|
||||||
|
continuation after an await verifies that generation. Stop closes admission,
|
||||||
|
waits for pending startup to settle, and disposes children in reverse order.
|
||||||
|
|
||||||
|
Service Worker activation and reset messages are discriminated by kind and
|
||||||
|
carry source build, target build, nonce, and a typed result. Activation calls
|
||||||
|
`skipWaiting()` only after every controlled client acknowledges the same nonce.
|
||||||
|
Install owns a deadline AbortController, reads at most declared bytes plus one,
|
||||||
|
aborts siblings on first failure, and atomically records current and previous
|
||||||
|
verified asset digests.
|
||||||
|
|
||||||
|
## Tooling and schema policy
|
||||||
|
|
||||||
|
Subprocesses return `SUCCESS`, `EXPECTED_DIAGNOSTIC`, `TOOL_FAILURE`, `SIGNAL`,
|
||||||
|
or `TIMEOUT`. Negative fixtures must match expected diagnostic identifiers;
|
||||||
|
arbitrary non-zero exits are failures. CI gates have per-step timeouts and are
|
||||||
|
generated or structurally checked against `config/ci/gates.json`.
|
||||||
|
|
||||||
|
The TypeScript-aware custom source analyzer becomes authoritative unless a
|
||||||
|
dependency-cruiser version with TypeScript 7 support is selected. A zero-module
|
||||||
|
analysis is always a gate failure. Concrete adapter-to-adapter dependencies are
|
||||||
|
replaced by injected ports or explicitly named shared infrastructure.
|
||||||
|
|
||||||
|
## Error handling
|
||||||
|
|
||||||
|
- Artifact or boot schema mismatches use stable, version-specific failure codes.
|
||||||
|
- Unknown future versions fail closed and do not fall back to V1.
|
||||||
|
- Mandatory scope cleanup and worker protocol failures remain terminal.
|
||||||
|
- Transport readers return closed failure unions; `UNKNOWN` is not a success
|
||||||
|
fallback.
|
||||||
|
- Tool invocation failures are never accepted as expected fixture rejection.
|
||||||
|
|
||||||
|
## Testing strategy
|
||||||
|
|
||||||
|
Every behavior change follows red-green-refactor. Required matrices include:
|
||||||
|
|
||||||
|
- Release V1/V2 success plus field, digest, package, and schema tampering.
|
||||||
|
- Boot V1/V1 and V2/V2 success; mixed and future versions fail.
|
||||||
|
- Synchronous old-data hiding, late completion fencing, and cleanup failure.
|
||||||
|
- Old-page/new-worker activation, partial acknowledgement, reset results, and
|
||||||
|
install deadline/body limits.
|
||||||
|
- Process spawn error, null status, signal, timeout, and expected diagnostic.
|
||||||
|
- IndexedDB concurrent open, worker RPC crash/abort, and composite-key collision.
|
||||||
|
|
||||||
|
Repository-wide verification includes types, lint, unit/component/integration,
|
||||||
|
browser capability tests where supported, build, release verification, schema
|
||||||
|
round-trip, architecture analysis, and diff hygiene.
|
||||||
|
|
||||||
|
## Delivery order and compatibility
|
||||||
|
|
||||||
|
Release artifact integrity and boot protocol integrity ship first and retain a
|
||||||
|
read-only V1 window. Scope ownership and HTTP registry consolidation ship next.
|
||||||
|
Optional runtime, quality infrastructure, and adapter decomposition follow as
|
||||||
|
separate reviewable changes. Public facades remain stable during internal file
|
||||||
|
splits; removal of legacy exports occurs only after static usage checks reach
|
||||||
|
zero.
|
||||||
|
|
||||||
|
## Acceptance criteria
|
||||||
|
|
||||||
|
- A clean V2 build passes release verification; every supported tamper fails.
|
||||||
|
- No accepted V2 boot bypasses contract-set verification.
|
||||||
|
- FENCED renders no previous-account data and late work cannot mutate a new
|
||||||
|
generation.
|
||||||
|
- Selected optional capabilities have a concrete host or fail composition.
|
||||||
|
- Negative quality fixtures cannot pass because a tool crashed or timed out.
|
||||||
|
- Checked-in JSON schemas exactly match executable schemas.
|
||||||
|
- Architecture analysis covers a non-zero complete module graph.
|
||||||
|
- No source file contains an actual NUL byte, and all final verification gates
|
||||||
|
report their real status.
|
||||||
Reference in New Issue
Block a user