Skip to content

Remediation proof packet: emit fix-proof.json for every fix attempt #43

Description

@PhysShell

Classification

  • Change type: enhancement / remediation evidence contract
  • Priority:P1
  • Expected value: very high — turns Fix Arm output into one reviewable, machine-checkable proof artifact
  • Estimated effort: medium
  • Implementation risk: medium — false claims of fixed would corrupt audit truth
  • Recommendation:YES, strong product improvement after finding identity v2 is stable
  • Depends on:PhysShell/Own.NET#266
  • Consumes derived lifecycle/evidence state from:PhysShell/Own.NET#268
  • Consumes agent evidence from:PhysShell/007#42 and replay verification from PhysShell/007#43 when available

Problem

The Fix Arm already has the correct safety shape:

select -> dry-run -> apply -> re-audit -> reject regression -> tier gate

It also records a useful coverage ledger and reverts rejected/no-effect patches. However, the evidence that a remediation succeeded is spread across several artifacts:

  • original finding(s);
  • proposed diff;
  • re-audit output;
  • introduced/removed finding comparison;
  • build/test logs;
  • runtime evidence where available;
  • optional agent run records;
  • human review disposition.

A reviewer currently has to reconstruct the argument manually. Humans can do that, naturally, because apparently archaeology is now part of code review.

Goal

Emit one versioned, deterministic fix-proof.json for every attempted fix, including accepted, rejected, no-effect, unfixable and operational-error outcomes.

The proof packet must answer:

Which exact occurrence was targeted?
What evidence justified the target?
What patch was attempted?
Did the target disappear under comparable analysis inputs?
Did a semantic successor remain?
Were new findings introduced?
Which build/tests/runtime checks ran?
Was the agent execution replay-verified?
What remains unknown?

Proposed contract

Exact names are reviewable; the information must remain explicit.

{
"schema": 1,
"proof_id": "...",
"status": "ACCEPTED | REVIEW | REJECTED | NO_EFFECT | UNFIXABLE | ERROR",
"target": {
"pattern_id": "...",
"occurrence_id": "...",
"lineage_id": "...",
"rule": "OWN001",
"before_evidence_digest": "..."
},
"patch": {
"digest": "...",
"changed_files": [],
"changed_symbols": [],
"diff_artifact": "..."
},
"verification": {
"target_removed": true,
"semantic_successor_present": false,
"introduced_occurrences": [],
"build": {},
"tests": [],
"runtime_witness": null,
"reaudit_comparability": {}
},
"agent_run": {
"run_id": null,
"action_id": null,
"replay_report_digest": null
},
"provenance": {
"target_commit": "...",
"own_version": "...",
"ownaudit_version": "...",
"config_digest": "...",
"input_digest": "..."
},
"limitations": []
}

Required semantics

  1. target_removed is matched by occurrence/lineage identity, not (rule, basename, nearest line) once #266 is available.
  2. Disappearance under a changed analyzer/config/input is not presented as a verified fix.
  3. A target disappearing while a semantic successor remains is not accepted as fixed.
  4. Any introduced actionable occurrence remains explicit and rejects automatic acceptance.
  5. Missing build/test/runtime checks remain unknown/not-run; they are never treated as pass.
  6. An agent process exiting zero is not remediation proof.
  7. Human review is an explicit disposition layered over machine evidence, not a rewritten machine verdict.
  8. Rejected/no-effect attempts still produce proof packets so failed strategies do not vanish from evaluation data.

Integration with the current Fix Arm

run_fix() should return or construct a proof model in addition to the existing FixResult/ledger output.

Suggested output layout:

artifacts/fix-runs/<proof-id>/
fix-proof.json
diff.patch
before-findings.json
after-findings.json
verification/
build.json
tests.json
runtime.json
logs/

The packet should reference large artifacts by relative path + digest rather than embedding unbounded logs.

Required controls

  1. Target removed, no new findings, comparable config, tests pass → accepted/review according to tier.
  2. Target removed but a new finding appears → rejected.
  3. Target line moves but lineage remains → no false remove/add pair.
  4. One repeated occurrence is fixed and another remains → only the targeted occurrence changes state.
  5. Re-audit uses a different config digest → inconclusive/rejected, not fixed.
  6. Target remains → NO_EFFECT with reverted patch.
  7. Applier throws after modifying the tree → rollback evidence and ERROR proof retained.
  8. Agent claims success but re-audit disagrees → machine verdict wins; claim remains provenance only.
  9. Runtime witness is unavailable → explicit limitation, never synthetic pass.
  10. Re-rendering the same normalized inputs produces byte-stable proof JSON.

Acceptance

  • Versioned fix-proof.json schema is documented and implemented.
  • Every fix attempt emits a proof packet, including rejected/no-effect/error paths.
  • Identity uses #266 contracts when available and has an explicit legacy fallback.
  • Tool/config/input comparability is checked and recorded.
  • Large logs/artifacts are digest-addressed rather than embedded.
  • Existing Fix Arm safety behavior and rollback semantics remain unchanged.
  • The dashboard/report can link to the proof packet without re-deriving remediation truth.
  • 007 action/replay evidence is optional but verifiable when attached.

Non-goals

  • No new fix engine.
  • No AI judge deciding whether a patch is correct.
  • No automatic acceptance of T4 fixes.
  • No replacement of the Finding Evidence Ledger.
  • No requirement that every finding has a runtime witness.
  • No storage of secrets or unbounded agent stdout in the proof JSON.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions