From 84bd121683add4440a3652b12b70e6e2d45f5384 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 30 Jul 2026 07:42:47 -0500 Subject: feat(ai): add --helper for a second session in a live project A helper is a second agent session in a project that already has a live one. It reads freely, makes only scoped single-heading edits, and never touches git. Until now the only way to get one was to tell a session by hand it was a helper, and nothing checked whether that was true. --helper runs agent-roster first, so the claim gets verified rather than asserted. It opens its own tmux window and hands the session helper-mode.org instead of the normal startup workflow. Git prep is skipped because pulls belong to the primary. With no other agent live it warns and falls back to a primary launch. When the roster can't answer, it opens a helper anyway. I picked that direction because a helper that turns out to be alone merely does less, while a primary that turns out not to be alone runs pulls and rsync underneath a live session. Wrap-up gains a Step 0 branch. A helper archives its own context file and stops, and the primary's next commit carries its edits. An orphaned helper whose primary already exited runs the full wrap, because otherwise its edits strand as a dirty tree nobody owns. That branch resolves the project root before consulting the roster. agent-roster defaults to $PWD and only matches agents at or inside it, so a call from a subdirectory would miss a primary at the root and report the helper orphaned. That is the one path that commits and pushes. The agent id is sanitized to the charset session-context-path keeps, because it's interpolated into the command typed into the pane. A helper launching a helper gets a fresh id rather than inheriting its parent's. Two agents resolving to one context file is the collision the contract exists to prevent. Startup still has no roster check, so a bare claude launched into a busy project runs full primary startup regardless. helper-mode.org and protocols.org now say so instead of listing the routing as though it works. --- .ai/protocols.org | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to '.ai/protocols.org') diff --git a/.ai/protocols.org b/.ai/protocols.org index bf9f420..b291d9e 100644 --- a/.ai/protocols.org +++ b/.ai/protocols.org @@ -106,7 +106,7 @@ The epoch is baked into the id by the spawner, never minted inside =session-cont Resolve the path with =.ai/scripts/session-context-path= rather than hardcoding =.ai/session-context.org=; it prints the right path for the current =AI_AGENT_ID=. Fall back to =.ai/session-context.org= if the script isn't present (older checkouts mid-sync). Everything below — the record/recovery purpose, the update triggers, the startup existence check, the wrap-up rename — operates on that resolved path. The prose says "session-context.org" as the default name; read it as "the resolved active path" when =AI_AGENT_ID= is set. -A helper instance (a second agent running in this project while a primary session is live) follows a different contract: it skips the pulls and rsync, makes only scoped single-heading edits to shared files, leaves all git mutation to the primary, and wraps up by archiving its own context file without committing. The full rules — read/write tiers, data-integrity, light startup, helper wrap-up — live in [[file:workflows/helper-mode.org][workflows/helper-mode.org]]. A session is a helper only when something routes it there (the =ai --helper= launcher, startup's roster check, or an explicit "you are a helper" instruction); the routing itself ships behind the helper-instance feature gate and isn't live yet. +A helper instance (a second agent running in this project while a primary session is live) follows a different contract: it skips the pulls and rsync, makes only scoped single-heading edits to shared files, leaves all git mutation to the primary, and wraps up by archiving its own context file without committing. The full rules — read/write tiers, data-integrity, light startup, helper wrap-up — live in [[file:workflows/helper-mode.org][workflows/helper-mode.org]]. A session is a helper only when something routes it there: the =ai --helper= launcher (live — it checks the roster, assigns the id, and opens the helper in its own tmux window) or an explicit "you are a helper" instruction. Startup's roster check is *not* built, so a bare =claude= launched into a project that already has a live session will run full primary startup regardless. Launch helpers with =ai --helper=. This file serves two purposes with one mechanism: 1. *Crash recovery* — if the session dies mid-work, the live file is all that's left. On 2026-01-22 a session crashed during a 20-minute design discussion and all context was lost because this file wasn't being updated. -- cgit v1.2.3