feat(phase-5): salvage synthetic retired-Ward corpus onto hardened core (threads-uqx.13)#21
Conversation
Introduces a public, repository-authored synthetic corpus for Phase 5 retired-Ward approval semantics, including a canonical JSON generator example and digest-pinned conformance tests. Coverage now spans identity invariants, approval paths/labels, veto windows, region classification fidelity, and fail-closed unsupported cases. Also tightens `MaterializedDiff::try_new` to reject surfaces with neither `before` nor `after`, and unchanged surfaces, with matching unit tests and design-spec tracking updated in `PHASE-5-APPROVAL-SEMANTICS.md`.
|
🔎 Verified-loop iteration 2 in flight: an independent fresh-context verifier (separate session, holds the frozen threads-uqx.13 rubric from the 2026-07-21 loop) is scoring PR head |
|
✅ Verified-loop iteration 2: PASS — 97/100, all mandatory minima met (threshold ≥92; every dimension ≥ its minimum). Fresh-context verifier, PR head
All packet commands exit 0: corpus tests 4/4, full crate suite 176+17+4+14 pass / 0 fail, fmt clean, clippy Non-blocking follow-ups (verifier suggestions, fine post-merge):
Note for reviewers: |
There was a problem hiding this comment.
Pull request overview
This PR implements the salvage plan from #20 by bringing the synthetic retired-Ward Phase 5 corpus fixtures (and the minimal supporting hardening in MaterializedDiff::try_new) onto the veto-hardened core from #15, enabling digest-pinned conformance testing without relying on any historical/private Ward data.
Changes:
- Adds a repository-authored synthetic corpus builder plus digest-pinned conformance tests for identity fields, approval labels, veto windows, and surface-region classification.
- Tightens
MaterializedDiff::try_newto fail closed on surfaces with neitherbeforenorafter, and on unchanged surfaces, with unit tests. - Adds a canonical example binary for emitting the corpus JSON and updates the Phase 5 approval-semantics spec tracking entry.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| specs/PHASE-5-APPROVAL-SEMANTICS.md | Adds a threads-uqx.13 tracking entry documenting the public synthetic corpus and generator invocation. |
| crates/coven-threads-core/tests/support/phase5_retired_ward_corpus.rs | Introduces the synthetic retired-Ward corpus JSON builder with provenance assertions and valid/unsupported cases. |
| crates/coven-threads-core/tests/phase5_retired_ward_corpus.rs | Adds conformance tests validating identity invariants, approval/veto semantics, region classification fidelity, and pinned SHA-256 digest. |
| crates/coven-threads-core/src/surface_regions.rs | Hardens MaterializedDiff::try_new to reject absent-both and unchanged surfaces; adds unit tests. |
| crates/coven-threads-core/examples/generate_phase5_retired_ward_corpus.rs | Adds a canonical generator example for emitting the corpus as deterministic JSON. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| unsupported cases without using historical or private Ward data. Generate it | ||
| with `cargo run -q -p coven-threads-core --example | ||
| generate_phase5_retired_ward_corpus`. |
…stry-derived region assertion, documented digest (#22) Non-blocking follow-ups from the threads-uqx.13 verified-loop iteration-2 report (PR #21): 1. Add an AutoRegression { veto: null } valid corpus case — a legal configuration the harness supported but the corpus never exercised; pins the hardened wire shape (veto key present, null resolves to no window). 2. Derive the all-regions coverage assertion from SurfaceRegionRegistry::default_registry().descriptors() so a future built-in region flags corpus staleness instead of passing silently. 3. Document the pinned canonical SHA-256 next to the generation command in specs/PHASE-5-APPROVAL-SEMANTICS.md, including the trailing-newline nuance. Corpus digest moves once: 4ebe9d63398e6b14f2a097ce66197c96a577559984515ce03ce4297c0b0c7e10. Validation: corpus tests 4/4, full crate suite 176+17+4+14 green, fmt clean, clippy -D warnings clean; emitted-artifact digest reproduced via tr -d '\n' | shasum. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Executes the salvage plan from #20: cherry-picks the retired-Ward corpus fixtures from closed #17 (tip
c6cdb60) cleanly onto main, after #15 (ee3cc29) landed the canonical veto-hardened core. Closes #20; beadthreads-uqx.13.Included (corpus fixtures only, per #20):
tests/support/phase5_retired_ward_corpus.rs— repository-authored synthetic corpus builder (no historical/private Ward data; provenance block assertshistorical_data_used: false)tests/phase5_retired_ward_corpus.rs— digest-pinned conformance tests: 5 identity fields, all 4 approval labels, veto windows, region-classification fidelity +path_tier_floor, and 6 fail-closed unsupported casesexamples/generate_phase5_retired_ward_corpus.rs— canonical JSON generator (cargo run -q -p coven-threads-core --example generate_phase5_retired_ward_corpus)src/surface_regions.rs— tightensMaterializedDiff::try_newto reject absent-both and unchanged surfaces (the fail-closed defect flagged in the uqx.13 verification loop: 12/15 → fixed), with unit testsspecs/PHASE-5-APPROVAL-SEMANTICS.md§7 — uqx.13 tracking entryExplicitly NOT included: #17's
approval.rs/audit.rs/identity_invariants.rschanges — those regressed #15'sdeserialize_required_vetohardening and are why #17 closed.Validation (fresh worktree off main)
cargo fmt --checkcleancargo test -p coven-threads-core— 176 + 17 + 4 + 14 pass, 0 failcargo clippy -p coven-threads-core --all-targets -- -D warningscleanb3c5f156…db44; generator output reproduces the pin byte-for-byteGate
Draft until Echo semantic validation (owner per #20) + Nova/Val review. Verified fixtures compile and pass against #15's veto-hardened
ApprovalPathshape (wire keyauto_regression.vetorequired; corpus valid-cases carry explicit veto objects).