fix(verification): keep passed uat results across verifier re-runs #2
Reference in New Issue
Block a user
Delete Branch "fix/uat-verification-stale-loop"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
A phase whose human UAT passed could not reach
passed. Found on summercms.go (Phase 16.2, and earlier Phase 9): the user was sent round/msd-execute-phase N→/msd-verify-work N→/msd-progressrepeatedly, and each pass threw away the UAT they had just completed.Five causes, all confirmed against the source:
allCurrentArtifactsCovered()requires every live PLAN/SUMMARY to be incovered_files; a gap-closure plan always adds ones the earlier report could not list.staleoutrankshuman_needed.verify-workonly recorded a passed UAT against ahuman_neededstatus, so a passed UAT could never be recorded against a stale report.*-UAT.md, so it re-emitted the same human items; thehuman_neededbranch then rewrote the UAT file with every row[pending].Fix
Three new
msd-toolsverbs insrc/uat-evidence.cts, under theverificationfamily:verification.uat-evidenceverification.seed-uathuman_verificationitems into*-UAT.md. Existing rows are kept byte-for-byte; unseen items are appended as[pending]; a pass is reset only when the verifier recorded aretest_reason, which is written into the row.verification.canonicalize-uathuman_needed→passedflip, gated on the uat-only row predicate (#4663). Refuses any other status, so a stale report is never flipped.Also:
verification.statusreportsstale_reason(uncovered_artifacts,covered_changed,fingerprint_malformed,summary_newer) andraw_statuson a stale result.init.progresslists every executed-but-stale phase inreverify_phases.Prompt changes:
msd-verifier— new Step 8b (references/verifier-uat-evidence.md): a human item whose UAT row passed on unchanged code is verified by that row; a row whose tested code changed is re-listed with aretest_reason. Unsure → re-test.execute-phase— thehuman_neededbranch callsverification.seed-uatinstead of hand-writing the UAT file; a gap-closure run records its checkpoint's UAT answers before the verifier is dispatched (steps/gap-closure-uat-record.md).verify-work— a stale report is re-verified in-session, before canonicalization, instead of routing toexecute-phase.progress— Route V.stale re-verifies every stale executed phase as one action.references/stale-reverification.mdis the one shared re-verification procedure for all three workflows.Cross-phase drift decision (cause 4)
Drift detection is kept: a covered file edited by a later phase still makes the earlier report
stale. What changed is the cost. Progress offers all such phases as a single re-verify action and runs the verifiers itself, and the human is only asked to re-test rows the changed files bear on.Safety properties kept
stale(#4155).stale, and the affected UAT row is marked for re-test rather than silently passed.human_neededbranch ofexecute-phasestill never completes the phase directly (issue #38): when every UAT row already passes it hands off toverify-work, which records the pass without re-asking anything.Tests
New
tests/uat-evidence.test.cjs(24 tests), including the five acceptance scenarios:passedwithout re-testingreported:evidence are left byte-identicalThese simulate the verifier by writing the report it would write. The verifier's own judgement of which rows a changed file affects is prompt text and is not exercised by a test.
The second commit updates the text-pinning tests in
verify-work-auto-transition.test.cjsandprogress-forensic.test.cjsand refreshes the compact-content benchmark baseline.Known state of the suite
Full-suite comparison against
nextshows no failures introduced by this branch. Failures that exist onnextindependently of this work include one test inverification-status.test.cjsand three CI lint steps (lint-allow-test-rule-refs,lint-example-parser-parity,lint-docs-guard-registration).Notes for the reviewer
Emitted-Drift-Ack-Growthtrailer on the fix commit.🤖 Generated with Claude Code