LiteShip — status and remaining work
Last updated: 2026-07-13 (v0.10.0 tree; the completion cut landed the semantic-truth pass — see below).
Coverage stack standardized on Vitest 4.1.2 + Playwright browser mode.
Current node lane: 7786 passing tests (23 skipped) across 649 files (0.10.0 tree;
captured from a fresh pnpm test on 2026-07-13).
Current browser lane: shared-runtime suites run against a Chromium + Firefox + WebKit matrix, with capability-specific browser tests remaining Chromium-first where the platform surface is intentionally non-uniform.
Shipped since this baseline (0.7.0 → 0.8.1): the client→server mutation channel (graphMutationRoute / createGraphMutationClient / sendGraphMutation, ADR-0030), form-to-mutation binding (bindGraphForm, ADR-0031), morph-opaque client-owned subtrees (data-czap-morph-opaque, ADR-0032), Standard Schema interop on the node schema (DocumentGraphNodeSchema.~standard, ADR-0033), the Workers static-assets boundary-CSS dev path (ADR-0025), Receipt-DAG compaction (ADR-0026), the Cell value→wire boundary (ADR-0027), Epic 9 motion/stream spine (PR #135: interpretTransition, MotionCompiler, StateCell, wire-contract registry, active-surface gate #132), and 0.8.1 test/bench/CI hardening (parallel CI, check:gates, honest benches). Publishing is OIDC trusted publishing with provenance (no NPM_TOKEN). Neither dogfood consumer exercises the mutation channel or bindGraphForm in production yet — that surface is proven by tests + examples/06-mutation-roundtrip, not yet by a live consumer.
Shipped in the 0.9 completion campaign (2026-07-13, semantic-truth pass over the 25-package system):
moved several seams from structural completion (a field is read, a fallback is exported) to semantic
completion (the correct state / bytes / DOM / cache variant / timeline behaviour survives end to end).
Landed, each red-first + root-caused + propagated to examples & docs + independently QA’d:
recovery — a typed, attested DiscreteStateTransition protocol replaced the category-error
discreteSignalPayloadsFromPatch; SSE frames are hash/subject/chain-verified before replay; the
graph-native substrate now drives end to end (astro host wiring + reference emit route + integration
test; no longer latent). motion — the continuous runtime FLOOR is production-driven (client:motion,
#126), the explicit TransitionProgram seq/par/choice algebra replaced the collapsed routing label (#141),
and one authored program renders identically across six targets proven by a differential oracle (#130).
responsive media — one selectCandidates law so Save-Data is honoured across every output, wired
into Astro + Cloudflare hosts (#140). hardening — CSS conditional-group serialization, JSON-RPC
error XOR, Vary token merge, deployed-doctor semantic header checks + swallow-proof CLI flags,
AST-based Workers-Date analysis, and answer-first npm metadata for all 25 packages with a prepublish
gate (#146). Full node vitest suite green (7786/7809).
Product naming for prose elsewhere: GLOSSARY.md. Tables below stay operational. Identifiers like host-wired and pnpm exec czap are literal gate vocabulary, not marketing rename targets.
Current first-class support target (tier-1, CI-gated):
- Node 22 + pnpm 10
- Vite 8 + Astro 7 + Cloudflare Workers (
@astrojs/cloudflarev14+, Wrangler 4) - Windows + Linux (
windows-latestsmoke sweep +ubuntu-latestfull gauntlet via.github/workflows/ci.yml) - PowerShell + bash
- Chromium + Firefox + WebKit shared-runtime browser lane
- Chromium-first capability coverage where browser APIs are intentionally not uniform, including WebCodecs capture
macOS (tier-2, best-effort, real CI signal):
macos-smoke runs every PR on macos-latest via .github/workflows/ci.yml. The job is continue-on-error: true, so a macOS regression will not block merge to main; it surfaces as a yellow check, not silence. The smoke covers: build, typecheck, lint, invariants, test, test:vite, test:astro, test:cloudflare, test:tailwind, test:redteam, package:smoke. Playwright-browser-dependent lanes (test:e2e, coverage:browser) stay Linux-only because Playwright dep install on macOS is a separate path. Known divergence areas the smoke does not catch:
- Vite filesystem watchers use FSEvents on APFS vs inotify / ReadDirectoryChangesW on ext4 / NTFS; HMR behavior under
@czap/vitemay differ. - Worker startup on Apple Silicon is faster than the Linux baseline the bench gates are calibrated against; hard gates should still pass, distributions will differ.
- The
coverage:browserlane is Linux-only; merged coverage on macOS is partial.
Promotion path to tier-1 has two milestones:
macos-smoke(current scope: build / typecheck / lint / invariants / non-browser tests / package:smoke) stays green for a release cycle on a freshmacos-latestimage.macos-browserlanded (milestone-2 job in.github/workflows/ci.yml): Playwright + Homebrew ffmpeg, runstest:e2e+coverage:browser,continue-on-error: true. Proving green for a release cycle before tier-1 promotion.
When both are met, continue-on-error drops and macOS jobs join ci-summary needs. Until then, the gap is explicit: macOS authoring is safe; macOS browser-runtime testing is at-your-own-risk territory and won’t catch a Safari-specific regression before merge.
Current security/default-trust posture:
- runtime endpoints are same-origin by default
- cross-origin runtime endpoints require an explicit allowlist policy
- artifact ids are path-segment validated
- LLM rendering defaults to text-safe behavior
- stream and LLM HTML flows route through shared
text/sanitized-html/ explicittrusted-htmltrust surfaces - morph parsing strips executable markup classes
- boundary state writes default to
--czap-*,aria-*, androle - theme compilation rejects unsafe prefixes and CSS-breaking token values
__CZAP_DETECT__is a frozen, non-enumerable, minimal runtime snapshot rather than a writable probe dump__CZAP_RUNTIME_POLICY__is a frozen, non-enumerable runtime trust snapshot for endpoint and HTML policy decisions
Current browser-security posture:
- runtime code avoids
evalandnew Function - strict CSP currently requires host-provided hashes or nonces for Astro-injected bootstrap scripts
- Trusted Types are not auto-installed by LiteShip; hosts that enforce them should keep HTML sinks routed through the shared runtime trust surfaces
Gates
| Gate | Result | Shell |
|---|---|---|
pnpm install |
passes | PowerShell + bash |
pnpm run build |
green | any |
pnpm run lint |
green, zero errors, zero warnings (--max-warnings 0) |
any |
pnpm run typecheck |
green, package graph plus workflow-critical scripts/**/*.ts |
any |
pnpm run typecheck:scripts |
green, standalone script lane for CI/runtime tooling | any |
pnpm run typecheck:spine |
green | any |
pnpm run check |
green | any |
pnpm test |
green, 6903 tests / 559 files (6896 passed, 7 skipped) | any |
pnpm run test:vite |
green | PowerShell + bash |
pnpm run test:astro |
green | PowerShell + bash |
pnpm run test:cloudflare |
green, Astro 7 + Cloudflare adapter v14 + KV middleware/cache provider | PowerShell + bash |
pnpm run test:tailwind |
green | PowerShell + bash |
pnpm run test:e2e |
green, retries: 0 |
any |
pnpm run test:e2e:stress |
green, 10x repeated WebCodecs capture run | any |
pnpm run test:e2e:stream-stress |
green, 10x repeated stream reconnect / retarget run | any |
pnpm run test:flake |
green, repeated scheduler / stream / worker-sensitive suites; browser repeat pass defaults to Chromium unless CZAP_VITEST_BROWSERS is set |
any |
pnpm run test:redteam |
green, dedicated negative trust-boundary regression lane | any |
pnpm run bench |
green | any |
pnpm run bench:gate |
green, replicated statistical gate | any |
pnpm run bench:reality |
green, browser cold-start evidence artifact | any |
pnpm run package:smoke |
green, pack/install/export smoke for every publishable @czap/* scope |
any |
pnpm run coverage:node |
green, v8 coverage output | any |
pnpm run coverage:browser |
green, Vitest browser mode with Chromium-only coverage collection (matrix correctness runs separately) | any |
pnpm run coverage:merge |
green, merged thresholds enforced | any |
pnpm run report:runtime-seams |
green, writes local reports/runtime-seams.json + .md |
any |
pnpm run feedback:verify |
green, fail-closed provenance and contradiction check | any |
pnpm run audit |
green, advisory-first audit backed by verified artifacts | any |
pnpm run report:satellite-scan |
green, writes local reports/satellite-scan.json + .md |
any |
pnpm run runtime:gate |
green, final fail-closed telemetry enforcement | any |
pnpm run gauntlet:full |
canonical full sequential gauntlet | any |
pnpm run capsule:compile |
green, emits reports/capsule-manifest.json + tests/generated/* harness files | any |
pnpm run capsule:verify |
green, runs all generated tests + benches | any |
pnpm exec czap describe |
green, emits JSON schema of catalog + commands | any |
pnpm exec czap mcp |
runs indefinitely on stdio; MCP tools/list + tools/call | any |
pnpm run coverage:merge is the source of truth for threshold enforcement.
It seeds missing runtime files, merges node + browser lanes, and hard-fails if
merged totals or per-package totals drop below the configured thresholds.
It now also writes coverage/coverage-meta.json, which fingerprints the merged
coverage artifact, records the active include/exclude policy, and snapshots the
zero/missing-runtime file counts used by downstream feedback checks.
Coverage timing (2026-04-23)
coverage:browserruns in ~10s locally on current hardware once the Vite browser dep cache is warm. Earlier gauntlet logs showed ~19 minutes; that cost reflected coldnode_modules/.vite-browser+ multi-browser optimizer churn rather than real test wall time. With the persistent cache dir and the existingcoverageEnabled ? 'chromium' : ...matrix clamp, the browser lane is already at its structural floor – further reductions would require skipping real browser semantics (DOM, Canvas, Worker, AudioWorklet paths), which we reject because those paths are the reason the browser lane exists.coverage:browsernow drops thehtmlandlcovreporters whenprocess.env.CIis unset, so local runs write only the merge-criticalcoverage-final.jsonplus the consoletextreport. CI keeps the full reporter set so drill-down HTML and lcov uploads remain available.coverage:mergewall time is dominated bycoverage:node(~40s) plus thecoverage:browserpass. Node lane cost is driven by real test execution across 135 files; no per-file shard reduced it meaningfully when we tried.
pnpm run report:runtime-seams must run after a fresh pnpm run coverage:merge.
If the seam report reads stale merged coverage, the hotspot story is wrong even
when the code is fine. This ordering is required and enforced by the gauntlet
sequence, not optional.
pnpm run bench:gate writes benchmarks/directive-gate.json, evaluates
median overhead across five replicates, and only fails a hard-gated pair when
the regression is both above threshold and stable across replicates. The JSON
artifact now includes a top-level summary and an explicit workerGateDecision
record showing whether the normalized worker pair is promoted and why. It also
records worker startup seam shares plus LLM steady-state early-warning signals
so tail drift and scaling drift show up as explainable telemetry instead of one
scary percentage.
pnpm run bench now persists raw replicate data to
benchmarks/directive-bench.json, keyed by the same source + environment
fingerprint used elsewhere. pnpm run bench:gate reuses those samples when
the fingerprints match (same gauntlet run, no drift since bench), and only
falls back to running a fresh replicate pass when the cache is missing or
stale. The gate still runs across five replicates with identical
median/exceedance math; only the redundant second sampling pass is
eliminated. When the cache is honored, the [bench-gate] log line records
“Reusing replicates from benchmarks/directive-bench.json”; otherwise it
records the drift that triggered a fresh run.
pnpm run feedback:verify is the anti-lie step. It independently re-derives
coverage, bench, startup reality, runtime-seams, satellite-scan, and audit
truths, then hard-fails on stale fingerprints, impossible ordering, or
contradictory summaries. A report file existing is no longer enough to count
as truth.
pnpm run bench:reality is the browser startup evidence lane. It records cold
start envelopes, staged summaries, raw samples, and outliers in
benchmarks/startup-reality.json, but it is not the canonical startup verdict
by itself. Startup truth now comes from the verified synthesis in
reports/runtime-seams.json, which combines replicated shared-pair parity from
bench:gate with browser reality context from bench:reality.
pnpm run report:satellite-scan is the operator north-star report. It fuses
runtime-seams, audit, startup-reality, and coverage steering into one ranked
strike board. It is self-checking and is now validated by feedback:verify as
part of the fail-closed artifact chain.
Startup steering now follows a generic paired-truth model:
- replicated shared-pair startup parity from
bench:gateis the primary gateable truth - browser cold-start evidence from
bench:realityis support context and envelope evidence runtime-seamsis the verified synthesized startup truthruntime:gateis the final fail-closed enforcement step- invalid measurements fail verification
- support-lane noise cannot become a top-level warning when the browser lane passes
Current Watch Items
llm-runtime-steadyremains the main warm steady-state watch lane; it is diagnostic-only and should keep trending away from threshold flirtation.worker-enveloperemains a transport watch lane; it is healthier than the broader worker startup seam, but still worth watching for avoidable wrapper tax.- satellite hard-gate margin is a watch item when the pass is close enough to threshold that future runtime churn could erase headroom.
worker-runtime-startupremains the loudest honest residual seam; it is diagnostic-only because shared startup parity is the gateable truth.- raw bench formatter tone is an operator-experience watch item; the output should stay honest without implying release danger where the verified gate posture is green.
- partial pasted transcripts are not authoritative; fresh shell output plus verified artifacts are the source of truth.
- Capsule catalog closure – any new assembly arm proposal must go through an ADR amendment with first concrete instance in the same PR (ADR-0008). Governance watch, not a bench watch.
ReceiptDAG.pruneToBoundcaps per-session DAG growth atDEFAULT_MAX_DAG_NODES(10_000), retaining the canonical linear tail — bound-pinning test intests/unit/core/dag.test.ts.
pnpm run gauntlet:full runs the canonical phase sequence. That sequence has ONE
source of truth — packages/cli/src/gauntlet-phases.ts — and scripts/gauntlet.ts
simply loops it; there are no per-phase run(...) call sites to count against. Do not
re-list the phases here (a hand-maintained mirror drifts the moment a phase is added,
removed, or reordered). To see the live ordered sequence, run czap gauntlet --dry-run
or read gauntlet-phases.ts directly. The per-phase timing table below is a captured
performance snapshot, not the authoritative sequence.
Per-phase wall-time ranges
Total across all 40 phases (the count is pinned by tests/unit/devops/gauntlet-profile.test.ts against gauntletPhases.length — never hand-counted here): roughly 15–22 minutes on a fast 8-vCPU local box, ~40 minutes under CI (cold browser-coverage cache). The README’s gauntlet snapshot carries the latest CI datapoint, distilled from the truth-artifacts-linux artifact by scripts/refresh-bench-snapshot.ts. Phase 0 is rig-check (doctor --preflight --ci); phase 8 is audit:floor (rule-inventory gate before the long test tranche).
scripts/gauntlet.ts writes benchmarks/gauntlet-phase-timings.json after every run (success or failure), so the live ledger for a 3am operator is the latest artifact, not this static table. Re-run pnpm run gauntlet:full and the artifact updates automatically. The numbers below are a captured snapshot from one Linux run, useful as anchors when the artifact isn’t fresh.
Captured 2026-05-10 on Linux x64, 8 vCPU (Node 22). Phases 1–11 are measured wall times from the captured run; phases 12 onward are marked see artifact (the captured run failed at test:e2e because the sandbox lacked Playwright dep-install). The phase numbers below follow the canonical order in packages/cli/src/gauntlet-phases.ts at capture time — this table is a snapshot, not the authoritative list.
| Phase # | Name | Command | Wall time | Source |
|---|---|---|---|---|
| 1 | build | pnpm run build |
1.3s | captured run |
| 2 | capsule:compile | pnpm run capsule:compile |
10.2s | captured run |
| 3 | typecheck | pnpm run typecheck |
4.2s | captured run |
| 4 | lint | pnpm run lint |
5.1s | captured run |
| 5 | docs:check | pnpm run docs:check |
39.7s | captured run (TypeDoc regen + diff) |
| 6 | invariants | pnpm exec tsx scripts/check-invariants.ts |
987ms | captured run |
| 7 | test | pnpm test |
1m7s | captured run (~75s claim from README) |
| 8 | test:vite | pnpm run test:vite |
3.1s | captured run |
| 9 | test:astro | pnpm run test:astro |
6.9s | captured run |
| 10 | test:tailwind | pnpm run test:tailwind |
2.3s | captured run |
| 11 | test:e2e | pnpm run test:e2e |
6.5s | captured run (failed downstream — Playwright dep-install gap) |
| 12 | test:e2e:stress | pnpm run test:e2e:stress |
see artifact | 10x repeat-each WebCodecs capture |
| 13 | test:e2e:stream-stress | pnpm run test:e2e:stream-stress |
see artifact | 10x repeat-each stream reconnect |
| 14 | test:flake | pnpm run test:flake |
see artifact | repeated runs of runtime-sensitive tests |
| 15 | test:redteam | pnpm run test:redteam |
see artifact | Linux fast (~seconds); browser red-team is separate |
| 16 | bench | pnpm run bench |
see artifact | full bench sweep |
| 17 | bench:gate | pnpm run bench:gate |
see artifact | replicated 5-run statistical gate |
| 18 | bench:trend | pnpm run bench:trend |
see artifact | rolling-median drift gate; skips until 3 historical fingerprints exist |
| 19 | bench:reality | pnpm run bench:reality |
see artifact | browser cold-start evidence lane |
| 20 | package:smoke | pnpm run package:smoke |
see artifact | per-package pack/install/export cycle |
| 21 | coverage:wipe-subprocess | rimraf coverage/subprocess-raw |
<1s | filesystem cleanup before tracked coverage |
| 22 | coverage:node:tracked | pnpm run coverage:node:tracked |
~38s | scripts/gauntlet.ts orchestration comment for coverage:node |
| 23 | coverage:browser | pnpm run coverage:browser |
~10s warm / ~19m cold | “Coverage timing (2026-04-23)” block earlier in this doc |
| 24 | merge-subprocess-v8 | tsx scripts/merge-subprocess-v8.ts |
see artifact | merges subprocess v8 coverage frames |
| 25 | coverage:merge | tsx scripts/merge-coverage.ts |
~40s + browser pass | “coverage:merge wall time is dominated by coverage:node (~40s) plus the coverage:browser pass” |
| 26 | report:runtime-seams | pnpm run report:runtime-seams |
see artifact | derived from coverage + bench |
| 27 | audit | pnpm run audit |
see artifact | structural + integrity + surface |
| 28 | report:satellite-scan | pnpm run report:satellite-scan |
see artifact | derived synthesis |
| 29 | feedback:verify | pnpm run feedback:verify |
see artifact | provenance / contradiction check |
| 30 | runtime:gate | pnpm run runtime:gate |
see artifact | final fail-closed enforcement |
| 31 | capsule:verify | pnpm run capsule:verify |
see artifact | runs all generated tests + benches |
| 32 | flex:verify | pnpm run flex:verify |
see artifact | 7-dimension acceptance roll-up |
Phase 23 (coverage:browser) is the only phase with a meaningfully bimodal cost — the cold path on a fresh node_modules/.vite-browser cache crosses ten minutes. If your CI image rebuilds the Vite browser optimizer cache from scratch, plan around that; if it persists the cache, you stay at the ~10s warm cost.
For the canonical, current truth, read benchmarks/gauntlet-phase-timings.json after a fresh pnpm run gauntlet:full. The snapshot above is a reference anchor, not the live ledger.
For 3am operators without a local repo: the truth-linux job in .github/workflows/ci.yml uploads benchmarks/ (including gauntlet-phase-timings.json) as the truth-artifacts-linux artifact on every push to main and every pull request. That artifact carries all 40 phases measured under CI conditions and is the single source of truth without needing to re-run anything locally — find the most recent successful CI run on the relevant branch in the GitHub Actions UI, download the artifact, read the JSON. The static table above is for orientation; the artifact is for decisions.
Quality Policy
- Package source files do not use raw
console.*for runtime boundary logging. Centralized diagnostics now flow through@czap/coreDiagnostics. - Diagnostics are typed (
level,source,code,message, optionalcause, optionaldetail) and testable via a swappable sink. warnOnceis the standard path for deduped capability and fallback notices.- Lint is a hard architecture gate, not best-effort hygiene. Warnings are treated as debt and fail the repo gate.
Runtime Wiring Model
Astro client directives are now lifecycle shells over shared runtime adapters. The source of truth for runtime behavior is no longer embedded directive-local logic.
| Classification | Package / Surface | Current status |
|---|---|---|
host-wired |
@czap/astro shared runtime adapters |
satellite, stream, llm, worker, and wasm all route through packages/astro/src/runtime/* |
host-wired |
@czap/web DOM runtime |
Astro stream + LLM paths use shared SSE, Resumption, Morph, SlotRegistry, and LLMAdapter |
host-wired |
@czap/worker |
Astro worker directive now uses WorkerHost rather than inline Blob worker protocol |
host-wired |
@czap/core runtime coordination + WASM / GenUI surfaces |
Compositor and worker host paths now expose shared RuntimeCoordinator state; Astro wasm uses WASMDispatch; Astro llm uses TokenBuffer, UIQuality, GenFrame, Receipt, and DAG-ordered replay plumbing |
host-wired |
@czap/vite wasm asset path |
virtual:czap/wasm-url is wired into the real plugin/integration path |
host-wired |
@czap/edge request + cache/theme host path |
Astro middleware now routes through createEdgeHostAdapter, which resolves ClientHints, EdgeTier, compileTheme, and createBoundaryCache in one host path |
host-wired |
@czap/cloudflare Workers KV glue |
cloudflareMiddleware maps cloudflare:workers env bindings to @czap/edge KV cache; cache config is build-derived from the virtual:czap/boundaries manifest (minted ids + precompiled per-tier outputs); proof at examples/cloudflare-astro/ |
standalone subsystem |
@czap/remotion |
supported video branch, not part of the default Astro/Web runtime path |
host-wired |
@czap/core Plan / ECS |
promoted through RuntimeCoordinator; the compositor and worker host paths now use a real plan graph plus ECS-backed dense stores for runtime bookkeeping |
Coverage Snapshot
Latest merged coverage (pnpm run coverage:merge):
- read
coverage/coverage-final.jsonandcoverage/coverage-meta.jsonfor the fresh merged totals and policy fingerprint tests/generated/is a tracked test source contributed bycapsule:compile; generated property tests and benches are included in the merged coverage totals
Runtime Steering
Use pnpm run report:runtime-seams after intentional runtime/coverage waves.
It summarizes the real next work instead of relying on memory or stale notes.
The seams report is now a derived report backed by provenance checks against
coverage + bench artifacts, not a standalone truth source.
Use pnpm run report:satellite-scan when the question is bigger than one seam.
The scan now ranks strikes by startup impact, browser-vs-proxy divergence,
branch-hotspot overlap, and feedback confidence instead of just raw overhead.
Current steering artifacts:
- local
reports/runtime-seams.json - local
reports/runtime-seams.md - local
reports/satellite-scan.json - local
reports/satellite-scan.md coverage/coverage-meta.jsonbenchmarks/startup-reality.json
reports/ artifacts are generated per run and are intentionally local now.
They are still fail-closed telemetry inputs, but they are no longer a tracked
source of repo history. When you need the latest hotspot or strike-board story,
regenerate them from the current tree instead of trusting an old diff.
Fresh local guidance now comes from verified generated reports rather than a hardcoded ledger in this file. After a clean sequential gauntlet:
- read
reports/codebase-audit.jsonfor the current advisory counts and aggregate score - read
reports/runtime-seams.jsonfor the current paired-truth statuses and startup seam story - read
reports/satellite-scan.jsonfor the current runtime warning summary and ranked strike board reports/is git-ignored local telemetry, so a fresh gauntlet should not leave tracked report churn behind
Current browser startup evidence from bench:reality:
- worker cold start median: see fresh local
benchmarks/startup-reality.json - worker cold start p99: see fresh local
benchmarks/startup-reality.json - llm simple cold start envelope: see fresh local
benchmarks/startup-reality.json - llm promoted cold start envelope: see fresh local
benchmarks/startup-reality.json
Current worker startup steering from fresh local runtime seams:
worker-runtime-startupremains a broad continuity diagnostic, not a gateworker-runtime-startup-sharedis the primary shared-parity read; use fresh local artifacts for the current status instead of this fileworker-runtime-startup-seamis the honest residual note for off-thread handoff cost- runtime seams now emits
messageReceiptSharePct,dispatchSendSharePct,sharedResidualSharePct, seam-to-browser-startup ratio, and a seam tail ratio - the dominant remaining worker startup seam stage should be read from fresh
local
reports/runtime-seams.json, not from this file - worker shared startup parity status: read from fresh local
reports/runtime-seams.json - llm simple startup paired truth status: read from fresh local
reports/runtime-seams.json - llm promoted startup paired truth status: read from fresh local
reports/runtime-seams.json
Current LLM steady-state steering from fresh local runtime seams:
llm-runtime-steadyremains diagnostic-only unless a future policy change promotes it- bench artifacts now emit replicate exceedance rate plus directive-to-baseline
p75/p99ratios - long text-session slope and mixed text/tool-session slope are now exported as first-class metrics in
reports/runtime-seams.jsonearly-warning signals for scheduler drift and buffering churn - if mixed-session slope rises materially faster than long-text slope, investigate tool-call delta normalization or flush churn before touching parser internals
Current advisory audit headline:
- read fresh local
reports/codebase-audit.jsonfor the current errors / warnings / info / suppressed counts - runtime seams, audit, satellite scan, feedback verification, and
runtime:gateshould agree on the current source fingerprint and gauntlet run id
The advisory audit is also now a derived report, not an oracle. If runtime-seams provenance fails, the audit is expected to accuse the telemetry chain first and mark the supporting artifact as failed instead of quietly treating it as present.
Current satellite scan blind spots:
- worker browser startup tail remains a watch item, but the current fresh p99
should be read from local
benchmarks/startup-reality.jsonrather than trusting a hardcoded number here - worker startup residual should now be read through the early-warning lens in
reports/runtime-seams.md: shared bootstrap drift vs off-thread handoff pressure vs host callback congestion - current local merged hotspot cluster is
packages/vite/src/style-transform.ts,packages/core/src/signal.ts,packages/quantizer/src/animated-quantizer.ts,packages/vite/src/plugin.ts,packages/compiler/src/ai-manifest.ts,packages/worker/src/compositor-worker.ts,packages/astro/src/runtime/worker.ts,packages/astro/src/runtime/stream.ts,packages/astro/src/headers.ts, andpackages/astro/src/runtime/receipt-chain.ts - hard-gated bench lanes remain
watchrather thanfail, with replicate spread and canary context recorded in the verified artifacts - audit warnings cleared; remaining blind spots are telemetry watch notes, not active audit findings
- the exact ranked hotspot list should be read from fresh local
reports/satellite-scan.mdandreports/satellite-scan.jsonoutputs
Worker startup early-warning trigger:
- do not jump to SAB/shared-memory transport from one noisy run
- if
worker-runtime-startup-seam.absoluteMeanNs > 10000andmessageReceiptSharePct >= 60for two consecutive verified runs, open a separate transport architecture evaluation - use fresh
reports/runtime-seams.*andreports/satellite-scan.*outputs for the current evidence trail instead of hardcoding a verdict here
Explicit runtime coverage exclusions now live in vitest.shared.ts and are
limited to barrels plus runtime-unexecutable/type-only files:
packages/core/src/capture.tspackages/core/src/protocol.tspackages/core/src/quantizer-types.tspackages/core/src/type-utils.tspackages/web/src/lite.tspackages/web/src/types.ts
Merged thresholds currently enforced:
- totals:
90 / 80 / 90 / 90for statements / branches / functions / lines - per package:
85 / 75 / 85 / 85 - missing non-excluded runtime files are treated as
0%during merge
Benchmark Gate
- Bench pairs run against shared production/runtime helpers, not benchmark-only duplicate logic.
- The
streamdirective benchmark reuses@czap/webSSE.parseMessage()instead of a local parser copy. - Hard-gated pairs:
satellite,stream,llm,worker,llm-startup-shared,llm-promoted-startup-shared,worker-runtime-startup-shared - Diagnostic-only pairs:
worker-envelope,llm-runtime-steady,edge-request,worker-runtime-startup,worker-runtime-steady - Browser startup evidence lane:
benchmarks/startup-reality.jsonrecords real browser worker and llm cold-start timings, staged summaries, raw samples, top outliers, timer-floor metadata for sub-resolution llm slices, p75/p95/p99 budgets, and divergence from the Node proxy without promoting timer-quantized slices into top-level truth - Canary tasks now live in the directive bench config to surface harness noise instead of silently absorbing it
- The bench artifact now also records a worker startup breakdown so we can see
claim-or-create,coordinator-reset-or-create,listener-bind,quantizer-bootstrap,request-compute,state-delivery, anddisposecosts without promoting those subphases into top-level warnings. - The bench/report chain now also splits worker startup meaning explicitly:
worker-runtime-startupremains the broad continuity envelope,worker-runtime-startup-sharedmeasures comparable startup work as a real hard-gated parity slice, andworker-runtime-startup-seamrecords the worker-only residual as absolute time first and derived percent second. - The Astro worker directive now uses host-authoritative resolved state for visible startup and hysteresis-sensitive updates; the worker mirrors that resolved state and acknowledges agreement instead of being the source of truth for first paint.
- Worker startup artifacts now also carry
visible-first-paintandworker-takeover-seamtimings so the bench warning reflects handoff cost rather than first visible state latency. - The broader diagnostic pairs measure shared runtime boundaries, not just parser or serialization leaf work.
worker-runtime-startupis now an honest Node-side host bootstrap support lane (WorkerHost.create()/ first update flush / first compute), and its async shim no longer produces negativestate-delivery.- LLM startup paired truth now reads matched shared slices from
reports/runtime-seams.jsonrather than broad envelope timings. - Browser startup budgets are enforced through
feedback:verify; support lanes can only fail the chain when they become invalid measurements. CompositorWorkernow reuses a cached inline worker script URL, so repeated host construction no longer recompiles the same Blob URL on every create.- Failure rule: median overhead exceeds threshold and at least
4/5replicates exceed threshold - Artifact:
benchmarks/directive-gate.jsonincludes per-replicate raw inputs, aggregate decision data,runtimeClass,workerGateDecision, and final pass/fail reasoning
Done — Spec 1.1 Hardening via Flex (2026-04-24)
11 audit findings closed by turning each bug into a reusable kernel:
- CanonicalCbor encoder (
core.canonical-cbor) — RFC 8949 §4.2.1 honored in code; ADR-0003 graduates from aspiration to spec. - Type-directed AST walker —
cachedProjectionarm went from 0 to 2 real manifest instances; factory-wrapped capsules detected. - Phantom-kinded TrackId —
TrackId<K>brands cross-kind refs as compile-time errors;typecheck:testsgauntlet step added. - VitestRunner capsule — three execSync sites retrofitted; argv spawn closes RCE surface; Windows cmd.exe quoting drift-guarded.
- RIFF walker + WAV decoder —
examples/scenes/intro-bed.wavnow decodes cleanly;intro-bed:wav-metadatareads INAM/IART/IBPM. - SceneRuntime capsule — worlds actually tick; ADR-0009’s ECS- as-substrate claim no longer theatrical.
- JsonRpcServer kernel — JSON-RPC 2.0 conformance; 35 §6/§7 examples transcribed as tests; -32700/-32600/-32601/-32602/-32603 emitted correctly; notifications no longer get responses.
- Real generative property tests — vacuous
() => truetests replaced withfc.propertyover schema-derived arbitraries OR honestit.skipwith TODO when no run handler is set. - Beat-binding sceneComposition — BeatMarkerProjection output reaches SyncSystem via pure ECS data flow; no closure sidecar.
- Scoped SceneContext —
Scene.subscene(parent, partial)fills missing bpm/fps from parent. - Self-describing CLI describe — drift-guard test asserts every dispatch verb appears in describe output.
E2E reference render verified (intro-bed scene compiles, ticks, and emits stable mix receipts end-to-end through the SceneRuntime).
Done — Dev-experience layer (2026-05-16)
First-run developer experience built on top of the existing CLI dispatch:
czap doctor— preflight rig check with 9 probes (Node, pnpm, workspace install, core/cli built, git hooks, git config, Playwright, WASM toolchain). Emits JSON receipt on stdout + colored TTY summary on stderr. Three bearings (ok/warn/fail) aggregate to one verdict (ready/caution/blocked).czap doctor --fix— cheap, local remediation: invalidates tsbuildinfo and rebuilds when dist/ is missing-but-tsconfig-thinks-fresh; re-links pre-commit hook. Receipt recordsfixed: DoctorFix[].czap doctor --ci— escalatescautionto exit 1 (warnings block CI). Verdict stays honest; only exit code escalates. Recordsstrict: truein the receipt.czap glossary [term]— terminal access to the prose register (LiteShip / CZAP / @czap/* naming + maritime CLI ontology).czap help— verb table grouped by phase (cast off, compose + render, manifest, ship out, servers);czap helpprojects the live grouping.czap completion <bash|zsh|fish>— shell tab-completion scripts. Drift-guarded bytests/unit/cli/commands/completion.test.tsparsing dispatch.ts.pnpm shakedown— guided shakedown: doctor → install (if needed) → build → test. Phase-by-phase progress with maritime ontology. Namedshakedown(notsetup) so it doesn’t collide with pnpm’s built-inpnpm setupinstaller command.scripts/postinstall.ts— mooring receipt onpnpm install, points topnpm shakedownfor the shakedown.scripts/clean.ts— dry-dock cleaner with named-bearing receipt.scripts/scripts-index.ts— the deck plan (pnpm scripts).- Engines minima dynamic — doctor reads
engines.node/engines.pnpmfrom root package.json instead of duplicating constants. - Package list dynamic — doctor’s tsbuildinfo invalidation loop parses the build script out of root package.json; can’t drift.
- Glossary-lint —
tests/unit/cli/glossary-lint.test.tsscans CLI source for maritime register terms and asserts each is defined in bothGLOSSARY.mdandczap glossary. Future ontology additions can’t land without their glossary entry. SKIP_PRECOMMIT=1escape hatch in pre-commit hook (with re-run reminder banner).CI=truecolor —colorEnabled()now honors the CI convention so CI build logs render ANSI properly.- Dependabot — weekly grouped npm updates (typescript-stack, vitest-stack, lint-stack, framework-stack) + monthly github-actions.
Receipts on stdout stay machine-clean; colored output goes to stderr only,
so czap doctor | jq and MCP-mode usage keep working.
Decided (Closed)
B.1: DECIDED – examples/remotion-demo is standalone
examples/* is included in the pnpm workspace (pnpm-workspace.yaml) but excluded from the root TypeScript composite (tsconfig.json). examples/remotion-demo uses file: deps and its own tsconfig.json; install from the repo root with pnpm install.
Documented in README.
B.2: DECIDED – Node/PNPM wrappers are the supported feedback loop
Fix applied:
- Root scripts now run through
pnpm,tsx, andvitestdirectly. scripts/test-vite.ts,test-astro.ts, andtest-tailwind.tsimport bypathToFileURL()so Windows paths work under ESM.tests/integration/*/test.tsandscripts/test-e2e.tsusespawn(..., { shell: false })and switch topnpm.cmdautomatically on Windows.- Root
preparenow usesscripts/link-pre-commit.ts, sopnpm installis non-failing on PowerShell and Linux. scripts/check-invariants.tsis pure Node and no longer shells out togrep.
B.3: RESOLVED
Comment – fixed to fx.components in style-css.ts:5czap.components.
Known Limitations
B.4: Browser coverage is partial, not complete
The Playwright-backed browser lane now covers:
- slot registry DOM scanning and mutation observation
- physical capture / restore behavior
- audio processor bootstrapping
- capture pipeline rendering
- worker / wasm / gpu directive happy paths
- stream directive reconnect / morph behavior
- llm directive tiering / tool-call / reconnect behavior
- stream reconnect / retarget stress behavior
- detect preference and fallback browser probes
The shared-runtime browser lane now runs as a browser matrix. Capability-specific paths are still allowed to stay Chromium-first when the browser API itself is non-uniform, but correctness/fallback behavior is expected across Chromium, Firefox, and WebKit.
Remaining browser-level gaps still exist in:
- deeper
satellite.tstiming / attribute-mutation edges - deeper morph / semantic remap edge cases beyond the current reorder / swap / retarget coverage
The host seams that used to be directive-local are now shared-runtime seams, which means the browser lane is measuring the real host path rather than a set of per-directive one-offs.
B.5: Remaining branch hotspots
Most packages now clear the enforced gate, but the following areas still have less margin than the rest of the repo and are the right place to buy future stability:
packages/vite/src/style-transform.tspackages/core/src/signal.tspackages/quantizer/src/animated-quantizer.tspackages/vite/src/plugin.tspackages/compiler/src/ai-manifest.tspackages/worker/src/compositor-worker.tspackages/astro/src/runtime/worker.tspackages/astro/src/runtime/stream.tspackages/astro/src/headers.tspackages/astro/src/runtime/receipt-chain.ts
B.6: Browser capture stress remains worth keeping
WebCodecs capture is now part of the main gate with retries: 0, and
pnpm run test:e2e:stress gives us a repeat-each feedback loop to catch future
browser regressions early. The current harness passed 10 repeated capture runs
cleanly, but this remains the most platform-sensitive path in the repo and is
worth keeping under stress coverage.
B.7: Virtual module stubs (by design, not a gap)
virtual-modules.ts returns export const tokens = {} etc. This is
intentional: transform pipeline replaces @token/@theme blocks inline in CSS files.
Stubs exist for explicit import 'virtual:czap/tokens' use (type-checker/bundler
happy path). Documented in JSDoc.
Extraction Checklist (Definition of Done)
1. Fresh clone installs cleanly
git clone <liteship-repo> && cd LiteShip && pnpm install must succeed with zero
parent-repo assumptions. No paths that reach outside the repo root.
2. Root gates stay green
tsc --build --force and pnpm test must both pass on a fresh clone.
3. Shell matrix – DECIDED
PowerShell and bash are both supported for the root feedback-loop commands.
CI still runs in a Unix-like environment, but wrapper scripts in scripts/*.ts
normalize cross-platform invocation so local development is not shell-fragile.
4. examples/remotion-demo – DECIDED
Excluded from workspace and tsconfig. Documented as standalone example
requiring its own cd examples/remotion-demo && pnpm install.
5. Release model for packages
Packages are publish-shaped and tarball-smoke-tested. The repo still dogfoods
through workspace:* links until each external npm cut.
- package surfaces,
dist/outputs, export maps, and type entrypoints must stay release-ready package:smokeis required proof for every publishable@czap/*scope (including type-only@czap/_spine); the roster is derived from the package manifests and guarded bytests/unit/devops/package-smoke-roster.test.ts- external publishing remains a deliberate release decision, not an accidental side effect of package shape
CUT Campaign Closeout (2026-06-08)
Lens C/E micro-cuts, D10 interactivity, MCP Apps spec-completeness, and Lens W (WebMCP) landed on main:
| Cut | Receipt |
|---|---|
quantizer-cache-key |
Output cache ids minted via CanonicalCbor + fnv1aBytes (no composite mkContentAddress forgery) |
quantizer-hlc |
HLC.increment replaces ad-hoc hlcCounter++ |
worker-typed-boundary |
Worker wire types use ContentAddress / StateName |
asset-ref-brand |
AssetRef() returns branded AssetRefId |
resumption-hlc |
parseEventId reads canonical HLC.encode wire format |
blake3-digest |
AddressedDigest implements blake3 via @noble/hashes |
boundary-spec-wiring |
evaluateBoundary gates on Boundary.isActive |
wgsl-gpu-runtime |
WGSL directives use WebGPU path (wgpu.ts) with WebGL2 fallback |
mcp-apps-spec-completeness |
UI resources emit _meta.ui.permissions + prefersBorder |
d10-interactive-widgets |
View bridge callServerTool + server ui/call-tool handler |
webmcp-host-browser |
@czap/command/host-browser + registerWebMcpTools() |
Framework primitives (v0.2 prep)
@czap/canonical— standalone bytes kernel (RFC 8949 §4.2.1 CBOR, FNV-1a labels, syncAddressedDigest); sole runtime dependency is@noble/hashes; no spine/core/Effect graph in-package.@czap/genui— closed catalog renderer (defineComponentCatalog,validateGeneratedUITree,renderFromCatalog); allowlisted DOM only — no model HTML; host owns interaction authority viagenui:interaction.GenFrame.receiptId— each frame mints a deterministic content address from stable fields (frameCount,type,tokens,qualityTier,morphStrategy,bufferPosition) viaCanonicalCbor.encode; timestamp stays metadata.@czap/coreshim — re-exports the canonical kernel at its export boundary; byte parity pinned intests/unit/canonical/core-shim-conformance.test.ts.- Golden vectors — encoder and digest output pinned under
tests/unit/canonical/(ADR-0013). - GenUI stream discriminator — catalog trees arrive as
{ "_genui": true, name, props, ... }; legacy token/text/HTML streaming unchanged when the marker is absent (ADR-0014). - 25 publishable packages — 23
@czap/*scopes pluscreate-liteshipandliteship;package:smokeroster derived from manifests; B6a guard intests/unit/devops/package-smoke-roster.test.tsprevents silent skips.
Future Work
Medium priority (can schedule)
| ID | Task | Scope |
|---|---|---|
| F.3 | brands.ts runtime tests |
Minimal – brand constructors + brand() factory |
| F.4 | Merge gate ratchet-up | Raise totals beyond 94.08 / 84.81 / 93.78 / 95.24 as remaining runtime files close |
| F.5 | Runtime seam hotspot lift | Use reports/runtime-seams.md to target the next real branch/perf hotspots |
| F.6 | webcodecs.ts browser tests |
Move current mocked-node coverage into a real browser lane |
Low priority (can stay as-is indefinitely)
| ID | Task | Notes |
|---|---|---|
| F.7 | vite/src/hmr.ts tests |
Browser-only, document.querySelector – needs jsdom/Playwright |
| F.8 | vite/src/environments.ts tests |
Internal, Vite environment config builder |
| F.9 | Capture stress cadence | Keep test:e2e:stress in the toolbox for browser/runtime regressions |
Completed Work Summary
Phases 1-5: Render Runtime (2026-03-17)
| Phase | Items | Scope |
|---|---|---|
| Phase 1: Conveyor Belt | 8/8 | CompositorStatePool, DirtyFlags wiring, MotionTier gating, MemoCache, springToLinearCSS, FrameBudget priority lanes, SpeculativeEvaluator, microtask batching |
| Phase 1.5: GenUI Pipeline | 5/5 | TokenBuffer (jitter buffer + EMA), UIQuality (ABR tiers), GenFrame (I/P/B frames + receipt chain), LLMAdapter (provider-agnostic), gap resolution orchestrator |
| Phase 2: Edge Pipeline | 4/4 | Client Hints parser (13 headers), EdgeTier detection + data-czap-* attributes, KV boundary cache (content-addressed), per-tenant theme compilation |
| Phase 3: Worker Architecture | 4/4 | SPSC lock-free ring buffer (SharedArrayBuffer), compositor worker (typed messages), VideoRenderer + OffscreenCanvas, main-thread host coordinator |
| Phase 4: WASM Escape Hatch | 3/3 | czap-compute Rust crate (#![no_std], C-ABI), WASMDispatch detection/loading, TypeScript fallback kernels |
| Phase 5: A/V Convergence | 5/5 | AVBridge (atomic sample counter on SAB), Signal.audio() (sample/normalized), Scheduler.audioSync(), AVRenderer (deterministic offline), AudioWorklet processor |
Phase 6 Waves (all verified green)
| Wave | Items | Scope |
|---|---|---|
| Wave 1: Showstoppers | 6/6 | WebCodecs sync, AnimatedQuantizer, Op.retry, Derived.flatten, Codec errors, receipt MAC |
| Wave 2: Ontological Rename | 3/3 | --fx- -> --czap-, data-fx- -> data-czap-, virtual:fx/ -> virtual:czap/ |
| Wave 3: Almost-Correct | 11/11 | Zap.debounce, Cell.all semaphore, Op.allSettled, Spring scaling, Animation duration, Compositor blend, Video scheduler, CSS inferSyntax, Plan.topoSort, Vite CSS parser, DOM diff + WGSL + ComponentCSS |
| Wave 4: Architectural | 5/5 | DAG multi-parent, LiveCell crossings + makeBoundary, CSS block overrides, HMR virtual module, test imports |
| Wave 5: Platform + Cleanup | 17 items | HLC overflow, Boundary validation, Wire shutdown, SSE queue, resumption URL, restore try/catch, dead code removal, ARIA/WGSL fixes, bench setup |
| Wave 6: Test Coverage | 15 files, 514 tests | 12 new test files from original wave + 3 new (store, typed-ref, live-cell) |
Effect 4.0.0-beta.32 API Adjustments
Schedule.intersect->Schedule.both(intersection combinator)Effect.makeSemaphore->Semaphore.makeUnsafe(1)Effect.fork->Effect.forkChild/Effect.forkScopedStream.make->Stream.succeed(single-value stream)
Unicode Cleanup
All em dashes and arrows replaced with ASCII across all source, test, demo, spine, fixture, and documentation files.
Repo Restructure (2026-03-17)
- Packages moved from root to
packages/ - Tests moved from
test/totests/(unit/bench/e2e/integration) - Demo moved from
demo/remotiontoexamples/remotion-demo - Docs moved to
docs/(ARCHITECTURE.md, STATUS.md, plus the rest);CHANGELOG.mdwas subsequently moved back to the repo root - Scripts extracted to
scripts/*.ts