Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 29 Jun 00:35

[0.4.0] - 2026-06-25

The live-runtime cut: the framework primitives that 0.3.0 left built-but-test-only
are now plumbed into the live cast pipeline — and a new gate makes "built-not-plumbed"
a CI failure so it can't happen silently again.

This cut also hard-cuts the Astro host substrate to Astro 7 / @astrojs/cloudflare v14:
czapFetchLayer() is the front-of-pipeline fetch layer, @czap/cloudflare/cache-provider
bridges Astro cache.invalidate() into the CZAP boundary KV tag index, czap astro dev/status/stop delegates to Astro background dev-server management, and czap doctor --target astro probes the Astro dev status endpoint.

Added

  • @czap/astroruntime DocumentGraph loader. loadGraphRuntime(serialized, resolve)
    lowers a sealed DocumentGraph onto the live boundary cast pipeline (CSS/ARIA/GPU),
    with a surgical castGraphDelta re-cast seam (only changed cells re-lower; untouched
    observers survive). New client:graph directive. The loader is the seam an authoring
    producer feeds; the producer itself is downstream.
  • @czap/astroscene→live-runtime bridge. bridgeSceneToGraph(scene, handle, …)
    drives a signal-indexed @czap/scene against the live runtime: a DISCRETE state crossing
    emits a GraphPatchrecast, while the CONTINUOUS tween writes a leaf CSS var / GPU
    uniform each frame and never patches the graph. @czap/scene is now a live runtime
    consumer (was video/offline-only).
  • @czap/astroAI-apply seam. castGraphContext (cast the live graph OUT to a
    model-facing AIContext) + admitGraphPatchProposal (admit a candidate IN through the
    un-bypassable validateGraphPatchProposalapplyValidatedPatch token-witness chain,
    then re-cast the delta). LiteShip exposes the seam; the model producer is downstream.
  • @czap/astroSVG last-mile directive (client:svg): resolves data-czap-entity → SVGElement and applies @czap/scene's applySvgAttrs to the live DOM each frame.
  • @czap/stageheadless node video encode. dualExportNode(graph, ffmpegFrameEncoder())
    runs the graph→page+video dual-export proof in node/CI via an injected ffmpeg/libx264
    FrameEncoder (was browser/WebCodecs-gated). The frame-source digest == page digest
    invariant holds headless (frames addressed, bytes injected).
  • @czap/quantizerAnimatedQuantizer frame-clock injection. AnimatedQuantizer.make(…, { scheduler })
    takes an optional @czap/core Scheduler.Shape (raf / fixedStep / audioSync) so the output
    interpolation rides the display refresh (or a deterministic render/test clock) instead of its internal
    fixed 16ms sleep. Omitted, the 16ms loop is byte-unchanged — existing callers are untouched.
  • @czap/astrocontinuous signal→uniform bridge. driveUniformFromSignal(element, input, uniform)
    (from @czap/astro/runtime) drives the existing czap:uniform-update event continuously from a
    continuous signal (e.g. scroll.progress), writing the value into the GLSL/WGSL uniform the GPU runtime
    already consumes each (rAF-throttled) frame. Replaces the hand-rolled scroll→uniform glue and its
    0..1-vs-0..100 scale footgun.
  • @czap/vite@quantize container-target opt-out. New quantize.container plugin option
    retargets the auto-emitted viewport @container containment off :root to a named selector
    (e.g. '.czap-vp') for hosts whose layout can't have a size-contained :root. Default :root
    unchanged; applies to both the CSS transform and emitted boundary assets.
  • @czap/astroconvention-file watch battery. The integration now calls Astro's addWatchFile
    for the convention primitive sources (boundaries / tokens / themes / styles, via the resolver's own
    primitiveSearchPatterns), so editing a definition restarts the dev server and re-collects the
    manifest — even for definitions not yet imported by a CSS block.
  • @czap/cliczap audit --consumer --profile <p> now combines (was mutually exclusive): the
    profile becomes the consumer discovery base, so a downstream can run the audit engine against THEIR
    OWN installed node_modules topology, not just LiteShip's @czap/*. The engine seam
    (consumerDevopsProfile(cwd, base)) was already there; this wires it to the CLI.
  • Plumb-completeness gate (plumb:gate, gauntlet phase 37). A package-plumb ledger
    classifies every published package runtime/tooling/deferred (an unclassified package
    fails CI, so a test-only subsystem can't ship hidden) + an unwired-capsule floor. Closes
    the hole where built-not-plumbed primitives passed green (the audit's orphan findings were
    info-only; no phase asserted producer→consumer plumbing).
  • Determinism hardening: an ast-grep guard banning re-implemented threshold reverse-scans
    outside the canonical f32 kernels, + a BlendTree.computeBlend accumulation-order-independence
    property test (run against the fresh wasm in CI).
  • New package @czap/error — a composable tagged-error algebra (a closed variant coproduct
    over an open TaggedError contract, value AND type, Effect- and throw-compatible) the whole
    stack now adopts as its foundational zero-dep leaf.
  • New package @czap/gauntlet — the self-proving rigor engine (ADR-0023): gates, findings,
    assurance levels (L0–L4), and the authority ratchet (a gate earns blocking power only by
    self-proving against its own red/green/mutation fixtures). Lean (no typescript; the
    triangulated repo-IR + the mutation / MC-DC / taint / coverage-guided-fuzz / claim-vs-reality /
    traceability / agent-safety gate families are host-injected via @czap/audit, ADR-0012). This
    is the rigor work the small live-runtime cut grew into when it exposed the gaps.
  • FactGate — evidence-bound gates (ADR-0019). Gates can be defined as DATA (defineFactGate
    requires + decide) instead of arbitrary closures, closing the stale-green hole where a run
    body could read undeclared evidence. Cache identity derives from the declared facts; the
    discriminant is an unforgeable WeakSet. The always-blocking no-skipped-test gate has a
    proven-equivalent FactGate form.
  • API-docs source-of-truth. Every publishable package is in the TypeDoc roster (guarded), and
    a broken {@link} now fails the build (treatWarningsAsErrors) — zero dead links, enforced.
  • Astro 7 (hard-cut). The workspace targets Astro 7 + @astrojs/cloudflare v14 (Vite 8 /
    Rolldown). @czap/astro needs no code changes — the integration hooks, middleware, and
    client:* contracts are unchanged — and the batteries Astro 7 ships are now consumed:
    • @czap/astroczapFetchLayer() (ADR-0024): request-time adaptation as a layer in
      FRONT of Astro via src/fetch.ts. Shares the one createEdgeHostAdapter().resolve() with
      czapMiddleware; on an opt-in serveFromEdge path it serves boundary CSS from the edge and skips Astro
      entirely. serializeBoundaryCss exposed. Astro's Fetchable / Hono-compatible.
    • @czap/astroDiagnostics → Astro logger bridge. bridgeDiagnosticsToAstroLogger /
      installDiagnosticsBridge route @czap/* runtime diagnostics through Astro's logger
      (structured astro dev --json output); wired in astro:config:setup.
    • @czap/edge / @czap/cloudflareactive cache invalidation. BoundaryCache.invalidateByPath
      (purge by content address) + invalidateByTag (Astro.cache tag parity, index-backed) close
      ADR-0017's passive-TTL gap; KVNamespace gains optional delete/list, forwarded by the
      Cloudflare adapter, degrading to a diagnostic when a provider omits them.
    • @czap/cliczap doctor --target astro: an Astro 7 /_astro/status dev-server
      liveness probe for agent-run background dev sessions.

Changed

  • @czap/core — factored the DocumentGraph node well-formedness reader (isWellFormedNode,
    DocumentGraphNodeSchema) out of ai-cast.ts into document-graph-schema.ts so the
    runtime loader and the AI seam share one trust gate.