From 8c9a68cf1cdb5b77856fe8a0a531c599b7ebb527 Mon Sep 17 00:00:00 2001 From: Godopu Date: Wed, 21 Oct 2026 15:58:54 +0000 Subject: [PATCH] docs(stop,resume,create): the lines that became wrong (Issue #63) --- .agents/skills/multi-agent-mux-create/SKILL.md | 2 +- .agents/skills/multi-agent-mux-resume/SKILL.md | 18 +++++++++--------- .agents/skills/multi-agent-mux-stop/SKILL.md | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.agents/skills/multi-agent-mux-create/SKILL.md b/.agents/skills/multi-agent-mux-create/SKILL.md index 9841f27..5a8c659 100644 --- a/.agents/skills/multi-agent-mux-create/SKILL.md +++ b/.agents/skills/multi-agent-mux-create/SKILL.md @@ -183,7 +183,7 @@ bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh --workspace | Exit | Meaning | |---|---| | 0 | Created; or `--dry-run` | -| 1 | Pre-flight failure, nothing was spawned: workspace not a directory, herdr not installed, agent CLI not in `PATH`, agent not authenticated. After spawn: the task brief could not be written or the instruction injection failed (the session is rolled back) | +| 1 | Pre-flight failure, nothing was spawned: workspace not a directory, herdr not installed, agent CLI not in `PATH`, agent not authenticated, or a same-cwd session of the same Class A agent did not record its conversation ID within `MAM_ID_ORDER_WAIT_S` (default 600). After spawn: the task brief could not be written or the instruction injection failed (the session is rolled back) | | 2 | Bad arguments; control-plane binding refused for a worktree; whitespace in a control-plane path that must be forwarded | | 3 | A herdr session of that name already exists (`multi-agent-mux-resume`, or `multi-agent-mux-stop` first) | | 4 | The YAML already has a `running` row of that name. The YAML write raises it after spawn, and the herdr session is rolled back. A row the monitor registered for this very pane while it was being created is replaced instead | diff --git a/.agents/skills/multi-agent-mux-resume/SKILL.md b/.agents/skills/multi-agent-mux-resume/SKILL.md index 44d9e3a..637d157 100644 --- a/.agents/skills/multi-agent-mux-resume/SKILL.md +++ b/.agents/skills/multi-agent-mux-resume/SKILL.md @@ -36,10 +36,10 @@ its row is `status: stopped` with `resumable: true` and the conversation id already recorded in `claude_session_id_own` / `agy_conversation_id_own`. This is the ideal resume path: -- **tier-1, race-free**: because the stop command wrote the id into the row at stop - time, `resolve_session_id.sh` resolves it via `find_workspace_uuid` tier-1 (the - per-row own id) — no reliance on the mtime-based disk scan, so a concurrent - session in another workspace can never shadow it. +- **tier-1, race-free**: when the row has its own id recorded, `session_ids.py` + resolves it directly from the per-row own id (after checking no other row + claims it and revalidating on disk) — no reliance on the mtime-based disk scan, + so a concurrent session in the same or another workspace can never shadow it. - On resume, `update_yaml_resumed.sh` transitions `stopped → running` and **clears the stop metadata** (`stopped_at`, `stopped_at_epoch`, `stop_reason`, `resumable`) along with the usual `terminated_at*` / `termination_mode` / `archived_at`, so the @@ -49,10 +49,10 @@ ideal resume path: `agent-sessions.yaml` and on-disk discovery are used to resolve the UUID in this order: -1. **`herdr_sessions[]` row's per-row own id** (`claude_session_id_own` / `agy_conversation_id_own` / `hermes_conversation_id_own` / `grok_session_id_own` / `opencode_session_id_own` / `codex_session_id_own`) — explicitly saved by `multi-agent-mux-stop` right before teardown (tier-1, race-free). -2. **Workspace-scoped on-disk scan** (adapter `discover()`) +1. **`herdr_sessions[]` row's per-row own id** (`claude_session_id_own` / `agy_conversation_id_own` / `hermes_conversation_id_own` / `grok_session_id_own` / `opencode_session_id_own` / `codex_session_id_own`) — verified against disk and refused (exit 1) if another row also records it (tier-1, race-free). +2. **Without an own id**: Class A (`agy`, `hermes`, `opencode`, `codex`) uses `#40` pane capture (`autopin.capture`) when herdr is alive, starts a fresh conversation (`FRESH_SPAWN=1` + `NOTE:` on stderr) when herdr is dead and 2+ same-type rows share the cwd, or scans the workspace when it is the only row; Class B (`claude`, `grok`) runs the workspace scan (`find_workspace_uuid`, skipping ids claimed by other rows). -If both are empty → for Class A agents (`agy`, `hermes`, `opencode`, `codex`), `resume_session.sh` automatically falls back to `FRESH_SPAWN=1` (`spawn-spec`). For Class B agents (`claude`, `grok`), fall back to `multi-agent-mux-create`. +If the resolved id is empty → for Class A agents (`agy`, `hermes`, `opencode`, `codex`), `resume_session.sh` uses `FRESH_SPAWN=1` (`spawn-spec`). For Class B agents (`claude`, `grok`), fall back to `multi-agent-mux-create`. ## Workflow @@ -75,11 +75,11 @@ bash .agents/skills/multi-agent-mux-resume/scripts/resume_session.sh --workspace | Exit | Meaning | |---|---| | 0 | Resumed; or already running, so only the row was updated (no attach); or `--dry-run` | -| 1 | From the checks before spawn, nothing was changed: no saved session for claude/grok (use `multi-agent-mux-create` first), agent binary missing or not executable. **The YAML update after spawn (`update_yaml_resumed.sh`) also exits 1** (YAML not found) | +| 1 | From the checks before spawn, nothing was changed: no saved session for claude/grok (use `multi-agent-mux-create` first), the row's id is also claimed by another row, a same-cwd Class A session did not record its id within `MAM_ID_ORDER_WAIT_S` (default 600), or agent binary missing/not executable. **The YAML update after spawn (`update_yaml_resumed.sh`) also exits 1** (YAML not found) | | 2 | From the checks before spawn, nothing was changed: bad arguments, `--workspace` differs from the original cwd or it no longer exists, control-plane binding refused, whitespace in the control-plane path. **The YAML update after spawn also exits 2** (bad arguments) | | other | A later step failed (herdr spawn, start-up dialogs, YAML update) and its code is passed through. resume does not roll back | -A non-zero exit after the spawn can leave the herdr session running while the row is still `stopped`. Before retrying or creating a new session, check with `multi-agent-mux-status`. The `ERROR:` line on stderr tells the two apart: the pre-spawn checks' messages are in `resume_session.sh` (lines 50-223). +A non-zero exit after the spawn can leave the herdr session running while the row is still `stopped`. Before retrying or creating a new session, check with `multi-agent-mux-status`. The `ERROR:` line on stderr tells the two apart: the pre-spawn checks' messages are in `resume_session.sh` (lines 50-243). ## Original cwd only (Issue #21 phase 2) diff --git a/.agents/skills/multi-agent-mux-stop/SKILL.md b/.agents/skills/multi-agent-mux-stop/SKILL.md index c408342..baa1397 100644 --- a/.agents/skills/multi-agent-mux-stop/SKILL.md +++ b/.agents/skills/multi-agent-mux-stop/SKILL.md @@ -31,7 +31,7 @@ The stop command is always **graceful by default**: 1. Sends exit keys to the agent TUI (`/exit` for Claude, `/exit` for Agy) and waits 3 seconds. 2. If still alive, issues `herdr kill-session` (SIGTERM) and waits 5 seconds. 3. If still alive, kills the pane PID via SIGKILL (`kill -9`) as a last resort. -4. Auto-captures the conversation ID into the row (`claude_session_id_own`/`agy_conversation_id_own`) before killing, ensuring the next resume uses a race-free tier-1 lookup. +4. Auto-captures the conversation ID into the row (`claude_session_id_own`/`agy_conversation_id_own`) before killing (for Class A agents, only an ID verified as this pane's via `#40` capture is recorded, and nothing is recorded if the herdr session was already dead), ensuring the next resume uses a race-free tier-1 lookup. ## Pre-flight @@ -93,7 +93,7 @@ The script: 2. If `delegate_job_id` is set, automatically publishes a `progress --detail "terminating"` event to the multi-agent-mux-delegate-job registry 3. Captures the `last_visible_status` from `herdr capture-pane` (so we have a final TUI snapshot for audit) 4. Attempts graceful exit keys → SIGTERM kill-session → SIGKILL fallback -5. For `purge-conversation`: deletes, for claude, every path the session owns — `projects//.jsonl` and `/`, `file-history//`, `session-env//`, `jobs//` (when its `state.json` names the session), stale `sessions/.json` (+ that pid's `.key`) and `/claude-/*//`, then prints anything still carrying the UUID as `WARN residual:`; shared files such as `history.jsonl` are not rewritten (Issue #31). Or, for agy, `~/.gemini/antigravity-cli/conversations/.db` with its `-wal`/`-shm`/`-journal` sidecars, `brain//`, `annotations/.pbtxt` and `presence/.lock` (the lock only once no live process references the conversation — Issue #10) +5. For `purge-conversation` (purging only the row's own ID or an ID verified for this pane, and never an ID another row records — Issue #63): deletes, for claude, every path the session owns — `projects//.jsonl` and `/`, `file-history//`, `session-env//`, `jobs//` (when its `state.json` names the session), stale `sessions/.json` (+ that pid's `.key`) and `/claude-/*//`, then prints anything still carrying the UUID as `WARN residual:`; shared files such as `history.jsonl` are not rewritten (Issue #31). Or, for agy, `~/.gemini/antigravity-cli/conversations/.db` with its `-wal`/`-shm`/`-journal` sidecars, `brain//`, `annotations/.pbtxt` and `presence/.lock` (the lock only once no live process references the conversation — Issue #10) 6. Updates the YAML entry and SQLite database atomically 7. If `delegate_job_id` is set, publishes a `completed` event to the multi-agent-mux-delegate-job registry