Address clawsweeper P2 on PR #79067: the prior cross-tool recovery
extracted the path target by splitting the joined fingerprint string
on `|`, which is also a legal character in file paths. A failed edit on
`/tmp/a|left` and a successful write to `/tmp/a|right` would both
extract as `path=/tmp/a` and incorrectly clear the prior failure.
Carry a structured `fileTarget: { path?, oldpath? }` alongside the
existing `actionFingerprint` string and compare it directly.
`extractFileTarget` reads args once at fingerprint-build time, with
the same alias support as `buildToolActionFingerprint`. The
fingerprint string is unchanged for diagnostics and the exact-equality
match path; only the cross-tool fallback now compares structurally.
Threaded through `ToolMutationState`, `ToolActionRef`, `ToolCallSummary`,
and `ToolErrorSummary` so the existing handler code at
`pi-embedded-subscribe.handlers.tools.ts:910-928` can populate and
consume it without re-parsing.
Adds delimiter-bearing-path regression test asserting that
`/tmp/a|left` vs `/tmp/a|right` returns false, and that an identical
delimiter-bearing path on both sides still matches.
Drop apply_patch from the file-mutating recovery set after clawsweeper
P2 review on PR #79067 noted production apply_patch calls only carry
opaque `input` patch text, so buildToolActionFingerprint never extracts
a `path=` segment from real call args. Including apply_patch only
matched handcrafted fingerprints in tests, not real recoveries, and
the public CHANGELOG claim was unimplemented.
Also drops the now-orphaned `oldpath` segment from
FILE_TARGET_FINGERPRINT_KEYS since edit and write do not produce it,
and replaces the apply_patch test expectation with an explicit
negative assertion that proves the narrowing.
Re-files apply_patch ↔ write recovery as a future enhancement; it
needs single-file patch-target extraction in
buildToolActionFingerprint to be honestly supportable.
Recognize a successful file-mutation on the same path/oldpath target as
recovery for an earlier failed file-mutation, even when the tool name
differs (edit -> write, apply_patch -> write, etc). Previously
isSameToolMutationAction required exact fingerprint equality, which
includes tool=<name>, so an edit failure followed by a successful
write to the same path was never recognized as recovery. The unresolved
lastToolError then drove the cron classifier to flag a healthy
self-healed run as fatal with the user-visible warning prefix from
issue #79024. Limited to file-mutating tools (edit, write, apply_patch)
and the stable path/oldpath segments of the action fingerprint;
non-file-mutating tools and different paths still fail closed.
Fixes#79024.