diff --git a/AGENTS.md b/AGENTS.md index f0969c4..cee1550 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -180,10 +180,11 @@ The unpause reason: alkforge (family ADR-002, gitea replacement; see needs server-side HTML generation for its web view, and alkgen provides it. The alkforge SSR use case is simpler than the code-generation branches and is needed before them, so it jumps the queue as the first -real consumer. The generality constraint it brings: the core must serve -two target classes equally well (document/HTML generation and actual -code generation), so do not bake reader/writer assumptions into shared -core types. +real consumer. The generality constraint it brings: the core is a +text-generation engine (contexts + templates + partials → text) and +must not bake reader/writer assumptions into shared core types; HTML, +Rust, and WGSL are all the same shape, proven by handlebars' native +case, the reader POC, and alkminer respectively. Family ADR-002 also records the no-deformation rule for consumers: downstream asks file upstream gaps rather than forking or patching the diff --git a/docs/research/phase-0.md b/docs/research/phase-0.md index 687bd67..e7dc8c1 100644 --- a/docs/research/phase-0.md +++ b/docs/research/phase-0.md @@ -63,11 +63,12 @@ What this adds, and what it changes about the framing: demand: same template/registry/context machinery, different deployment posture. The settled answer for the code branches stands; it just no longer covers the whole crate. -- **The core must serve both target classes equally well**: plain - document generation (HTML) and actual code generation. Shared core - types (registry construction, strict mode, context building, - rendering entry points) must not assume code output. This is now a - design constraint with a real consumer behind it (OQ-GN-09). +- **The core is a text-generation engine, target classes are + template sets.** HTML comes free (handlebars' native case), Rust + codegen is proven (reader POC), WGSL is proven (alkminer's kernel + builder); the shape is identical. The constraint with a real + consumer behind it: do not bake reader/writer assumptions into + shared core types (OQ-GN-09). - **Queue order**: SSR first (alkforge needs it before the codegen branches matter to it), then BAST readers (branch 1), then call-protocol handlers (branch 2), then the template-JIT core @@ -95,32 +96,53 @@ projection of the same machinery: branch-specific complexity lives in the context builder (plan projection, OQ-GN-02), not the registry/render layer. That is evidence this split works. -- **WGSL / the wasm JIT idea (branch 3 territory)**: alkminer-v1's - `ShaderBuilder` is the precedent. Since alktype + handlebars are - already wasm-clean, a wasm build can carry the render-then-compile - cache itself (render as the JIT step at runtime). Far down the - timeline, but it fixes one design requirement today: keep partials +- **WGSL (confirmed coming; branch 3 territory)**: alkminer-v1's + `ShaderBuilder` is the precedent, and the JS runtime will require + codegen that generates the WGSL. There is prior research in that + direction in the family. Because alktype + handlebars are already + wasm-clean, a wasm build can carry the render-then-compile cache + itself (render as the JIT step at runtime). Far down the timeline, + but it fixes one design requirement today: keep partials first-class and keep rendering pure, synchronous, and deterministic so the render step can be cached and compiled downstream. Retrofit cost would be high later, preservation cost now is near zero. +Framing correction (2026-11-06, same discussion, second steer): the +"document generation vs code generation" split above carries a false +distinction. The core is a text-generation engine: contexts + +templates + partials → text. HTML is what handlebars was designed +for, Rust codecs are proven by the reader POC, and WGSL is proven by +alkminer's kernel builder; three data points, one shape. Neither the +registry/layout/render machinery nor the context interface changes +because the output text happens to be code: if the core can generate +valid HTML, it can generate valid code. What genuinely differs per +target is only: + +- the template set and context shape (plan-driven projection vs page + data views vs shader contexts); +- the emit posture (static files at build time vs in-library render + vs render-then-compile feed); +- the validity pinning (each template set's render tests pin its + notion of valid output; the core cannot know what "valid" means + for WGSL vs HTML vs Rust and should not pretend to). + Concretely, the working split for Phase 1: - **Shared core**: registry construction (strict mode, first-class partials), context conventions, deterministic render entry point, typed errors. Everything wasm-clean, synchronous, allocation-lean. -- **Per target**: the template set, the context shape (plan-driven - projection vs page/data views vs shader contexts), and the emit - posture (static files at build time vs in-library render vs - render-then-compile feed). +- **Per target**: the template set, the context shape, the emit + posture, and the validity pinning. - **Demoted, not dead**: the dev-tool emit model (OQ-GN-01) stays the shape of branches 1/2's output but is no longer the definition of - the crate; the crate is "template rendering over alk-type documents - and arbitrary contexts", with targets as template sets plus emit - layers. + the crate; the crate is "text generation from templates and + partials over typed contexts", with targets as template sets plus + emit layers. This refines OQ-GN-09: the SSR branch is not a special case to be accommodated; it is the first instantiation and the generality test. +WGSL is the third instantiation and needs nothing from the core that +the first two do not already require. ## What is already settled