feat(ward-migrate): compile-or-reject v0.1 identity invariants; bump coven-threads-core pin#464
feat(ward-migrate): compile-or-reject v0.1 identity invariants; bump coven-threads-core pin#464BunsDev wants to merge 2 commits into
Conversation
…coven-threads-core to threads main Closes the silent-drop gap in ward migration (threads-uqx.8): v0.1 [protected].invariants were previously deserialized away without a trace. Now every retired declaration is compiled through coven-threads-core's IdentityInvariantSet compiler: - all declarations compile -> migration proceeds; per-declaration dispositions (typed fact + operator) recorded in the report and the originals preserved in ward.toml.v01.bak (Phase-2 ward.toml has no invariants surface, so they are never carried forward silently) - any declaration rejected -> migration fails closed (Unmigratable) with the compiler's explicit indexed reasons; nothing written - no invariants -> nothing to preserve, no dispositions Bumps the coven-threads-core pin 7da030d -> 6fa360b (threads main), picking up the post-#15/#21/#22 hardened core (tightened MaterializedDiff::try_new, approval/audit/identity-invariant hardening). Full workspace fmt/clippy/test green against the new pin. Tests mirror the phase-5 retired-Ward corpus grammar: five-shape fidelity (name/person/pronouns/purpose/coven, ==/includes, both quote styles), explicit rejection per compiler lane (unsupported fact, missing operator, duplicate, empty value, missing mandatory name/person), fail-closed no-write on rejection, and backup-only preservation on apply. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
⚠️ Not ready to approve
The new dry-run report text can incorrectly claim invariants were preserved in the backup file even though dry-run does not write a backup, which makes the migration report misleading.
Pull request overview
This PR tightens coven ward migrate’s v0.1 → Phase-2 migration fidelity by explicitly compiling (or rejecting) retired v0.1 identity invariants via coven-threads-core, avoiding silent drops, and updates the coven-threads-core git pin to a newer reviewed revision.
Changes:
- Parse and gate v0.1
[protected].invariantsthroughIdentityInvariantSet::compile, recording per-declaration dispositions and failing migration closed on any rejection. - Extend the migration report output and tests to cover invariant compilation, rejection lanes, and “no invariants” behavior.
- Bump
coven-threads-coregit rev and updateCargo.lockaccordingly.
File summaries
| File | Description |
|---|---|
| crates/coven-cli/src/ward_migrate.rs | Adds invariant compilation/rejection gate, report dispositions, and expanded migration tests. |
| crates/coven-cli/Cargo.toml | Updates coven-threads-core git pin to 6fa360b. |
| Cargo.lock | Locks the updated git dependency graph from the new pin. |
Review details
- Files reviewed: 2/3 changed files
- Comments generated: 2
- Review effort level: Low
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| message: format!( | ||
| "would migrate Ward v0.1{}", | ||
| invariant_summary_suffix(&invariant_dispositions) | ||
| ), |
| let message = format!( | ||
| "v0.1 [protected].invariants rejected explicitly ({} of {} declarations): {}", | ||
| rejection_reasons.len(), | ||
| legacy_invariants.len(), | ||
| rejection_reasons.join("; "), | ||
| ); |
…riant remnants Review advisories from the fresh-context pass on b39dd22: - A-1: a ward.toml that parses as Phase-2 (WardConfig tolerates unknown fields) but still carries a v0.1 [protected].invariants remnant was blessed AlreadyMigrated, silently ignoring the declarations. Now such hybrids return Unmigratable with the remnant count; the file is left untouched for the principal to fix. - N-1: set-level rejection message now reads 'N rejection(s) across M declaration(s)' instead of the misleading 'N of M declarations'. - N-3: Cargo.lock regenerated via cargo update --precise; the remaining tempfile getrandom 0.4.2->0.3.4 edge re-resolution is within tempfile's declared '>=0.3.0, <0.5' range and CI builds --locked. - N-5: stray indentation normalized. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
✅ Ready to approve
The functional changes and accompanying tests look solid, with only minor doc/error-message clarity nits noted.
Note: this review does not count toward required approvals for merging.
Review details
Comments suppressed due to low confidence (1)
crates/coven-cli/src/ward_migrate.rs:42
MigrationEntry::invariant_dispositionsis documented as "per-declaration", but when compilation fails the current implementation records compiler errors (which can be set-level and may not be 1:1 with declarations). Tighten the doc comment to reflect the actual semantics so the report contract is clear.
/// Per-declaration disposition for v0.1 `[protected].invariants`:
/// each retired declaration either compiled deterministically into a
/// typed identity invariant or was rejected explicitly. Never silent.
pub invariant_dispositions: Vec<InvariantDisposition>,
- Files reviewed: 2/3 changed files
- Comments generated: 1
- Review effort level: Low
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
| message: format!( | ||
| "ward.toml parses as Phase-2 but retains a v0.1 [protected].invariants remnant ({remnants} declaration(s)); Phase-2 has no invariants surface, so these would be silently inert — remove the remnant or restore the v0.1 file and re-run migration" | ||
| ), |
Fresh-context review cycle (informs, does not simulate, the human gates)A fresh-context adversarial review was run against head Verified by the reviewer (independent runs)
Advisories → dispositions
Reviewer's bottom line: "Every migrate lane now terminates in an explicit disposition or an explicit rejection — the never-silent property holds end-to-end. Clean to hand to Nova (uqx.9) and Val (uqx.10)." |
What
Closes the v0.1 invariant silent-drop gap in
coven ward migrateand bumps thecoven-threads-corepin to threads main. Implementation lane for threads-uqx.8 (Phase 5 approval semantics, spec §7).1. Migration invariant fidelity (
ward_migrate.rs)Previously
LegacyProtecteddeserialized onlyfiles, so v0.1[protected].invariantsvanished without a trace — exactly the silent-drop anti-pattern the retired-Ward corpus exists to prevent. Now:coven_threads_core::IdentityInvariantSet::compile) → migration proceeds; per-declaration dispositions (typed fact + operator, no principal values) recorded inMigrationEntry.invariant_dispositionsand rendered in the report; originals preserved verbatim inward.toml.v01.bak. The generated Phase-2ward.tomlhas no invariants surface, so they are never carried forward implicitly — the report says so.Unmigratable, nonzero exit) with the compiler's explicit indexed reasons; the v0.1 file is untouched and no backup is written.2. Pin bump
7da030d→6fa360bThe old rev was an unmerged feature-branch commit (pre-#15 squash). The new pin is coven-threads main, picking up the hardened core from threads PRs #15/#21/#22: tightened
MaterializedDiff::try_new(rejects no-content and unchanged surfaces), approval/audit hardening, identity-invariant compiler. Daemon call sites verified compatible; full workspace green against the new pin.Tests
New coverage mirrors the phase-5 retired-Ward corpus grammar:
name/person/pronouns/purpose/coven,==andincludes, single and double quotes — asserted disposition-by-dispositionname, missing mandatorypersoninvariantsValidation
cargo fmt --check✓cargo clippy --workspace --all-targets --locked -- -D warnings✓cargo test --workspace --locked✓ (all 9 suites; 11 ward_migrate tests)Beads: threads-uqx.8 (in_progress → evidence on merge). Claim:
threads-uqx-8held.