diff --git a/tasks/implementation/review-wave-2.md b/tasks/implementation/review-wave-2.md index 5dabc04..7e7eff8 100644 --- a/tasks/implementation/review-wave-2.md +++ b/tasks/implementation/review-wave-2.md @@ -1,7 +1,7 @@ --- id: review-wave-2 name: "Wave 2 gate: consumer-shaped proofs and the conformance battery" -status: pending +status: completed depends_on: [w2-ssr-proof, w2-code-proof, w2-conformance-battery] scope: narrow risk: low @@ -17,35 +17,35 @@ 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 +- [x] `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 +- [x] `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 +- [x] 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 +- [x] 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 +- [x] 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 +- [x] 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: +- [x] 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 +- [x] gate verdict recorded in Notes: wave-3 decomposition unblocked, or blockers + booked findings listed ## References @@ -62,8 +62,139 @@ disposes of the generality claim and any stop-and-book findings. ## Notes -Gate verdict: to be filled by the review agent. +**Gate verdict: GREEN. Wave-3 decomposition unblocked. No blockers, no +booked findings; one minor inline fix applied (checkbox state in +`w2-conformance-battery.md`, see below). The generality claim holds on +the real code.** + +Gate review performed 2026-11-07 over the three wave-2 implementation +commits (08803b3, 3b0483e, 952f208; hashes verified against the +decomposition record) by reading the full landed tree (tests/ +conformance.rs, tests/ssr_proof.rs, tests/code_proof.rs, the fixture +files, src/lib.rs, src/error.rs, src/escape.rs, src/registry.rs, +AGENTS.md, the task notes) against emit.md (postures A/B/C and the +cross-posture obligations table), core.md, and ADR-001/003/005/008. + +**w2-ssr-proof vs emit.md posture B (line by line):** +Consumer-supplied registration verified in code: every asset +registers from the test binary through `register_template` / +`register_partial`, in three caller-supplied text shapes at once +(`include_str!` fixtures, a runtime-built `String`, an inline +literal), the ADR-008 machinery-equality posture. Output unit: +`page.hbs` composes the header/nav/footer/card partials via includes +(verified in the fixture file), and `card` registers as its own +template and renders directly by name, with a partial's name rejected +as typed `Error::Render` (the core.md render-name rule). Escape +goldens pin hostile interpolation entity-escaped (including `=` and +`'` inside attribute values) and a deliberate `{{& }}` raw slot +passing verbatim. Error-page mapping: a strict-mode failure on +`settings_page` maps consumer-side to a consumer-owned error page +built from `err.to_string()` and `err.source()`, panic-free, with the +failing template's identity and missing path entity-escaped in the +pinned output. Determinism pinned across repeats, registry rebuilds, +fresh contexts, and both sinks. Hygiene rows: output pinned to start +at the doctype with no banner markers; no filesystem path exists by +construction. No unrecorded divergences. The whitespace observations +in both proofs' Notes are correctly dispositioned as pinned substrate +behavior, not gaps. + +**w2-code-proof vs emit.md postures A/C and ADR-003 (line by +line):** Typed context built by a Rust builder from the document +fixture with document-ordered arrays (zeta, magic, alpha, length, +chosen so document order differs from both sort and reverse order; +verified in code and goldens), and the reordered-array row proves the +array's new order drives the render. No-op escaping verified in both +directions (builder-quoted source-escaped literals verbatim, +pre-escape-shaped text unprocessed). The ADR-003 determinism +invariant is pinned at full strength: byte-identical across repeated +renders, independent registry rebuilds, differing registration +orders, fresh contexts, and `render` vs `render_to_write` on both +template kinds. The banner-gap note is honest as required: no test +asserts anything banner-related, and emit.md's posture-A banner row +is recorded as an emit-layer obligation with no engine-owned set in +v0.1.0 to exercise it; the proof asserts nothing implying coverage. + +**Stop-and-book ledger:** clean. All three tasks state "no core +changes required; nothing to book" and `git show --stat` confirms: +all three commits touch only tests/, fixtures, task files, and +AGENTS.md, zero `src/` changes. The one substrate observation the +battery surfaced (handlebars treats the expression name `raw` as +keyword-shaped and never resolves it as a context variable) is +dispositioned as data in the battery's Notes with the avoidance +reason documented in a doc comment; no consumer behavior change is +implied and no core change is booked for v0.1.0. No silent core +changes; no exceptions needing rationale. + +**Generality claim disposition:** ADR-001 holds on the real code. +Both consumer-shaped postures (B: HTML SSR with error mapping and +caching-grade determinism; A/C-shaped: codegen with document order +and regeneration determinism) were served by the shipped core through +the public API with no core exceptions. This is the falsifiability +discipline ADR-001 asks for, exercised on postures that sit at the +opposite ends of the target spectrum. + +**Conformance battery as the standing set:** verified, not just +asserted. `tests/conformance.rs` carries 13 rows: the strict-mode +matrix (top-level, `{{#each}}`, `{{#if}}` then and else branches, +each typed through both sinks, plus the write sink's no-atomicity +contract pinned by the `"prefix-ok\n"` row), error-surface +completeness (six failure paths each mapping to exactly one variant, +no half registrations including the failed-overwrite case, unknown +template including the empty name, hostile values through both sinks +and both escape policies with byte-pinned expectations, no panic +paths), and two-sink byte-equality over both postures with +posture-identity assertions proving the exercised rows are the real +shapes. AGENTS.md carries the wasm release build as a standing, +unconditional verification entry with the feature-matrix +coincide-today posture (ADR-009) and the handlebars +feature-inspection posture documented; the wave-1 gate's reminder +(b) is thereby absorbed as planned, and reminders (a) (freeze +inventory decides `#[non_exhaustive]`) and (c) (CI feature matrix +when the first feature gates something) remain correctly unassigned +as wave-3 concerns. + +**Conventions audit (re-run by the gate):** zero `unwrap`/`expect`/ +panics/`unsafe`/async/tokio/`std::fs`/`std::time`/`std::env`/threads +in non-test lib code (every `expect`/`panic!` hit is inside +`#[cfg(test)]` modules in src, permitted; tests use +`expect_err`/`unwrap_or_else(panic)` idiomatically); doc comments on +all public API with no inline `//` in src outside test banners; the +em-dash grep shows hits only in `docs/research/reader-poc-summary.md` +numeric ranges (2.4-2.7 us style), which convention 12 exempts (en +dashes inside numeric ranges), plus the grep command's own pattern +text in AGENTS.md (the wave-1 reading: a self-reference); fixture +data and goldens survive verbatim, prose in tests and tasks is clean +following the wave-1 reading. `preserve_order` untouched and +load-bearing (re-pinned by the code proof). + +**Verification set (re-run clean by the gate on the final wave-2 +tree):** `cargo test` (19 lib + 13 conformance + 7 code_proof + 4 +ssr_proof + 5 code_fixtures + 3 ssr_fixtures = 51 passing), +`cargo test --all-features` (identical; the coincide holds), +`cargo clippy --all-targets -- -D warnings` (clean), `cargo fmt +--check` (clean), `cargo doc --no-deps` (clean), `cargo build +--target wasm32-unknown-unknown --release` (clean), `taskgraph +validate` (18 tasks valid), and the ADR-002 tree inspection (`cargo +tree --all-targets -f "{p} {f}"`: `handlebars v6.4.4 default` only, +no `dir_source`, no `script_helper`). + +**Inline fix applied by the gate:** `w2-conformance-battery.md`'s +acceptance-criteria checkboxes were all done and verified but had +been left unchecked while the task shipped as `completed`; the gate +checked them and left a one-line note in that file. Nothing else +warranted an inline change. ## Summary -> To be filled on completion +Wave-2 gate passed green. The ssr proof (posture B) and code proof +(postures A/C shape) hold against emit.md and core.md line by line on +shipped code, the stop-and-book ledger is empty with zero core +changes across the wave, and ADR-001's generality claim is +dispositioned as holding on the real code. The conformance battery +stands as the standing verification home with its rows verified in +code, AGENTS.md carries the standing wasm build and feature-matrix +postures, and the conventions audit plus the full verification set +(including wasm release and the handlebars tree inspection) are +clean, re-run by the gate. One inline fix: checked the battery task's +completed-but-unchecked acceptance boxes. Wave-3 (validation and +release) decomposition is unblocked. diff --git a/tasks/implementation/w2-conformance-battery.md b/tasks/implementation/w2-conformance-battery.md index 7e74168..84c0ba5 100644 --- a/tasks/implementation/w2-conformance-battery.md +++ b/tasks/implementation/w2-conformance-battery.md @@ -60,30 +60,34 @@ workaround. ## Acceptance Criteria -- [ ] a standing conformance test binary exists +- [x] 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, +- [x] 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 +- [x] 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 +- [x] 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 +- [x] 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 +- [x] `cargo test` with `default` and with `--all-features` both pass -- [ ] full verification set green: `cargo test`, +- [x] full verification set green: `cargo test`, `cargo clippy --all-targets -- -D warnings`, `cargo fmt --check`, `cargo doc --no-deps`, `taskgraph validate` +> Checkbox state corrected by the wave-2 gate (2026-11-07): the work +> was done and verified but the boxes were left unchecked; see +> review-wave-2 Notes. + ## References - docs/plans/implementation.md (wave 2, the conformance battery