Skip to content

Valid handoff note still rejected when the work commit beneath it also deletes a handoff note #216

Closed

Description

@lbacik

Problem

The #213 fix skips too much. When the work commit beneath the note also touches the handoff note path, for example because it deletes an earlier round's note, a valid handoff note is still rejected:

handoff_note_rejected: Handoff note's `last_work_commit` does not match the last preserved work commit.

The attempt is then downgraded from handoff to incomplete, so no continuation is scheduled.

_this_attempt_note_commit_revisions collects every commit of this attempt from git log base..branch -- <note path>. That includes a work commit that only deletes the note alongside real changes. _validate_handoff_note then skips the whole unbroken run of those revisions beneath the newest note commit, "whatever other files they also carry" (comment in lifecycle.py). So it also skips the work commit and expects the commit below it.

#213 proposed skipping only commits that touch only the note path. The merged fix (#214) loosened that to any note-touching commit of this attempt.

Observed on

globaldb issue #146 (lbacik/globaldb#146), attempt 2026-10-13T10:19:46.131121Z, agent 0.4.4 (image built from v0.4.4), model muse-spark-1.3-contributor behind LiteLLM.

Branch agent/issue-146 after the attempt (newest first, author time UTC):

bc397e4 10:33 Handoff note: issue #146      <- note_commit (newest note-touching commit)
4097c8f 10:32 Handoff note: issue #146      <- earlier note commit, same attempt (the #213 case, handled)
41de6c3 10:32 Extract pinToCurrentRevision helper, drop handoff notes from the change
                                            <- the note says last_work_commit: 41de6c3…
50d4525 10:28 Fix soft-delete delete tests for identity-map staleness
                                            <- expected_last_work_commit computed by the validator

41de6c3 --stat:

 .agent/handoff/146.md                   | 71 ---------------------------------
 .agent/handoff/issue-146-spec-review.md | 18 ---------
 src/Service/EntityCoreService.php       | 25 +++++++-----

The model removed the previous round's note from the diff as a "process artifact" after a code-review pass, in the same commit as a code change. All three commits are authored after the attempt start, so handoff_note_commits returns bc397e4, 4097c8f, 41de6c3, and the cursor walks past all three.

Timeline from agent_output.json:

UTC event
10:32:43 token_soft_threshold_crossed (budget 5 627 902 / soft 5 600 000)
10:32:43 token_soft_threshold_handoff_context_injected
10:32:56 token_soft_threshold_handoff_note_committed revision=4097c8f
10:33:02 token_soft_threshold_handoff_followup. The model rewrites the note (wording only, same header) and commits bc397e4
10:33:18 model_execution_finished: status=model_limit_reached
10:33:18 handoff_note_rejected, then completion_decided: outcome=incomplete

According to the note, the implementation is committed and the full gate is green (433 tests, all quality tools exit 0). Only the validator stood between this attempt and a proper handoff.

The pattern recurs: on 2026-10-08 an earlier round of the same issue also removed the note in its own commit (3c8d1be Remove agent handoff note (process artifact, not part of the change)).

Expected

last_work_commit names the newest attempt commit beneath the note that carries work. Here that is 41de6c3, so the note should be accepted.

Proposed fix

When walking beneath note_commit, skip a commit only if it is a pure note commit: its diff touches only handoff_note_relpath(issue_number), and the note file still exists after it (a modification or addition, not a deletion). Stop at the first commit that changes anything else, or that deletes the note, and expect that commit (or base_revision if the walk runs out). Either restrict _this_attempt_note_commit_revisions to such commits, or apply the check in the loop in _validate_handoff_note. handoff_note_commit (locating the newest note) can stay as it is.

Regression test next to the #213 one in tests/test_handoff_end_to_end.py: a work commit that changes a source file and deletes an existing note, then two note-only commits with last_work_commit set to the work commit. Assert outcome=handoff. The #213 test (two note-only commits over a plain work commit) and the stale-commit test should keep their current results.

Related

Activity

  1. added
    bugSomething isn't working
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 13, 2026
  2. self-assigned this
    on Oct 13, 2026
  3. lbacik commented on Oct 13, 2026

    @lbacik
    OwnerAuthor

    Agent Attempt Result: complete

    Branch: agent/issue-216
    PR: #217

    Evidence

    • Check command: UV_PROJECT_ENVIRONMENT=/home/agent/venv-py311 uv run --python 3.11 --extra dev ruff check && UV_PROJECT_ENVIRONMENT=/home/agent/venv-py311 uv run --python 3.11 --extra dev pytest && UV_PROJECT_ENVIRONMENT=/home/agent/venv-py313 uv run --python 3.13 --extra dev pytest → exit code 0
    • Reviews performed: 1
    • Review repair cycles: 0/2
    • Review findings: not collected

    Details

    Claude SDK completed the implementation workflow.

  4. removed
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 13, 2026
  5. removed their assignment
    on Oct 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions