Skip to content

feat: handoff lifecycle — list / resume / clear from the phone#21

Merged
JaidenSy merged 2 commits into
mainfrom
feature/handoff-processing
Jul 23, 2026
Merged

feat: handoff lifecycle — list / resume / clear from the phone#21
JaidenSy merged 2 commits into
mainfrom
feature/handoff-processing

Conversation

@JaidenSy

Copy link
Copy Markdown
Owner

The "system to go through handoffs properly" you asked for. A failed step already writes a resume handoff (PR #15) — but acting on one meant opening Jump Desktop. Now it's phone-driven:

command what it does
handoffs list pending handoffs — [project] task — age (id), newest first
resume <n> seed a fresh agent with handoff #n in the right repo, pick up where it stopped, then archive the handoff → handoffs/resolved/
handoffs clear archive all pending at once

resume 2 alphabot overrides the project if routing guesses wrong.

How resume knows the repo

_finalize_step_failure now prepends a machine marker — <!-- hermes-meta project="…" --> — to the handoff. resume parses it → resolve_project → the repo to cd into. No marker (legacy handoffs)? It infers the project from the original task, or you pass one explicitly. Archiving on resume keeps the pending list honest: if the resumed run fails again, a new handoff appears.

Ride-along fix

The handoff mirror used project.capitalize(), which misroutes hyphenated projects (finance-tracker → a Finance-tracker orphan folder nothing reads). Now registry-resolved via raphbrain_dir, matching agent_runner. (Fable flagged the same class of bug in #20 — fixing #20's copy separately.)

Tests

+8 (152 pass / 1 skip): meta parse incl. legacy-no-marker, pending-excludes-resolved + newest-first, resume dispatches-into-repo-then-archives, unresolvable-project → no dispatch + not archived, clear.

Independent of #20

Branched off main, touches different functions than #20 (no stacking). Merge order doesn't matter.

Deploy

Reload after merge. Held for your review — not merged.

🤖 Generated with Claude Code

JaidenSy and others added 2 commits July 22, 2026 17:59
A failed step already writes a resume handoff, but there was no way to act on
one without opening Jump Desktop. Now Jaiden can work them from Telegram:

- `handoffs` — list pending handoffs (project, task, age) newest-first
- `resume <n>` — seed a fresh agent with handoff #n IN THE RIGHT REPO and pick
  up where it stopped; archives the handoff to handoffs/resolved/ so the pending
  list always reflects reality (a fresh failure writes a new one). Accepts a
  project override: `resume 2 alphabot`.
- `handoffs clear` — archive all pending at once.

To route a resume, `_finalize_step_failure` now prepends a machine-readable
`<!-- hermes-meta project=... -->` marker to the handoff; resume parses it (or
falls back to inferring the project from the original task). Legacy handoffs with
no marker still list and can resume with an explicit project.

Also fixes the handoff MIRROR folder: it used project.capitalize(), which
misroutes hyphenated projects (finance-tracker → Finance-tracker orphan) — now
resolved via the registry's raphbrain_dir, matching agent_runner.

Tests: +8 (152 pass / 1 skip) — meta parse incl. legacy, pending-vs-resolved
separation + newest-first, resume dispatches-into-repo-then-archives,
unresolvable-project no-dispatch, clear.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fresh review found two Mediums in the resume command:

- Out-of-range numeric index silently fell through to a substring match and
  resumed the WRONG handoff: stems embed unix timestamps, so `resume 9` with 2
  pending matched "9" inside a timestamp and dispatched + archived the wrong one.
  A numeric selector is now STRICTLY an index — out of range fails cleanly.
- The `resume ` prefix hijacked any natural task starting with the word
  ("resume the deploy refactor") → intercepted as a command, never routed to the
  planner, task silently dropped. The dispatch guard now only fires on bare
  `resume` or `resume <digit…>`; anything else falls through to the planner.

Also: bare `resume` now shows the pending list instead of "matches ''", and
_list_handoffs / _resume_handoff guard per-file reads so one unreadable handoff
can't crash the whole command.

Tests: 154 pass / 1 skip (+2): out-of-range index doesn't substring-match a
timestamp stem; bare resume lists.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@JaidenSy
JaidenSy merged commit 16296f6 into main Jul 23, 2026
2 checks passed
@JaidenSy
JaidenSy deleted the feature/handoff-processing branch July 23, 2026 01:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant