-
Notifications
You must be signed in to change notification settings - Fork 1
the scoped-review descendant walk fails closed forever after a squash, and its guarantee is unavailable rather than violated #694
Copy link
Copy link
Open
Labels
area:governanceLifecycle, approval, adoption, or release-policy behaviorLifecycle, approval, adoption, or release-policy behaviorarea:securityIntegrity, authentication, supply-chain, or secret-handling riskIntegrity, authentication, supply-chain, or secret-handling riskimpact:developer-experienceAffects authors, maintainers, or local workflowsAffects authors, maintainers, or local workflowsimpact:maintainerPrimarily affects CI, release, or repository operatorsPrimarily affects CI, release, or repository operatorspriority:p1Highest-impact or release-blocking riskHighest-impact or release-blocking riskresolution:partialRelated work landed but meaningful residual work remainsRelated work landed but meaningful residual work remainsscope:specsync-6Applies to current SpecSync 6 behavior or release contractApplies to current SpecSync 6 behavior or release contract
Description
Activity
Metadata
Metadata
Assignees
Labels
area:governanceLifecycle, approval, adoption, or release-policy behaviorLifecycle, approval, adoption, or release-policy behaviorarea:securityIntegrity, authentication, supply-chain, or secret-handling riskIntegrity, authentication, supply-chain, or secret-handling riskimpact:developer-experienceAffects authors, maintainers, or local workflowsAffects authors, maintainers, or local workflowsimpact:maintainerPrimarily affects CI, release, or repository operatorsPrimarily affects CI, release, or repository operatorspriority:p1Highest-impact or release-blocking riskHighest-impact or release-blocking riskresolution:partialRelated work landed but meaningful residual work remainsRelated work landed but meaningful residual work remainsscope:specsync-6Applies to current SpecSync 6 behavior or release contractApplies to current SpecSync 6 behavior or release contract
The second half of #689. The readiness half is fixed separately; this one needs a decision rather than a patch.
Symptom
After a squash-merge,
shiprefuses:Re-running
change reviewdoes not help on a change that has advanced toaccepted—record_scoped_reviewrequiresChangeState::Verifying(src/change.rs:5850). So a squash-merged change that reachedacceptedhas no forward verb at all. That is the wedge in #690.Why this one cannot be fixed the way readiness was
#689's readiness fix replaced commit ancestry with content agreement, because
verification.commitancestry was freshness wearing a trust costume — never resolved to a tree, never compared to a digest.This check is not that.
review_commit_is_current_checked(src/change.rs:5686-5760) walks every commit betweenreview.implementation_commitandHEADand requires every changed path to sit under:So it proves: between the review and HEAD, nothing changed except this change's own lifecycle records.
Compare what
scoped_review_is_currentalready checks by content —contract_digest,execution_digest, andproject_input_digest == review.workspace_digest. Those cover product and spec files. Butproject_input_is_volatile(src/change.rs:10493) excludes:precisely the region the walk polices. So the walk's unique contribution is detecting that another change's records, or the archive, moved after the review was recorded. Content digests cannot see that, by design.
That is a real guarantee. Deleting the walk would lose it silently.
The actual defect
A squash destroys
review.implementation_commit, so the walk cannot run at all. The guarantee is not violated — it is unavailable. The code treats those identically and fails closed forever.Measured on this repository: 2 of 105 archived reviews are reachable in a fresh clone. The walk is inert for 98% of history already; it simply fails loudly instead of admitting it cannot answer.
Options, none chosen
scoped_review_is_current's other four checks still run. The output must state that the descendant guarantee was unavailable — an unavailable guarantee reported as a satisfied one is worse than the current failure.accept_change_with_gatealready re-anchorsverification.commitwhenallow_verified_tree_adoptionis set. Keeps a walk, but over a window that no longer spans the reviewed work — worth checking whether that window proves anything..specsync/changes/and.specsync/archive/are volatile by design because they churn during the lifecycle; a scoped digest over other changes' records might be tractable and would survive any merge strategy.What I am not doing
Guessing. Three explanations of this repository's change coupling were wrong today, each killed by someone running a command. This one changes what a review proves, so it should be decided deliberately and stated in the spec rather than inferred from whichever patch lands.
Related: #689 (readiness, fixed), #690 (the wedge this produces), #688 (the two-sided archive block).