feat(proven): transitive-import closure hashing + cycle-safety regression#26
Merged
Merged
Conversation
…sion Closes #12, #13. A promoted file now goes stale when a proof *under* it changes, not only when it is edited -- the spec's full `proven` invalidation form, and the silent-failure class the tool exists to catch. - proven.rs: closure_hash(file, include_root) = SHA-256 over the file's own bytes plus every transitive import resolving in-tree, deterministic order; ProvenRecord.closure_sha256 (optional, backward-compatible -- older manifests still load). - config.rs: [proven] include_root knob + proven_include_root() (resolved relative to the workspace; the source tree is a workspace property, so transition/stale_proven signatures are unchanged). - workspace.rs: record the closure hash on promotion when an include root is configured; stale_proven distinguishes "content changed" from "a transitive import changed since promotion". - graph.rs: regression test pinning that transitive_imports terminates on an A<->B cycle (the reachable visited-set already guarantees this; the test locks it against refactors). Full gate green locally (fmt, build, 50+ tests, clippy -D warnings, SPDX). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019GiSiEfgZCte35dyykgBHs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The two corrective musts from the v0.2 maintenance roadmap.
Closes #12 · Closes #13.
#12 — transitive-import closure hashing (the real fix)
proveninvalidation hashed a file's own bytes only, so a promoted file whose dependency changed upstream stayed green inproven/while logically broken — exactly the silent-failure class arghda exists to catch.Now, when a workspace declares a source tree (
[proven] include_rootin.arghda/config.toml), promotion records a closure hash (the file + every transitive import that resolves in-tree, deterministic order), andstalere-checks it — distinguishingcontent changed since promotionfroma transitive import changed since promotion.Design keeps it backward-compatible and low-blast-radius: the include root is a workspace property, so
transition/stale_provensignatures are unchanged, existing call sites and tests are untouched, and olderhashes.jsonmanifests still load (closure_sha256is optional).#13 — cycle-safety regression test
On inspection,
graph::transitive_importsis already cycle-safe (thereachablevisited-set prevents re-traversal) andbuildis a flat pass — so the survey's "infinite-loop risk" was overstated. Rather than invent a fix for a bug that isn't there, this pins the property with a regression test (A↔B fixture terminates), guarding against a refactor reintroducing a loop — relevant becausewatchruns overworking/, where half-edited files can transiently form a cycle.Changes
src/proven.rs—closure_hash();ProvenRecord.closure_sha256(optional).src/config.rs—[proven] include_rootknob +proven_include_root()(relative paths resolved against the workspace).src/workspace.rs— record closure on promotion; richer stale reason.src/graph.rs— cycle-termination regression test.tests/proven.rs— end-to-end transitive-staleness test.STATE.a2ml— content-hash milestone 75% → 100%.Verification
Full CI gate green locally:
cargo fmt --check,cargo build --all-targets,cargo test(50 unit + integration, incl. the 4 new tests),cargo clippy --all-targets -- -D warnings, SPDX invariant.Context
First two items of the corrective/adaptive/perfective backlog filed as #12–#25. Remaining corrective follow-ups: #14 (parser resilience), #15 (timestamp KATs).
🤖 Generated with Claude Code
https://claude.ai/code/session_019GiSiEfgZCte35dyykgBHs
Generated by Claude Code