Harden safe deletion fingerprints #58

Merged
pdurlej merged 2 commits from codex/deletion-fingerprint-safety into main 2026-05-18 23:08:31 +02:00
Collaborator

Canary Context Pack

Product story

Agents should never delete code from stale evidence. safe_to_remove previously returned unknown fingerprints as ordinary manual_only classifications, which made "not found in current analysis" indistinguishable from "current low-confidence finding".

What changed

  • safe_to_remove now returns a structured result:
    • classifications: one classification per requested fingerprint
    • unrecognized: requested fingerprints not present in the current analysis
  • Each Classification includes recognized: bool, defaulting to true for current findings and false for unknown fingerprints.
  • Unknown fingerprints remain non-auto (manual_only in the current pre-ADR-0009 namespace) with a rationale that forbids deletion.
  • Cycle fingerprints canonicalize rotated cycle_path evidence so the same cycle does not produce a new fingerprint just because traversal starts from another module.
  • Added focused fingerprint tests covering rotated cycle paths and repeated cycle/dead-code analysis stability.
  • Updated MCP/docs/release notes for the new safe_to_remove response shape.

Why it changed

This is Domain C from the 2026-05-18 fork pack: make the dangerous path boring. Deletion candidates must be based on current, recognized evidence, not stale fingerprints from an older report.

Files touched

  • mcp/src/fallow_py_mcp/safety.py
  • mcp/src/fallow_py_mcp/schemas.py
  • mcp/src/fallow_py_mcp/server.py
  • src/fallow_py/fingerprints.py
  • mcp/tests/test_mcp.py
  • tests/test_fingerprints.py
  • README.md
  • mcp/README.md
  • docs/agent-integration.md
  • docs/schema.md
  • docs/release-notes/0.3.0a3.md

Relevant context

  • Closes #10
  • Closes #11
  • References #15, but does not close it; this PR adds fingerprint-focused tests, not the full graph/dead_code coverage suite requested there.
  • ADR 0008: evidence-gated dogfood
  • ADR 0009 is not implemented here; this PR intentionally keeps the current bucket namespace.

Runtime evidence

  • Red before fix: PYTHONPATH=src:mcp/src python3.13 -m pytest -q mcp/tests/test_mcp.py::test_safe_to_remove_classifies_unknown_fingerprints_deterministically
  • Red before fix: python3.13 -m pytest -q tests/test_fingerprints.py
  • python3.13 -m compileall -q src tests mcp/src mcp/tests scripts/dogfood
  • PYTHONPATH=src:mcp/src python3.13 -m pytest -q
  • PYTHONPATH=src python3.13 -m fallow_py analyze --root . --fail-on warning --min-confidence medium
  • PYTHONPATH=src:mcp/src python3.13 -m fallow_py analyze --root mcp --fail-on warning --min-confidence medium
  • git diff --check

Known constraints

This branch was developed in a separate git worktree at /Users/pd/Developer/fallow-python-domain-c because other domain forks were active in the primary worktree. Local tests were run with explicit PYTHONPATH=src:mcp/src so they exercised this branch rather than an editable install pointing at the primary worktree.

Explicit out-of-scope

  • No ADR 0009 bucket rename.
  • No broader deletion automation.
  • No new analyzer findings.
  • No full #15 graph/dead_code coverage suite.

Requested decision

Approve if safe_to_remove now makes stale fingerprints explicit and cycle fingerprints are stable across rotated cycle paths.

Merge blockers

  • Unknown fingerprints can still be mistaken for current findings.
  • safe_to_remove loses requested fingerprints.
  • Cycle-path fingerprint stability is not tested or not deterministic.
## Canary Context Pack ### Product story Agents should never delete code from stale evidence. `safe_to_remove` previously returned unknown fingerprints as ordinary `manual_only` classifications, which made "not found in current analysis" indistinguishable from "current low-confidence finding". ### What changed - `safe_to_remove` now returns a structured result: - `classifications`: one classification per requested fingerprint - `unrecognized`: requested fingerprints not present in the current analysis - Each `Classification` includes `recognized: bool`, defaulting to `true` for current findings and `false` for unknown fingerprints. - Unknown fingerprints remain non-auto (`manual_only` in the current pre-ADR-0009 namespace) with a rationale that forbids deletion. - Cycle fingerprints canonicalize rotated `cycle_path` evidence so the same cycle does not produce a new fingerprint just because traversal starts from another module. - Added focused fingerprint tests covering rotated cycle paths and repeated cycle/dead-code analysis stability. - Updated MCP/docs/release notes for the new `safe_to_remove` response shape. ### Why it changed This is Domain C from the 2026-05-18 fork pack: make the dangerous path boring. Deletion candidates must be based on current, recognized evidence, not stale fingerprints from an older report. ### Files touched - `mcp/src/fallow_py_mcp/safety.py` - `mcp/src/fallow_py_mcp/schemas.py` - `mcp/src/fallow_py_mcp/server.py` - `src/fallow_py/fingerprints.py` - `mcp/tests/test_mcp.py` - `tests/test_fingerprints.py` - `README.md` - `mcp/README.md` - `docs/agent-integration.md` - `docs/schema.md` - `docs/release-notes/0.3.0a3.md` ### Relevant context - Closes #10 - Closes #11 - References #15, but does not close it; this PR adds fingerprint-focused tests, not the full graph/dead_code coverage suite requested there. - ADR 0008: evidence-gated dogfood - ADR 0009 is not implemented here; this PR intentionally keeps the current bucket namespace. ### Runtime evidence - Red before fix: `PYTHONPATH=src:mcp/src python3.13 -m pytest -q mcp/tests/test_mcp.py::test_safe_to_remove_classifies_unknown_fingerprints_deterministically` - Red before fix: `python3.13 -m pytest -q tests/test_fingerprints.py` - `python3.13 -m compileall -q src tests mcp/src mcp/tests scripts/dogfood` - `PYTHONPATH=src:mcp/src python3.13 -m pytest -q` - `PYTHONPATH=src python3.13 -m fallow_py analyze --root . --fail-on warning --min-confidence medium` - `PYTHONPATH=src:mcp/src python3.13 -m fallow_py analyze --root mcp --fail-on warning --min-confidence medium` - `git diff --check` ### Known constraints This branch was developed in a separate git worktree at `/Users/pd/Developer/fallow-python-domain-c` because other domain forks were active in the primary worktree. Local tests were run with explicit `PYTHONPATH=src:mcp/src` so they exercised this branch rather than an editable install pointing at the primary worktree. ### Explicit out-of-scope - No ADR 0009 bucket rename. - No broader deletion automation. - No new analyzer findings. - No full #15 graph/dead_code coverage suite. ### Requested decision Approve if `safe_to_remove` now makes stale fingerprints explicit and cycle fingerprints are stable across rotated cycle paths. ### Merge blockers - Unknown fingerprints can still be mistaken for current findings. - `safe_to_remove` loses requested fingerprints. - Cycle-path fingerprint stability is not tested or not deterministic.
Harden safe deletion fingerprints
All checks were successful
CI / Python 3.11 (push) Successful in 1m0s
CI / Python 3.12 (push) Successful in 1m5s
CI / Python 3.13 (push) Successful in 1m3s
CI / Python 3.11 (pull_request) Successful in 59s
CI / Python 3.12 (pull_request) Successful in 1m4s
CI / Python 3.13 (pull_request) Successful in 1m4s
87f2482782
safe_to_remove now returns a structured result with per-fingerprint classifications plus an explicit unrecognized list so stale evidence is visible to agents. Cycle fingerprints canonicalize rotated cycle paths, and focused tests cover unknown fingerprints plus repeated cycle/dead-code analysis stability.

Verified:

- Red before fix: PYTHONPATH=src:mcp/src python3.13 -m pytest -q mcp/tests/test_mcp.py::test_safe_to_remove_classifies_unknown_fingerprints_deterministically

- Red before fix: python3.13 -m pytest -q tests/test_fingerprints.py

- python3.13 -m compileall -q src tests mcp/src mcp/tests scripts/dogfood

- PYTHONPATH=src:mcp/src python3.13 -m pytest -q

- PYTHONPATH=src python3.13 -m fallow_py analyze --root . --fail-on warning --min-confidence medium

- PYTHONPATH=src:mcp/src python3.13 -m fallow_py analyze --root mcp --fail-on warning --min-confidence medium

- git diff --check
pdurlej approved these changes 2026-05-18 22:42:41 +02:00
Dismissed
Merge main into deletion fingerprint safety
All checks were successful
CI / Python 3.11 (push) Successful in 59s
CI / Python 3.12 (push) Successful in 1m2s
CI / Python 3.13 (push) Successful in 1m1s
CI / Python 3.11 (pull_request) Successful in 58s
CI / Python 3.12 (pull_request) Successful in 1m3s
CI / Python 3.13 (pull_request) Successful in 1m1s
0c954da568
Resolve the Domain C branch after ADR 0009 decision-contract landed on main. Keep the SafeToRemoveResult/unrecognized/recognized shape from #58 while adopting decision_needed and mandatory trade_offs from #61.

Verified:

- PYTHONPATH=src:mcp/src python3.13 -m pytest -q mcp/tests/test_mcp.py::test_safe_to_remove_classifies_unknown_fingerprints_deterministically mcp/tests/test_mcp.py::test_safe_to_remove_separates_unrecognized_from_recognized mcp/tests/test_classification_namespace.py tests/test_fingerprints.py

- python3.13 -m compileall -q src tests mcp/src mcp/tests scripts/dogfood

- PYTHONPATH=src:mcp/src python3.13 -m pytest -q

- PYTHONPATH=src python3.13 -m fallow_py analyze --root . --fail-on warning --min-confidence medium

- PYTHONPATH=src:mcp/src python3.13 -m fallow_py analyze --root mcp --fail-on warning --min-confidence medium

- git diff --check
codex dismissed pdurlej's review 2026-05-18 22:45:54 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

pdurlej scheduled this pull request to auto merge when all checks succeed 2026-05-18 23:08:19 +02:00
pdurlej approved these changes 2026-05-18 23:08:30 +02:00
Sign in to join this conversation.
No description provided.