From a4ec8be3e86b1e26f30bf4a25bf9bf4cd070f47e Mon Sep 17 00:00:00 2001 From: "glm-5.3-flash" Date: Fri, 6 Nov 2026 20:16:11 +0000 Subject: [PATCH] chore(tasks): decompose wave 2 into implementation tasks - w2-ssr-proof and w2-code-proof: the two consumer-shaped proofs, parallel by construction (own test binaries, own fixture modules per the wave-1 convention) - w2-conformance-battery: the standing verification set, ordered after the proofs so it consolidates over the final wave-2 tree and absorbs any stop-and-book findings; folds the wave-1 gate's reminder (b) (wasm build standing, not ad-hoc) - review-wave-2: the wave gate, depends on all three - decomposition record added to docs/plans/implementation.md with the logistic-ordering rationale; wave-2 status flipped to decomposed Verification: taskgraph validate (18 tasks valid); em-dash grep clean on all changed files --- docs/plans/implementation.md | 33 +++++- tasks/implementation/review-wave-2.md | 69 +++++++++++ tasks/implementation/w2-code-proof.md | 94 +++++++++++++++ .../implementation/w2-conformance-battery.md | 108 ++++++++++++++++++ tasks/implementation/w2-ssr-proof.md | 98 ++++++++++++++++ 5 files changed, 400 insertions(+), 2 deletions(-) create mode 100644 tasks/implementation/review-wave-2.md create mode 100644 tasks/implementation/w2-code-proof.md create mode 100644 tasks/implementation/w2-conformance-battery.md create mode 100644 tasks/implementation/w2-ssr-proof.md diff --git a/docs/plans/implementation.md b/docs/plans/implementation.md index c446d53..634f7cb 100644 --- a/docs/plans/implementation.md +++ b/docs/plans/implementation.md @@ -1,7 +1,8 @@ --- status: open last_updated: 2026-11-06 (created at the start of implementation; - wave 1 decomposed the same day) + wave 1 decomposed and its gate passed the same day; wave 2 + decomposed immediately after) --- # alkgen: Implementation plan @@ -84,7 +85,7 @@ Dependency logic in one line: core foundations (consumer-shaped proofs | Wave | Contents | Depends on | Status | |---|---|---|---| | [1](#wave-1-the-core) | The core: manifest landing (dep pins, alktype removal, feature graph); the public error model; registry construction (strict mode, escaper policy, typed registration, helper seam); the render entry point (two sinks); engine fixture doubles | none | decomposed | -| [2](#wave-2-consumer-shaped-proofs) | The generality proofs on shipped code: the full ssr-shaped (posture-B) fixture through the public API; the code-shaped (posture-A/C) fixture with ordering and determinism invariants; the conformance battery (strict-mode matrix, error surface, two-sink correctness, wasm, feature matrix) | wave 1 | planned | +| [2](#wave-2-consumer-shaped-proofs) | The generality proofs on shipped code: the full ssr-shaped (posture-B) fixture through the public API; the code-shaped (posture-A/C) fixture with ordering and determinism invariants; the conformance battery (strict-mode matrix, error surface, two-sink correctness, wasm, feature matrix) | wave 1 | decomposed | | [3](#wave-3-validation--release) | Release readiness (README, CHANGELOG, rustdoc, dry-run, freeze inventory); the release gate; the publish | waves 1 + 2 | planned | ## Wave 1: The core @@ -233,6 +234,34 @@ falsifiability discipline). Wave 2 decomposes after the wave-1 gate, absorbing whatever it corrects. +**Decomposition record** (2026-11-06, immediately after the wave-1 +gate passed green; that gate absorbed no corrections, so nothing above +changes): wave 2 decomposes into three implementation tasks plus the +gate under `tasks/implementation/`. Shape: `w2-ssr-proof` and +`w2-code-proof` carry the two consumer-shaped proofs and are parallel +by construction: each lives in its own test binary owning its fixture +modules per the wave-1 convention, so there is nothing to sequence +between them and no shared-module collisions. Then +`w2-conformance-battery` depends on both proofs. The dependency line +above reads proofs ∥ battery and the wave releases when both groups +hold; the battery ordered after the proofs is a logistic choice with +the wave-1 precedent (a chain is sequential *logistically*, not +necessarily in working time): the battery consolidates the standing +verification set over the final wave-2 tree (strict-mode matrix, +error-surface rows, two-sink rows, feature-matrix posture, the wasm +build joining the verification list), which is only meaningful once +the proofs it stands beside have landed, and if a proof books a +finding under the stop-and-book rule, the battery would order itself +over the corrected surface rather than pin rows twice. Finally +`review-wave-2` (the wave gate) depends on all three. Carried +reminders from the wave-1 gate: (b) folds into the conformance task +(the wasm build becomes a standing, unconditional entry in the +verification command list rather than an ad-hoc gate run); (a) and +(c) remain wave-3 concerns and are deliberately unassigned here. The +stop-and-book rule applies throughout this wave: a proof that finds a +needed core exception books it for the gate with written rationale +and never silently absorbs it (ADR-001's falsifiability discipline). + ## Wave 3: Validation & release - **Release readiness**: public-API rustdoc warning-free; README diff --git a/tasks/implementation/review-wave-2.md b/tasks/implementation/review-wave-2.md new file mode 100644 index 0000000..5dabc04 --- /dev/null +++ b/tasks/implementation/review-wave-2.md @@ -0,0 +1,69 @@ +--- +id: review-wave-2 +name: "Wave 2 gate: consumer-shaped proofs and the conformance battery" +status: pending +depends_on: [w2-ssr-proof, w2-code-proof, w2-conformance-battery] +scope: narrow +risk: low +impact: phase +level: review +--- + +## Description + +The wave-2 gate. Wave boundaries are review boundaries; this one +reads the wave's proofs and battery against the architecture and +disposes of the generality claim and any stop-and-book findings. + +## Acceptance Criteria + +- [ ] `w2-ssr-proof` checked against emit.md posture B line by line + (consumer-supplied registration, fragments as render targets, + escape golden pins, error-page mapping, determinism, hygiene + rows); no unrecorded divergences +- [ ] `w2-code-proof` checked against emit.md postures A/C and + ADR-003's determinism invariant line by line (document-ordered + contexts, no-op escaping, rebuild determinism, two-sink + equality); the banner-gap note is honest +- [ ] the stop-and-book ledger is clean: every gap found during the + proofs is dispositioned in Notes (no silent core changes; any + booked core exception carries written rationale or is resolved) +- [ ] the generality claim disposition recorded: ADR-001 holds on + the real code (no consumer-specific exceptions landed in the + core in wave 2, or the booked exceptions are fully argued) +- [ ] the conformance battery verified as the standing verification + set: strict-mode matrix, error-surface rows, two-sink rows, + feature-matrix posture, wasm build standing in the + verification command list +- [ ] conventions audit: no `unwrap`/`expect`/panics in `src/`, no + unsafe, no async, no filesystem access, doc comments only on + public API, no em dashes in prose (tests and fixtures follow + the wave-1 reading: prose-y content rewritten, fixture data + and goldens survive verbatim) +- [ ] full verification set re-run clean on the final wave-2 tree: + `cargo test`, `cargo clippy --all-targets -- -D warnings`, + `cargo fmt --check`, `cargo doc --no-deps`, + `cargo build --target wasm32-unknown-unknown --release`, + `taskgraph validate` +- [ ] gate verdict recorded in Notes: wave-3 decomposition + unblocked, or blockers + booked findings listed + +## References + +- docs/plans/implementation.md (wave 2 section and the + decomposition record) +- docs/architecture/core.md, emit.md, targets.md +- docs/architecture/decisions/001-one-core-template-set-targets.md +- docs/architecture/decisions/003-core-posture-sync-wasm-deterministic.md +- docs/architecture/decisions/005-escape-strategy-per-template-set.md +- docs/architecture/decisions/008-template-set-ownership.md +- tasks/implementation/w2-ssr-proof.md, w2-code-proof.md, + w2-conformance-battery.md + +## Notes + +Gate verdict: to be filled by the review agent. + +## Summary + +> To be filled on completion diff --git a/tasks/implementation/w2-code-proof.md b/tasks/implementation/w2-code-proof.md new file mode 100644 index 0000000..ed286df --- /dev/null +++ b/tasks/implementation/w2-code-proof.md @@ -0,0 +1,94 @@ +--- +id: w2-code-proof +name: "Wave 2: the code-shape proof (posture-A/C, ordering and determinism invariants)" +status: pending +depends_on: [] +scope: narrow +risk: low +impact: component +level: implementation +--- + +## Description + +The generality claim re-proven on shipped code for the posture-A/C +shapes (emit.md): a code-shaped fixture set exercising the codec/JIT +context shape on the shipped core. This is the shape generated +artifact hygiene rests on: document-ordered contexts, no-op +escaping, and determinism that makes regeneration diff-quiet +(posture A) and output compilable (posture C). + +The proof lives in its own test binary (`tests/code_proof.rs`) with +its own fixture assets under `tests/fixtures/code_proof/`, per the +wave-1 per-binary fixture module convention. It grows beyond the +wave-1 double where the deep invariants live (the wave-1 double +pinned insertion-order arrays and the active `preserve_order` +feature; this proof pins the cross-registry determinism rows). + +- **Typed context with document-ordered arrays** (convention 5, + ADR-004): a typed context built by a Rust builder from a + document-shaped fixture, arrays in document order, kind mapping in + builder code, templates as dumb conditionals. The + `preserve_order` load-bearing expectation is exercised again on + the new set: document order drives rendered order. +- **No-op escaping** (ADR-005): the code posture renders without + entity mangling; source-escaped literals pass through verbatim. +- **The determinism invariant** (ADR-003, the row generated-artifact + hygiene depends on): byte-identical output across repeated renders + within one registry, and across independent registry rebuilds from + the same assets, including a rebuild registering in a different + order (registration-order independence over the code-shaped set, + the posture-A regeneration posture). +- **Both sinks in the determinism rows**: the streamed + `render_to_write` output is byte-identical to the `render` String + output on the same set and context. +- **The banner gap, stated honestly** (convention 8, emit.md posture + A): the DO-NOT-EDIT banner is an emit-layer obligation and no + engine-owned set ships in v0.1.0 to exercise it. The proof's + templates model artifact shape without asserting any banner; the + gap is recorded in Notes, never implied as coverage. + +The stop-and-book rule applies as in the ssr proof: a needed core +exception is booked for the gate with written rationale, never +silently absorbed. + +## Acceptance Criteria + +- [ ] the code-shaped fixture set registers and renders through the + public API with no-op escaping over a typed context with + document-ordered arrays built by a Rust builder +- [ ] byte-identical output across repeated renders within one + registry +- [ ] byte-identical output across independent registry rebuilds + from the same assets, including a differing registration order +- [ ] `render` and `render_to_write` produce byte-identical output + for the same set and context +- [ ] document order (not sort or hash order) drives rendered order + on the new proof set +- [ ] the DO-NOT-EDIT banner gap recorded honestly in Notes; tests + assert nothing banner-related +- [ ] `cargo test`, `cargo clippy --all-targets -- -D warnings`, + `cargo fmt --check` pass +- [ ] no core changes required; any gap found is booked for the gate + in Notes per the stop-and-book rule + +## References + +- docs/plans/implementation.md (wave 2, the code-shape proof bullet) +- docs/architecture/core.md (context conventions, render entry point) +- docs/architecture/emit.md (postures A and C) +- docs/architecture/decisions/001-one-core-template-set-targets.md +- docs/architecture/decisions/003-core-posture-sync-wasm-deterministic.md + (the determinism invariant) +- docs/architecture/decisions/004-typed-contexts-builders-not-templates.md +- docs/research/reader-poc-summary.md (the POC findings informing + the code-context shape this proof models) +- tests/code_fixtures.rs (the wave-1 double this proof grows beyond) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion diff --git a/tasks/implementation/w2-conformance-battery.md b/tasks/implementation/w2-conformance-battery.md new file mode 100644 index 0000000..2ec803e --- /dev/null +++ b/tasks/implementation/w2-conformance-battery.md @@ -0,0 +1,108 @@ +--- +id: w2-conformance-battery +name: "Wave 2: the conformance battery (strict-mode matrix, error surface, two sinks, wasm, feature matrix)" +status: pending +depends_on: [w2-ssr-proof, w2-code-proof] +scope: moderate +risk: low +impact: phase +level: implementation +--- + +## Description + +The standing verification set for the core, established as code and +as process: the rows the core's consumers (and every later wave) +lean on, collected in one standing test binary so future waves grow +rows there rather than scattering them. Rows already pinned by +wave-1 unit tests may be referenced and re-exercised, not duplicated +blindly; the battery's job is the standing home plus the rows not +yet pinned. + +- **Strict-mode behavior matrix** (ADR-002, core.md): a missing + context variable is a typed `Error::Render` through both sinks + (`render` and `render_to_write`), never silent output: top-level + variables and variables nested in `{{#each}}`/`{{#if}}` branches + both covered. The write sink's behavior on failure (typed error, + no partial-write contract beyond what wave 1 pinned) is stated by + the matrix rows. +- **Error-surface completeness** (core.md error model, convention + 2): every engine-owned failure path maps to exactly one typed + variant, with no catch-all: malformed template text at + registration resolves to `Error::Registration` and never survives + as a half-registered name; render-time failures (unknown template + name, partial name as render target, strict missing variable, + unknown helper) resolve to `Error::Render`; hostile context values + rendered through both sinks produce typed data or clean output, + never panics. No input the API accepts reaches a panic path. +- **Two-sink correctness rows** (core.md): for each fixture posture + (ssr-shaped and code-shaped), `render` and `render_to_write` + produce byte-identical output on the same context. +- **The wasm build joins the verification list** (ADR-003, wave-1 + gate reminder (b)): the final wave-2 dep set builds clean to + `wasm32-unknown-unknown` release, and the wasm entry becomes a + standing, unconditional line in the repo's verification command + list (the AGENTS.md verification section) instead of an ad-hoc + gate-only run. The tree inspection posture (no `dir_source` / + `script_helper` features enabled, per ADR-002) is re-verified on + the wave-2 tree. +- **The feature-matrix posture** (ADR-009, plan wave-2 bullet): + `cargo test` with `default` features and with `--all-features` + both pass (they coincide today since `bast-codegen` gates + nothing), and the coincide-today posture is documented honestly + where the verification list lands, to be grown when the first + feature starts gating something. + +The stop-and-book rule applies here too, though no core change is +expected: the battery is verification, and a battery row that +cannot pass without a core change is a booked finding, not a +workaround. + +## Acceptance Criteria + +- [ ] a standing conformance test binary exists + (`tests/conformance.rs`); the strict-mode matrix covers + missing variables through both sinks (top-level and nested + contexts) and asserts typed errors, never silent output +- [ ] error-surface completeness rows: registration parse failure, + unknown template, partial-as-render-target, strict missing + variable, unknown helper, hostile context values: each maps to + exactly one typed variant; no panic paths through either sink +- [ ] two-sink correctness rows: String and `io::Write` sinks are + byte-identical across the ssr-shaped and code-shaped fixture + postures +- [ ] the wasm build of the final wave-2 dep set passes release + build to `wasm32-unknown-unknown`; the tree inspection shows + no off-limits handlebars features enabled +- [ ] the verification command list in AGENTS.md carries the wasm + build as a standing, unconditional entry, and the + feature-matrix coincide-today posture is documented there + honestly (both edits recorded in Notes) +- [ ] `cargo test` with `default` and with `--all-features` both + pass +- [ ] full verification set green: `cargo test`, + `cargo clippy --all-targets -- -D warnings`, `cargo fmt + --check`, `cargo doc --no-deps`, `taskgraph validate` + +## References + +- docs/plans/implementation.md (wave 2, the conformance battery + bullet) +- tasks/implementation/review-wave-1.md (gate reminder (b): wasm + pinning standing, not ad-hoc) +- docs/architecture/core.md (render entry point, error model) +- docs/architecture/emit.md (the cross-posture obligations table + this battery makes standing) +- docs/architecture/decisions/002-handlebars-substrate-strict-mode.md +- docs/architecture/decisions/003-core-posture-sync-wasm-deterministic.md +- docs/architecture/decisions/009-feature-gated-template-sets.md +- src/registry.rs, src/error.rs (the wave-1 unit-test rows the + battery sits beside) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion diff --git a/tasks/implementation/w2-ssr-proof.md b/tasks/implementation/w2-ssr-proof.md new file mode 100644 index 0000000..7788da9 --- /dev/null +++ b/tasks/implementation/w2-ssr-proof.md @@ -0,0 +1,98 @@ +--- +id: w2-ssr-proof +name: "Wave 2: the ssr-html proof (posture B, consumer-shaped fixture through the public API)" +status: pending +depends_on: [] +scope: narrow +risk: low +impact: component +level: implementation +--- + +## Description + +The generality claim re-proven on shipped code for the posture-B +shape (emit.md): a full consumer-shaped fixture set, modeled on the +alkforge posture, rendered entirely through the public API. Where the +wave-1 double proved the machinery minimally, this proof walks the +ssr-html target's real shape at fuller scale: if the shipped core +serves a consumer-shaped set with no core exceptions, ADR-001's +generality claim holds on the real code, not just the POC. + +The proof lives in its own test binary (`tests/ssr_proof.rs`) with +its own fixture assets under `tests/fixtures/ssr_proof/`, following +the wave-1 convention that each test binary owns its fixture modules +(no module-sharing collisions with the wave-1 doubles; shared assets +may be re-included via `include_str!` of the same files). + +- **Consumer-supplied registration** (ADR-008 machinery equality): + every page template and partial registers from the test binary as + caller-supplied text through `register_template` / + `register_partial`, the identical machinery engine-owned sets use. + No core source access, no second-class path. +- **Pages compose fragments; fragments render directly** (core.md + render-name rule, emit.md posture B output unit): a full page + template composes fragment partials via includes; at least one + fragment a consumer would serve directly (header, nav, or card + shape) registers as its own template and is rendered by name, never + as a bare partial. +- **HTML-escape golden pins** (ADR-005, convention 7): goldens pin + hostile interpolated data entity-escaped, and a deliberate + raw-output slot (`{{& }}`) pinned passing through verbatim. +- **Error-page mapping** (posture-B error posture, emit.md): a + strict-mode render failure returns the typed `Error`; the proof + maps it consumer-side toward an error-page shape (a fallback page + built from the error's data) without panics, demonstrating that + everything a consumer needs for the mapping is reachable through + the public enum. +- **Determinism as the caching substrate** (ADR-003): repeated + renders are byte-identical; this is the property alkforge's + content-hash caching rests on. +- **Posture-B hygiene rows**: no banner, no filesystem, no + emit-layer output hygiene beyond what `render` returns. + +The stop-and-book rule applies: if the proof finds the shipped core +cannot serve this set without a core change, book it for the gate +with written rationale; never silently absorb it and never patch the +core invisibly (ADR-001 falsifiability discipline). + +## Acceptance Criteria + +- [ ] the full fixture set registers from outside the crate through + the public API only (caller-supplied text; ADR-008 equality + exercised at posture-B scale) +- [ ] a page template composes fragment partials; at least one + fragment is a registered template rendered directly by name +- [ ] HTML-escape goldens pin: interpolated hostile data escaped, a + deliberate raw-output slot verbatim +- [ ] a strict-mode render failure maps toward the error-page shape + through the typed error, panic-free, using only public API + data +- [ ] repeated renders produce byte-identical output +- [ ] posture-B hygiene rows confirmed: no banner, no filesystem +- [ ] `cargo test`, `cargo clippy --all-targets -- -D warnings`, + `cargo fmt --check` pass +- [ ] no core changes required; any gap found is booked for the gate + in Notes per the stop-and-book rule + +## References + +- docs/plans/implementation.md (wave 2, the ssr-html proof bullet) +- docs/architecture/core.md (registry construction, render entry + point, template assets) +- docs/architecture/emit.md (posture B: consumer, output unit, + hygiene, errors) +- docs/architecture/decisions/001-one-core-template-set-targets.md + (the generality claim being re-proven) +- docs/architecture/decisions/006-ssr-library-posture.md +- docs/architecture/decisions/008-template-set-ownership.md +- tests/ssr_fixtures.rs (the wave-1 double this proof grows beyond; + per-binary fixture module convention) + +## Notes + +> To be filled by implementation agent + +## Summary + +> To be filled on completion