Skip to content

feat(proven): transitive-import closure hashing + cycle-safety regression#26

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/modest-hawking-3fd6it
Jun 20, 2026
Merged

feat(proven): transitive-import closure hashing + cycle-safety regression#26
hyperpolymath merged 1 commit into
mainfrom
claude/modest-hawking-3fd6it

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

The two corrective musts from the v0.2 maintenance roadmap.

Closes #12 · Closes #13.

#12 — transitive-import closure hashing (the real fix)

proven invalidation hashed a file's own bytes only, so a promoted file whose dependency changed upstream stayed green in proven/ while logically broken — exactly the silent-failure class arghda exists to catch.

Now, when a workspace declares a source tree ([proven] include_root in .arghda/config.toml), promotion records a closure hash (the file + every transitive import that resolves in-tree, deterministic order), and stale re-checks it — distinguishing content changed since promotion from a transitive import changed since promotion.

Design keeps it backward-compatible and low-blast-radius: the include root is a workspace property, so transition/stale_proven signatures are unchanged, existing call sites and tests are untouched, and older hashes.json manifests still load (closure_sha256 is optional).

#13 — cycle-safety regression test

On inspection, graph::transitive_imports is already cycle-safe (the reachable visited-set prevents re-traversal) and build is 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 because watch runs over working/, where half-edited files can transiently form a cycle.

Changes

  • src/proven.rsclosure_hash(); ProvenRecord.closure_sha256 (optional).
  • src/config.rs[proven] include_root knob + 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

…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
@hyperpolymath hyperpolymath marked this pull request as ready for review June 20, 2026 23:15
@hyperpolymath hyperpolymath merged commit 0962e46 into main Jun 20, 2026
1 check passed
@hyperpolymath hyperpolymath deleted the claude/modest-hawking-3fd6it branch June 20, 2026 23:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants