feat(verify): C4 import-aware dependency binding#17
Conversation
A pytest:<nodeid> checker proves behavior when it runs, but its sealed watch was only the test file — so an edit to the implementation the test imports could be silently skipped at revalidation when the claim names no uniquely indexed symbol (a re-check TRIGGER gap, not a truth gap). `dorian verify`/`rebind` now statically resolve (stdlib `ast`, read-only — no import execution, sys.path mutation, package introspection, or network) the repo-local .py files a C4 test imports and add them to the claim's watch and auto-captured read-set. A source edit then re-runs the existing C4 checker; the test still decides truth (a file change never marks a claim BROKEN by itself). stdlib imports are skipped via the interpreter module-name table, symlinks are not followed, and ambiguous/zero matches are skipped, not guessed. - new src/dorian/test_deps.py resolver (no runtime dependency) - bindings: split program-named vs checker-exercised files so a widened C4 watch is not flagged trigger-only (and --binding-gate=fail still seals it) - bind-suggest: content-free test-dep provenance - dorian bench c4-import-binding (deterministic; selection recall 0.0 -> 1.0) - docs: spec/checkers, README, SECURITY_BOUNDARY, V1_SCOPE, CHANGELOG [Unreleased] No warrant-schema, checker-grammar, exit-code, fold-policy, or trust change. Trigger widening only; not a sandbox. Rebind old warrants to gain the wider watches. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (12)
📝 WalkthroughWalkthroughAdds C4 import-aware dependency binding to dorian: a new ChangesC4 Import-Aware Dependency Binding
Sequence Diagram(s)sequenceDiagram
rect rgba(70, 130, 180, 0.5)
Note over cmd_verify,seal_artifact: verify / rebind path
end
participant cmd_verify
participant claim_watch_paths
participant c4_dependency_watch_paths
participant merge_watch_maps
participant seal_artifact
cmd_verify->>claim_watch_paths: claims, repo
claim_watch_paths-->>cmd_verify: symbol_watch_map
cmd_verify->>c4_dependency_watch_paths: repo, claims
c4_dependency_watch_paths-->>cmd_verify: c4_watch_map
cmd_verify->>merge_watch_maps: symbol_watch_map, c4_watch_map
merge_watch_maps-->>cmd_verify: merged symbol_watch
cmd_verify->>seal_artifact: extra_watch=merged symbol_watch
rect rgba(180, 100, 50, 0.5)
Note over analyze_candidate,_checker_exercised_files: bindings diagnostic path
end
participant analyze_candidate
participant _checker_exercised_files
participant python_import_dependencies
analyze_candidate->>_checker_exercised_files: repo, claim, entry_uris
_checker_exercised_files->>python_import_dependencies: repo, test_file
python_import_dependencies-->>_checker_exercised_files: import deps
_checker_exercised_files-->>analyze_candidate: exercised file set
Note over analyze_candidate: trigger-only-symbol check uses exercised set
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Summary
Closes the silent C4 revalidation skip: a
pytest:<nodeid>checker proves behavior when it runs, but its sealed watch was only the test file — so an edit to the implementation the test imports could be silently skipped at revalidation when the claim names no uniquely indexed symbol. This is a re-check trigger gap, not a truth gap, and that framing is preserved end to end.dorian verify/dorian rebindnow statically resolve (stdlibast, read-only — no import execution, nosys.pathmutation, no package introspection, no network) the repo-local.pyfiles a C4 test imports, and add them to the claim's watch + auto-captured (hashed, scope-linted) read-set. A source edit then re-runs the existing C4 checker — the test still decides truth; a file change never marks a claimBROKENby itself.What's in it
src/dorian/test_deps.py— the static resolver. Binds only an unambiguous repo-local import (exactly one tracked file); stdlib imports are skipped via the interpreter module-name table; symlinks are not followed; ambiguous / zero matches are skipped, not guessed.bindings.py— splits program-named vs checker-exercised files so a widened C4 watch is not flaggedtrigger-only-symbol(and--binding-gate=failstill seals a good behavior claim).bind-suggest— content-freebind (test-dep)provenance.dorian bench c4-import-binding— deterministic, known-truth: test-file-only watcher selection recall 0.0 → 1.0 for direct-import impl edits, ambiguous selected 0, alarm match 2/2, falseBROKENfrom a behavior-preserving edit 0.spec/checkers.md,README.md,docs/SECURITY_BOUNDARY.md,docs/V1_SCOPE.md,CHANGELOG.md([Unreleased]).Invariants preserved
No
.warrantschema, checker-grammar, public exit-code, fold-policy, or trust change. No new runtime dependency.revalidatestays import-blind (the widened watch is baked into the sidecar at seal/rebind).--deny-execon a selected C4 → ERRORED/exit 5 (never PASS/BROKEN).checker-source=baseunchanged — the widened watch affects selection only, never which spec source executes; it is a trust root, not a sandbox.Verification
uv run pytest→ 919 passed (exit 0)uv run ruff check src tests bench→ cleanuv run ruff format --check src tests bench→ cleanuv run dorian bench c4-import-binding→ deterministic, run_id6fdcffa9b15aaa26Release scope
This lands as a feature at version
1.1.1with CHANGELOG[Unreleased]— no version bump, tag, or publish (READMElatest:/action@refs stay true at v1.1.1, so no dangling public claims). Cuttingv1.2.0is a separate dedicated release commit. Old warrants gain the wider watches viadorian rebind <artifact>.🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation
Tests