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
This commit is contained in:
glm-5.3-flash committed 2026-11-06 20:16:11 +00:00
1 parent 0a4aa1eefe
commit a4ec8be3e8
5 files changed
+400 -2

No files matched your search

+31 -2
View File
@@ -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
+69
View File
@@ -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
+94
View File
@@ -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
@@ -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
+98
View File
@@ -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