feat: progress-aware commit-recovery cap (no longer block on 2nd attempt)
The existing commit-recovery path blocked stories on the 2nd consecutive exit-without-commit. For long sweep refactors (e.g. story 997, the typed retries payload migration), claude-code's session-length boundary naturally terminates the coder mid-sweep before it can commit — even though substantial file-edit progress is being made each session. The old cap-of-1 misclassified normal mid-flight progress as 'agent declined to commit'. New behaviour: - Each commit-recovery respawn captures a worktree-diff byte-length fingerprint (git diff master | wc -c). - If the fingerprint differs from the previous attempt the agent made file-edit progress, the no-progress counter resets to 1. - If the fingerprint is byte-identical (no new edits between exits), increment the no-progress counter. - Block only when the counter reaches NO_PROGRESS_CAP (3) — i.e. three consecutive respawns where the agent did literally nothing. Adds ContentKey::CommitRecoveryDiffFingerprint to store the prior fingerprint. Updates the existing block-test to reflect the new cap semantics; existing 'first respawn issued' test continues to pass. All 2935 tests pass.
This commit is contained in:
@@ -24,8 +24,16 @@ pub enum ContentKey<'a> {
|
||||
MergeMasterSpawnCount(&'a str),
|
||||
/// Evidence that `run_tests` passed during an agent session.
|
||||
RunTestsOk(&'a str),
|
||||
/// Flag indicating a commit-recovery respawn is in progress.
|
||||
/// Flag indicating a commit-recovery respawn is in progress. Stored as
|
||||
/// a decimal string counting consecutive respawns that made NO file-edit
|
||||
/// progress (worktree diff byte-identical to the previous attempt). Reset
|
||||
/// to "1" whenever a respawn produces a different diff fingerprint.
|
||||
CommitRecoveryPending(&'a str),
|
||||
/// Worktree diff byte-length captured at the last commit-recovery respawn
|
||||
/// trigger. Used to detect whether the agent made any file-edit progress
|
||||
/// between consecutive session-boundary-clean exits. Same byte length on
|
||||
/// two consecutive attempts → no progress → increment CommitRecoveryPending.
|
||||
CommitRecoveryDiffFingerprint(&'a str),
|
||||
/// Flag indicating a merge gate fixup coder session is in progress.
|
||||
///
|
||||
/// Set when the merge gate fails with a self-evident-fix class of failure
|
||||
@@ -57,6 +65,9 @@ impl<'a> ContentKey<'a> {
|
||||
ContentKey::MergeMasterSpawnCount(id) => format!("{id}:mergemaster_spawn_count"),
|
||||
ContentKey::RunTestsOk(id) => format!("{id}:run_tests_ok"),
|
||||
ContentKey::CommitRecoveryPending(id) => format!("{id}:commit_recovery_pending"),
|
||||
ContentKey::CommitRecoveryDiffFingerprint(id) => {
|
||||
format!("{id}:commit_recovery_diff_fingerprint")
|
||||
}
|
||||
ContentKey::MergeFixupPending(id) => format!("{id}:merge_fixup_pending"),
|
||||
ContentKey::MergeFailureKind(id) => format!("{id}:merge_failure_kind"),
|
||||
ContentKey::MergeSuccess(id) => format!("{id}:merge_success"),
|
||||
|
||||
Reference in New Issue
Block a user