| Targets |
Every registry row with status: running and realpath(pane.cwd) == realpath(WS). Rows with any other status, worktree rows, and orchestrator_uuids are skipped and listed with their reason. |
| Confirmation |
[y/N] prompt; without a terminal -y/--yes is required (exits 3 otherwise). --dry-run inspects without --yes and changes nothing. |
| Prechecks |
Refuses before any change when an open job exists (prints the registry.py ... close --request cancelled command), when .mam/loop-guard-active or .mam/update-in-progress is held, when a target row lacks a valid agent or role, when a running claude/grok target has no recorded conversation id (the monitor had not pinned one; record it, or stop/purge it by hand first), when .mam/reset-spec.json is invalid, or when the caller itself is one of the targets. |
| Lock & concurrency |
Takes the update admission lock exclusively, acquires .mam/loop-guard-active and publishes .mam/reset-in-progress, then releases the admission lock and runs the prechecks. run_loop.sh, update.sh and another reset refuse on the loop marker. The reset then writes .reset-in-progress into every job registry its open-job check reads (.mam/jobs, MAM_JOBS_DIR, and a row's other control_plane.mam_jobs_dir; created when absent), each under that registry's lock, before the check. It refuses, changing nothing, when a registry shared with another workspace is already fenced by that workspace's live reset; it never replaces or removes another reset's marker. A registration (multi-agent-mux-delegate-job submit, registry.py register, the registry API) into a fenced registry - by any path to that directory - refuses; in another control plane's registry only for this workspace's sessions. The onboarding jobs of the reset's own create_session.sh are let through. |
| Spec file & rerun |
Writes .mam/reset-spec.json atomically before the first stop/purge and removes it only when all targets reach done. Rerunning resumes from the spec file without re-purging already recreated agents (created or done). |
| Sequence per target |
Sequential (never parallel): ⓪ re-checks that its row still has the spec's agent and herdr server and that no job addressed to it is open, ① normal stop_session.sh --reason reset (a post-discovered agent's id is captured onto the row while herdr is live; status: stopped), ② checks that the row's id is the one recorded before the stop and, for a post-discovered agent, that it still verifies as a conversation of the row's folder, ③ stop_session.sh --reason reset --purge-conversation --yes (using the row's recorded ID, never a CLI UUID), then create_session.sh with the original name, agent, role, --herdr-session, and --herdr-workspace (onboarding enabled by default). |
| When skipped (exit 4) |
The target is skipped and the reset continues to the next agent when step ⓪ finds a changed row (row changed) or an open job (job open) - nothing was changed for it -, or when step ② finds no id (no conversation id recorded) or an id other than the recorded one or one that does not verify for the row's folder (id not verified), or step ③ exits 4 (purge refused, in-use gate) - it is stopped but resumable (its row keeps its id) and its conversation files are untouched. Rerun once the cause is gone, or resume it. |