aboutsummaryrefslogtreecommitdiff
path: root/.ai/workflows/helper-mode.org
blob: cdec200e08c9572685a46b7bf958bac116d400a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#+TITLE: Helper Mode Workflow
#+AUTHOR: Craig Jennings & Claude
#+DATE: 2026-06-15

* Overview

The role contract for a *helper instance*: a second Claude session running in the same project as a live primary session, spawned to look something up or make a scoped task update while the primary keeps working. This file is the single canonical home of the helper rules. [[file:../protocols.org][protocols.org]] carries a one-paragraph pointer here; the spawn paths and the wrap-up reference this file rather than restating it.

A helper is not a subagent. When the work fits a dispatched subagent (the Agent tool) — a bounded lookup or analysis the primary folds back into its own context — use that instead; no second session exists and none of this applies. A helper is for interactive, long-lived parallel work Craig drives himself in a second terminal.

The governing fact behind every rule below: the session-context split isolates each agent's /session state/ (=.ai/session-context.d/<id>.org=), but everything else in the project — =todo.org=, =.ai/notes.org=, =inbox/=, docs, the git index — is shared mutable state. Two Edit-tool writers on one org file lose updates silently: both read, both write, last write wins. The helper's job is to stay useful without ever being the second writer that clobbers the primary.

* When to Use This Workflow

No operator trigger phrase. A helper reaches this contract one of three ways:

- The =ai --helper= launcher routes here after the roster confirms a live agent (the deterministic path).
- Startup's roster check finds the session is not alone and routes here instead of running normal startup (the safety net for a raw =claude= launch).
- An explicit "you are a helper, follow helper-mode.org" instruction (the manual fallback).

If none of those applies — the roster shows the session is alone — this is a primary session. Run normal [[file:startup.org][startup.org]], not this.

* Identity

A helper is =helper-<rand4>= (four random hex/alphanumeric characters, e.g. =helper-a83f=).

- If the launcher exported =AI_AGENT_ID=, use it. Otherwise self-assign =helper-<rand4>= now.
- Record the chosen id as the *first line* of the session-context file, so it survives across tool calls (shell state does not). The id lives in the file, never in ambient shell state.
- The active session-context path is =.ai/session-context.d/<id>.org=. Resolve it by prefixing the id explicitly wherever a script consumes =AI_AGENT_ID=:

  #+begin_src bash
  AI_AGENT_ID=<id> .ai/scripts/session-context-path
  #+end_src

  The id must be unique per run; =helper-<rand4>= and the launcher's epoch-tailed id both satisfy that (see protocols.org "Agent-scoped path").

* Read/Write Contract

Four tiers, by how much coordination the write needs.

** Always safe

Any read, anywhere in the project. Writes to the helper's own =.ai/session-context.d/<id>.org=.

** Safe by discipline — scoped task updates (the case Craig named)

Scoped writes to shared org files (=todo.org=, =.ai/notes.org=) are allowed under four rules, together:

1. Re-read the file region immediately before each edit.
2. Anchor the edit on a unique heading.
3. Scope each edit to that single heading's subtree.
4. Never reflow, restructure, or sweep the file.

Appending a new =**= task at a section's end and editing one existing task's body or state both qualify. The race window collapses to seconds, and a collision corrupts one heading rather than the whole file. Log the intended edit first (see Write-ahead journal below).

** Primary-only — never as a helper

- File-wide passes: =todo-cleanup.el=, =lint-org.el=, =wrap-org-table.el=, archive sweeps.
- Inbox processing and template sync.
- ALL git mutation: commit, push, pull, stash. Two committers in one worktree contend on the index lock and interleave staging.
- Startup's Phase A.0 pulls and the =.ai/= rsync. The primary already did them, and a concurrent pull-under-edit is exactly the race the startup guards exist to prevent.
- Memory writes. =MEMORY.md= is a shared read-modify-write index with no heading anchors, so it has the lost-update shape of =todo.org= with none of the scoped-edit protection.

The git ban is concurrency-scoped. /Helper wrap-up/ below lifts it for exactly one case: an orphaned helper that finds itself alone.

** Escalation

Anything the contract blocks gets reported to Craig, or — for a cross-project handoff — routed through =inbox-send= to the owning project's =inbox/=. The helper leaves its tree changes for the primary's next commit, or describes them in a note to Craig.

* Data-Integrity Rules

The scoped-edit discipline covers helper-vs-primary edits on /different/ headings. Four loss windows remain. They matter doubly in a consolidated project where one =todo.org= carries every task and corruption has maximal blast radius.

1. *Primary file-wide passes vs a live helper.* A whole-file rewrite run while a helper is mid-edit clobbers the helper's just-written change. Enforced primary-side (the live-helper gate before any hygiene pass), but the helper's part is to keep its own session-context file current so the primary's gate can see it is live.
2. *A new primary starting while a helper runs.* The helper's uncommitted edits make the tree dirty; Phase A.0 already skips pulls on a dirty tree, and startup surfaces live =session-context.d/= files so the new primary knows /why/ the tree is dirty rather than treating it as mess to resolve.
3. *Write-ahead edit journal.* Before applying any shared-file edit, log it — file, heading, one-line intent — to the helper's own session-context file. This tightens the Session Log discipline to log-before-write for shared files specifically, so after a crash the journal shows which edits landed.
4. *The memory dir.* Helpers don't write memory at all. Candidate memories go into the helper's session log; the primary (or its wrap-up promotion check) writes them.

One collision nit: =inbox-send= filenames carry minute-resolution timestamps, so a helper and primary sending to the same target in the same minute with the same slug would collide. Helper-originated sends include the agent id in the slug.

* Light Startup

A helper does not run normal startup. It runs a light version:

1. Self-assign or adopt the identity (above) and create =.ai/session-context.d/<id>.org= with the id on the first line.
2. Read [[file:../protocols.org][protocols.org]] and this file. Read =.ai/notes.org= for project context if useful.
3. Do NOT run Phase A.0 pulls, =make install=, or the =.ai/= rsync — the primary owns those.
4. Do NOT process the inbox — primary-only.
5. Begin the work Craig spawned the helper for.

* Helper Wrap-Up

When the helper's work is done:

1. Re-run the roster (=.ai/scripts/agent-roster=) to learn whether a primary is still live.
2. *Primary still live (the normal case):* finalize the Summary in the helper's own =.ai/session-context.d/<id>.org=, archive it to =.ai/sessions/YYYY-MM-DD-HH-MM-<id>-<description>.org=, and stop. Do NOT commit, push, or run hygiene — the primary's next commit picks up the archived file and any scoped edits the helper left in the tree.
3. *Orphaned helper (roster shows the helper is now alone):* the primary already exited, so the helper assumes full closing duties — the git ban lifts because the concurrency that justified it is gone. Commit and push the tree (including the helper's own edits, which would otherwise strand as a dirty tree), per the normal wrap-up flow in [[file:wrap-it-up.org][wrap-it-up.org]].

* Status

Phase 1.5 of the generic-agent-runtime spec. This contract is the canonical home; the spawn paths (=ai --helper=, startup's roster branch) and the [[file:wrap-it-up.org][wrap-it-up.org]] helper branch route here. Those wiring pieces ship behind the spec's bats-then-drills-then-pilot gate and are not yet live; until then, the manual "you are a helper" instruction is how a session adopts this contract.