aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-11 19:36:39 -0500
committerCraig Jennings <c@cjennings.net>2026-06-11 19:36:39 -0500
commitf4b856b9eacc5a7ce8af3a031d72e7b7d6840305 (patch)
treee4c54701c9285684e20e9bbb24b00f37b9090106
parent743cd85ca6ae4b8b71a69cc0499a8ab99dad409f (diff)
downloadrulesets-f4b856b9eacc5a7ce8af3a031d72e7b7d6840305.tar.gz
rulesets-f4b856b9eacc5a7ce8af3a031d72e7b7d6840305.zip
docs(spec): add helper-instance slice to the agent-runtime spec
The v0 draft covered identity and message targeting for concurrent agents but not spawn mechanics or write-safety for the shared files the session-context split doesn't isolate. I added a section for the motivating case (a second Claude in one project doing lookups and safe task updates): ai --helper spawn with automatic AI_AGENT_ID, a tiered read/write contract where helpers make scoped single-heading org edits and file-wide passes plus all git mutation stay primary-only, light helper startup, and helper wrap-up. Phase 1.5 sequences the slice independently of the runtime-neutral phases 2-6.
-rw-r--r--docs/design/2026-05-28-generic-agent-runtime-spec.org98
-rw-r--r--todo.org17
2 files changed, 115 insertions, 0 deletions
diff --git a/docs/design/2026-05-28-generic-agent-runtime-spec.org b/docs/design/2026-05-28-generic-agent-runtime-spec.org
index 8c16043..5e547e0 100644
--- a/docs/design/2026-05-28-generic-agent-runtime-spec.org
+++ b/docs/design/2026-05-28-generic-agent-runtime-spec.org
@@ -57,6 +57,14 @@ Sources checked:
Draft v0. This is not an implementation plan yet; it is a product/architecture
spec for the next =rulesets= refactor.
+Amended 2026-06-11: the resolver half of Phase 1 shipped
+(=.ai/scripts/session-context-path= + the protocols.org agent-scoped path
+contract); the launcher half has not. A new section, /Concurrent same-project
+agents (helper instances)/, covers Craig's motivating case the v0 draft left
+under-specified — spawning a second Claude in the same project to look things
+up or update tasks safely — and a new Phase 1.5 sequences that slice ahead of
+the runtime-neutral phases 2-6, which remain pending a go/no-go.
+
* Problem
=rulesets= is named and wired as a Claude Code rules distribution:
@@ -355,6 +363,80 @@ the same project are both active.
Receivers should ignore messages targeted at another =TARGET_AGENT_ID= unless
the user explicitly asks them to take over.
+** Concurrent same-project agents (helper instances) — 2026-06-11 amendment
+
+The motivating case (Craig, 2026-06-11): spawn a second Claude in the same
+project to look things up or update tasks safely while the primary session
+works. This is same-runtime concurrency — it needs none of the runtime
+manifests or local-model machinery from phases 2-6. It sits on the shipped
+session-context split plus the contracts below, which the v0 draft didn't
+cover: identity assignment at spawn, and write-safety for the files the
+session-context split does /not/ isolate.
+
+First, the boundary with subagents: when the lookup fits a dispatched
+subagent (the Agent tool), use that — no second session exists and nothing
+here applies. A helper instance is for interactive, long-lived parallel work
+Craig drives himself in a second terminal.
+
+*** Identity and spawn
+
+- The primary keeps the unset-id singleton (=.ai/session-context.org=), per
+ Phase 1's compatibility rule. Zero friction for the overwhelmingly common
+ one-agent case, and the asymmetry is harmless: the helper's writes land in
+ =.ai/session-context.d/=, away from the singleton.
+- The launcher assigns helper identity: =ai --helper [project]= detects a live
+ anchor (the singleton exists, or =session-context.d/= is non-empty), exports
+ =AI_AGENT_ID=helper-<rand4>= (sanitized by =session-context-path=), and names
+ the tmux window =<project>:helper-<rand4>=. Spawning a helper into a project
+ with /no/ live anchor still works — it just means the "primary" duties below
+ have no owner, so the helper warns and runs as a normal full session instead.
+- =--helper= also sets =AI_HELPER=1= so workflows can branch on role without
+ parsing the id.
+
+*** Read/write contract for shared files
+
+The session-context split isolates per-agent session state. Everything else
+in the project is shared mutable state — =todo.org=, =.ai/notes.org=,
+=inbox/=, docs — and two Edit-tool writers on one org file lose updates
+silently (both read, both write, last write wins). The contract, by tier:
+
+- /Always safe:/ any read; writes to the helper's own
+ =session-context.d/<id>.org=.
+- /Safe by discipline (task updates — the case Craig named):/ scoped writes to
+ shared org files under four rules: re-read the file region immediately
+ before each edit; anchor the edit on a unique heading; scope each edit to a
+ single heading's subtree; never reflow, restructure, or sweep the file.
+ Appending a new =**= task at a section end and editing one task's body or
+ state both qualify. The race window collapses to seconds, and a collision
+ corrupts one heading rather than the file.
+- /Primary-only:/ file-wide passes (=todo-cleanup.el=, =lint-org.el=,
+ =wrap-org-table.el=, archive sweeps), inbox processing, template sync, and
+ ALL git mutation — commit, push, pull, stash. Two committers in one
+ worktree contend on the index lock and interleave staging; the helper
+ leaves its tree changes for the primary's next commit, or describes them in
+ a targeted cross-agent message. The helper also never runs startup's
+ Phase A.0 pulls or the =.ai/= rsync — the primary already did, and a
+ concurrent pull-under-edit is exactly the race the startup guards exist to
+ prevent.
+- /Escalation:/ anything the contract blocks routes through the targeted
+ cross-agent form already specced above (=machine.project.agent-id=), or
+ just gets reported to Craig.
+
+*** Helper startup and wrap-up
+
+Helper startup is deliberately light: resolve the context path, read
+=protocols.org=, optionally read the primary anchor's =* Summary= only (never
+its Session Log — the context-contamination rule above), and start working.
+No pulls, no rsync, no inbox processing, no staleness nudges.
+
+Helper wrap-up: archive its own file to
+=.ai/sessions/YYYY-MM-DD-HH-MM-<id>-<desc>.org= (existing rule), skip the
+hygiene passes and the commit/push steps, and surface any uncommitted tree
+changes it left so the primary or Craig picks them up. A helper that dies
+uncleanly leaves its file in =session-context.d/= — the next startup's
+existence check surfaces it as an interrupted agent, same as the singleton
+today.
+
** Hook and validation strategy
V1 should not pretend all runtimes have Claude's hooks.
@@ -410,6 +492,22 @@ Rationale:
- Keep legacy =.ai/session-context.org= fallback.
- Add tests for two simultaneous session-context files.
+** Phase 1.5: Helper instances (concurrent same-project Claude) — added 2026-06-11
+
+Independent of the phases 2-6 go/no-go; same-runtime only.
+
+- =ai --helper= flag: live-anchor detection, =AI_AGENT_ID= + =AI_HELPER=
+ export, tmux window naming, no-live-anchor warning path.
+- The shared-file read/write contract documented where agents will obey it
+ (protocols.org, with startup.org and wrap-it-up.org carrying the helper
+ branches).
+- Bats tests: id assignment and sanitization through the launcher, helper vs
+ primary path resolution, two simultaneous context files (extends the
+ existing =session-context-path= suite).
+- Manual validation: Craig runs a real helper session against a live primary
+ — a task lookup, one scoped =todo.org= edit, wrap-up — and the primary's
+ next commit picks up the helper's edit cleanly.
+
** Phase 2: Introduce runtime manifests and generic install commands
- Add =runtimes/claude.toml= and make current install behavior data-driven.
diff --git a/todo.org b/todo.org
index 1cd298b..bb1c2cb 100644
--- a/todo.org
+++ b/todo.org
@@ -40,6 +40,20 @@ CLOSED: [2026-06-11 Thu]
Cancelled 2026-06-11: Craig confirmed the decision — one todo queue with a single Open Work / Resolved pair. Home reshapes its consolidated file to that form, and the existing single-pair tooling works unmodified. No code change needed.
+** TODO [#B] Helper-instance support — concurrent same-project Claude :feature:
+:PROPERTIES:
+:CREATED: [2026-06-11 Thu]
+:LAST_REVIEWED: 2026-06-11
+:END:
+Implement Phase 1.5 of the generic-agent-runtime spec ([[file:docs/design/2026-05-28-generic-agent-runtime-spec.org][spec]], amended 2026-06-11 with the "Concurrent same-project agents" section). Craig's case: spawn a second Claude in the same project to look things up or update tasks safely while the primary works. The session-context split (AI_AGENT_ID + session-context.d/) already shipped; this builds the rest:
+
+- =ai --helper= flag: live-anchor detection, auto AI_AGENT_ID + AI_HELPER export, tmux window naming, warn-and-run-normal when no primary is live.
+- Shared-file read/write contract into protocols.org (helper: scoped single-heading org edits only; file-wide passes, inbox processing, and all git mutation stay primary-only); helper branches in startup.org (light path, no pulls/rsync) and wrap-it-up.org (archive own file, skip hygiene + commit).
+- Bats: launcher id assignment/sanitization, helper-vs-primary resolution, two simultaneous context files.
+- Manual validation with Craig: live helper against a live primary — lookup, one scoped todo.org edit, wrap-up, primary commits the helper's edit cleanly.
+
+Independent of the spec's phases 2-6 (runtime-neutral refactor), which stay gated on their own go/no-go.
+
** VERIFY Should new personal projects start as areas inside home rather than standalone ~/projects entries?
Home's consolidation (2026-06-11) leaves ~/projects with home and work only. The open template question: when Craig starts a new personal project, does =first-session.org= / =install-ai.sh= guidance now say "create an area in home" by default, with standalone reserved for code projects in ~/code? Affects first-session.org, install-ai.sh docs, and the triggers.md "Launch project X" resolution (folded names like "finances" no longer resolve as projects; an area-aware launch could map them to home).
@@ -1123,6 +1137,9 @@ Before any implementation: needs a real review pass on the spec, and a decision
*** 2026-06-10 Wed @ 14:13:55 -0500 Noted Phase 1 already shipped; narrowed scope to the phases 2-6 decision
Phase 1 (the correctness fix) is live: protocols.org documents the AI_AGENT_ID-scoped session-context path (=.ai/session-context.d/<id>.org=) and =.ai/scripts/session-context-path= resolves it. The singleton race Codex flagged is closed. What remains is the spec review plus a go/no-go on the broader runtime-neutral refactor: runtimes/ adapter manifests, generic install commands, language-bundle split, launcher refactor, local model service.
+*** 2026-06-11 Thu @ 19:26:26 -0500 Spec amended with the helper-instance slice; implementation split out
+Craig's motivating case (a second Claude in the same project for lookups and safe task updates) was under-specified in v0 — it had identity and message targeting but no spawn mechanics and no write-safety contract for the shared files the session-context split doesn't isolate. Added the "Concurrent same-project agents (helper instances)" section (subagent boundary, identity/spawn via =ai --helper=, the tiered read/write contract, light startup, helper wrap-up) and Phase 1.5 to the migration plan. Implementation filed as its own [#B] task ("Helper-instance support"); this task stays scoped to the phases 2-6 go/no-go.
+
* Rulesets Resolved
** DONE [#C] Fix =cj-scan= false positives on cj fences nested inside other =#+begin_*= blocks :bug:
CLOSED: [2026-05-15 Fri]