fix(health): fsck survives approved delete proposals#538
Conversation
the decided-proposals check builds its presence map from the four create kinds only, so `presence[pr.kind]` raised a KeyError the moment a kb held an approved delete proposal — `vouch fsck` tracebacked permanently on any kb that ever approved a delete. delete proposals landed after fsck and never taught it the new kind. an approved delete promises the inverse of the create kinds: the target artifact should be gone. fsck now checks exactly that, reporting a still-present target as `decided_delete_artifact_present` (the mirror of `decided_missing_artifact`) instead of crashing.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughChangesApproved delete proposal consistency
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/vouch/health.py`:
- Around line 439-440: Update the added docstring prose in the approved delete
proposal path to begin with lowercase text, changing “Approved delete
proposals...” to “approved delete proposals...”; preserve the rest of the
wording and behavior unchanged.
- Around line 462-475: Update the DELETE handling in the proposal health-check
flow to validate `target_kind` before querying `presence_by_target_kind`. Emit a
consistency `Finding` when the value is missing or unsupported, and only perform
the artifact membership check for valid target kinds; do not let invalid deletes
pass as clean.
In `@tests/test_health.py`:
- Around line 307-313: The test helper _decide_proposal must use the real
proposal lifecycle instead of manually relocating YAML: create the proposal
through the normal propose flow and call proposals.approve() to produce the
decided state. Update the drift regression to recreate the target artifact after
approval, while preserving the review gate and avoiding direct filesystem
promotion of an APPROVED proposal.
- Around line 330-333: Update the clean-case test around the health.fsck call to
assert report.ok is True in addition to checking the finding codes, ensuring
unrelated findings cannot make the regression test pass.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 72784f2b-4fa2-490f-9260-bbe92c703100
📒 Files selected for processing (3)
CHANGELOG.mdsrc/vouch/health.pytests/test_health.py
address the review round: lowercase the added docstring prose, report a missing or unknown delete target_kind as decided_delete_invalid_target_kind instead of treating it as clean, and rework the regression tests to run the real propose/approve lifecycle rather than hand-landing decided yaml. running the real flow exposed a second gap the manual tests hid: after a gate-approved delete, the target's original create proposal tripped decided_missing_artifact — a kb that created and then deleted an artifact through the gate would report drift forever. approved deletes now explain the absence: create proposals whose artifact was removed by a matching approved delete are exempt from the missing-artifact finding.
|
all four findings addressed in the new commit:
worth flagging: switching to the real flow surfaced a second gap the manual tests had hidden. after a gate-approved delete, the target's original create proposal tripped validation rerun: |
what changed
health._check_decided_proposalsbuilds its presence map from the four create kinds (CLAIM/PAGE/ENTITY/RELATION) and then indexes it withpresence[pr.kind]for every approved proposal.ProposalKind.DELETEisn't in the map, so the first approved delete proposal makesvouch fscktraceback withKeyError: <ProposalKind.DELETE: 'delete'>— permanently, since the decided entry never goes away:repro on a clean kb: propose an entity → approve →
propose_deleteit → approve →vouch fsck.the fix teaches the check what an approved delete actually promises — the inverse of the create kinds. for
DELETEproposals the target artifact should be gone, so a target still on disk (a crash between the artifact removal and the decided-move) is now reported as a newdecided_delete_artifact_presenterror finding, the mirror of the existingdecided_missing_artifact. targets that are gone pass clean.why
fsck landed before delete proposals did, and the delete feature updated proposals, storage, index, and all three surfaces but never taught fsck the new kind (
git log -S "ProposalKind.DELETE" -- src/vouch/health.pyis empty). the presence check's docstring — "every approved proposal should have its artifact on disk" — is exactly backwards for a delete, so the fix encodes the inverse rather than just skipping the kind.what would break for an existing
.vouch/nothing — no on-disk shape, object model, or method surface changes. read-only check; the only behavior change is
vouch fsckcompleting (and reporting honest findings) on kbs where it previously crashed.test plan
two regression tests in
tests/test_health.py, both failing on the previous code with the exactKeyErrorabove:test_fsck_approved_delete_with_artifact_gone_is_clean— the healthy case: approved delete, target absent, fsck completes with nodecided_*findingtest_fsck_flags_approved_delete_artifact_still_present— the drift case: target survived on disk, fsck reportsdecided_delete_artifact_presentandok is Falsevalidation run locally:
Summary by CodeRabbit
vouch fsckwhen a knowledge base contains approved delete proposals.fsckreports it as clean.fsckflagsdecided_delete_artifact_present.fsckflagsdecided_delete_invalid_target_kind.fsckinconsistencies.