Skip to content

ara check --fix: relax value-recovering guard to work on artifacts with pre-existing errors #42

Description

@EYH0602

Problem

ara check --fix (added in #41) applies a fix only when the whole artifact re-parses fully clean. On the messy real corpus — where, per docs/ara-format-feedback.md item 13, "none parse cleanly; about half emit errors" — this means --fix usually applies nothing, even when the fixable drift is itself the cause of the errors.

The guard's Ok-gate is here:

// crates/ara-core/src/fix.rs — guard_ara004
let Ok((mc, _)) = cand else {
    return false;   // any remaining error in the edited artifact → reject the fix
};

The guard_alias path (ARA002/ARA003) is similarly conservative: it requires a clean base parse to compute its targeted one-field diff, so an unrelated pre-existing error (duplicate id, cycle, etc.) discards those fixes too.

Evidence (from an ara check sweep over the 14 vendored fixtures)

Detection is correct (0 panics; 2 artifacts flagged with real ARA004 dash-header drift), but --fix applied 0 fixes to both fixable artifacts:

  • corpus/speedrun/nanogpt-speedrun — all 10 claims C01C10 use em-dash headers (## C01 — …), so none parse, producing 29 evidence references unknown claim errors. The dash headers ARE the cause of those errors. Fixing them would recover the claims and clear the errors — but the fixpoint loop applies one fix at a time, and each single fix still leaves the artifact erroring, so every candidate is rejected and nothing moves.
  • corpus/rebench/rebench-restricted_mlm — the schema_version: "ara-2.0" shape (no tree:/root:); the base parse errors fatally, so all fixes are blocked. (This one is out of scope — a genuinely different format — and is fine to leave blocked.)

Proposed change

Relax the value-recovering guards (ARA004, and ARA002/003) from "must re-parse fully clean" to "must not introduce new errors" — i.e. accept the edit when errors_subset(cand, base) holds (the edited artifact's error set is a subset of the pre-fix error set) plus the existing targeted-recovery + idempotence checks. This keeps the safety guarantees (never adds an error, never corrupts a file, still idempotent) while letting a fix proceed on an already-imperfect artifact.

Note: errors_subset(cand, base) is already computed in guard_ara004 but is currently dead code behind the Ok early-return. The main implementation wrinkle is that parse_sources discards the manifest on any error, so recovery verification must use the tree-isolated claims_only(...) parse the guard already uses for the base claim set — extend that to the candidate side so the post-fix claim set is readable even when the tree still errors.

Acceptance

  • ara check --fix corpus/speedrun/nanogpt-speedrun (on a copy) recovers the C01C10 headers and clears the resulting unknown claim errors.
  • No fix is ever applied that introduces a new error diagnostic.
  • --fix remains idempotent; a discarded fix still leaves the file byte-identical.
  • Add a corpus-style test with a pre-existing unrelated error to lock in the relaxed-but-safe behavior.

Follow-up from #41. See also the "conservative on an already-broken artifact" concern noted during that implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions