Skip to content

Cheaper token handoff: supply git state, finish in one Write + one Bash #179

Closed

Description

@lbacik

This was generated by AI during triage.

Split out of #159 (part 2). Decisions are recorded in ADR 0004 (docs/adr/0004-handoff-reserve-in-turns-and-seal-based-token-handoff.md) and in the glossary terms Soft threshold, Handoff reserve and Sealing in CONTEXT.md.

Agent Brief

Category: enhancement
Summary: After the token soft threshold, give the model all the state it needs and have it finish the handoff in one Write plus one Bash.

Current behavior:
When the token soft threshold is crossed, the model gets a generic instruction to invoke the handoff skill (_cost_handoff_instruction), and possibly one follow-up prompt (_cost_handoff_followup_prompt). The skill then tells it to commit outstanding work, write the note, and commit the note separately. In the #155 attempt the model spent its remaining turns on separate git status, git log and git branch calls. It hit the hard ceiling before it wrote anything. Every turn re-counts the whole main context, so each orientation command costs as much as a real step.

The note validator requires the note's last_work_commit to be the commit directly beneath the note commit, or the base revision when nothing lies beneath it. A seal commit on top of the note is already accepted.

Desired behavior:

  • When the token soft-threshold handoff context is injected, and in its one follow-up prompt, the runtime includes a state snapshot taken at injection time:
    • the current branch, the base revision, and the current HEAD SHA
    • the output of git status --short, git log --oneline <base>..HEAD and git diff --stat <base>, each capped at about 40 lines with a +N more line
    • the attempt's started_at
    • a pre-filled note header: the # Handoff note: issue #<n> title plus the issue, started_at, reason: token_soft_threshold and last_work_commit: <HEAD SHA> lines
  • The instruction tells the model to do the following and nothing else:
    1. Do not run diagnostic commands; the state above is current.
    2. Do not commit work yourself. Sealing will commit any uncommitted work after the attempt.
    3. Write .agent/handoff/<n>.md using the pre-filled header verbatim, and fill in Summary, Remaining work and Evidence.
    4. In one Bash call, run git add .agent/handoff/<n>.md && git commit -m "Handoff note: issue #<n>".
    5. Stop.
  • skills/handoff/SKILL.md gets a token soft-threshold section that matches the instruction. It says the state is supplied, that the handoff takes at most two tool calls, and that work is not committed in this case. Today's flow, which commits work first, stays the documented path for operator handoff now requests and for turn/time-limit follow-ups.
  • The soft-threshold tool guard is unchanged. Read-only git commands stay allowed: a denied call costs a full turn too, so blocking them saves nothing.
  • Resulting branch layout: the work commits from before the threshold, then the note commit, then (if there was uncommitted work) the seal commit. That layout must still pass the note validator and be published as a valid handoff outcome.

Key interfaces:

  • _cost_handoff_instruction(...) and _cost_handoff_followup_prompt(...) gain the state snapshot (their signatures will need the workspace/base information).
  • The handoff skill text (skills/handoff/SKILL.md).
  • _validate_handoff_note: no behaviour change expected; tests should prove that the note + seal layout passes.

Acceptance criteria:

  • The token soft-threshold handoff context and its follow-up prompt contain the branch, base revision, HEAD SHA, status, log, diff stat, started_at, and a pre-filled header whose last_work_commit equals HEAD at injection time (unit tests).
  • Each git output in the snapshot is capped at ~40 lines with a +N more line (unit test with a large dirty tree).
  • An attempt where the model writes the note with the supplied header and commits only the note, leaving dirty work, ends with the note + seal layout. It passes note validation and is reported as a handoff outcome (test).
  • SKILL.md describes the two-call token soft-threshold path and keeps the existing flow for operator and turn/time-limit handoffs.
  • Operator handoff and turn/time-limit follow-up prompts are unchanged (existing tests still pass).

Out of scope:

  • How the soft threshold is computed (separate sub-issue: handoff reserve).
  • The runtime's emergency handoff note (separate sub-issue).
  • Changing the soft-threshold tool guard's allowlist.
  • Relaxing the note validator.

Activity

  1. added
    enhancementNew feature or request
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 8, 2026
  2. self-assigned this
    on Oct 8, 2026
  3. lbacik commented on Oct 8, 2026

    @lbacik
    OwnerAuthor

    Agent Attempt Result: no_changes

    Branch: no branch created
    PR: none

    Evidence

    • Check command: /home/agent/target-venv/bin/python -m pytest → exit code None
    • Review cycles: 0/2
    • Review findings: all clear

    Details

    Operator handoff req-5427e55cdf31 reached its 240-second model deadline without the model invoking the handoff skill.

  4. removed
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 8, 2026
  5. removed their assignment
    on Oct 8, 2026
  6. added
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 11, 2026
  7. self-assigned this
    on Oct 11, 2026
  8. lbacik commented on Oct 11, 2026

    @lbacik
    OwnerAuthor

    Agent Attempt Result: incomplete

    Branch: agent/issue-179
    PR: none

    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 None
    • Review cycles: 0/2
    • Review findings: all clear

    Details

    Handoff note is missing a valid started_at field.

  9. removed
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 11, 2026
  10. removed their assignment
    on Oct 11, 2026
  11. added
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 11, 2026
  12. self-assigned this
    on Oct 11, 2026
  13. added a commit that references this issue on Oct 11, 2026
  14. lbacik commented on Oct 11, 2026

    @lbacik
    OwnerAuthor

    Agent Attempt Result: complete

    Branch: agent/issue-179
    PR: #208

    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.

  15. removed
    ready-for-agentFully specified implementation issue ready for an unattended agent
    on Oct 11, 2026
  16. removed their assignment
    on Oct 11, 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

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions