refactor: optimize multi-agent-mux-loop spec and clean up workspace docs

- Add OPTIMIZATION.md detailing Invocation-Aware Scoped Guard, race-free lock design, and DoD verification gates approved via multi-agent loop
- Update root markdown files (README, BOOTSTRAP, MESSAGING) replacing legacy TMUX references with HERDR
- Remove redundant root markdown files and archive promoted reviewer PASS report
This commit is contained in:
2026-08-02 19:20:43 +09:00
parent 002d9b268d
commit 03ba94a030
21 changed files with 234 additions and 1279 deletions
+16 -16
View File
@@ -35,7 +35,7 @@ graph TD
SubClient["job_subscriber.py <br> (Role: subscriber)"]
end
subgraph "Tmux Workspace (Agent Host)"
subgraph "Herdr Workspace (Agent Host)"
PubClient["publish_event.py <br> (Role: publisher)"]
end
@@ -127,7 +127,7 @@ Every event payload must adhere to the following schema structure:
### 2.3 Event Type Dictionary and Schemas
#### 1. `started`
* **Emit Trigger**: Emitted by the worker agent immediately upon boot inside the tmux session, indicating it has parsed the instructions and started execution.
* **Emit Trigger**: Emitted by the worker agent immediately upon boot inside the herdr session, indicating it has parsed the instructions and started execution.
* **Payload Constraints**: `seq` must be `1`. Status in registry is transitioned to `running`.
* **Example Detail**: `"Job 918b0612 started"`
@@ -200,7 +200,7 @@ stateDiagram-v2
* **Timeout Initialization**: Dual timeouts (wall-clock budget and activity idle timer) are calculated and start ticking.
#### Phase 4: Execution & Progress Events (`publish`)
* **Trigger**: The agent executes prompts within tmux and runs `publish_event.py` at boot and checkpoint stages.
* **Trigger**: The agent executes prompts within herdr and runs `publish_event.py` at boot and checkpoint stages.
* **Network Handshake**: Publisher opens a fresh TCP/TLS socket to the broker, awaits CONNACK, publishes a single QoS 1 message, waits for PUBACK, and gracefully disconnects to avoid socket resource leaks.
* **State Updates**: Updates `last_seq` monotonically, updates `status` to `running` (if not already), and mirrors the published payload into the local audit logs (`events.ndjson`).
* **Subscriber Capture**: The subscriber captures the payload, performs bearer token checks, prints the formatted line to stdout, and resets its idle timer.
@@ -218,7 +218,7 @@ stateDiagram-v2
### 4.1 `registry.py` & `lib.sh` (Locking & Atomicity)
Two concurrency control schemes co-exist in this workspace to coordinate state modification:
1. **`lib.sh::atomic_dump_yaml()`**: Used for workspace-wide tmux session inventory (`agent-sessions.yaml`).
1. **`lib.sh::atomic_dump_yaml()`**: Used for workspace-wide herdr session inventory (`agent-sessions.yaml`).
* **Locking**: Uses SQLite database transaction serialization via `BEGIN IMMEDIATE` on `agent-sessions.db`.
* **Safe Mutation**: The mutation source code is passed in an environment variable `AGENT_SESSIONS_MUTATION` and executed dynamically using `exec(compile(..., 'exec'), globals())`. This isolates the execution and avoids command-injection vectors.
* **Atomicity**: Updates the SQLite tables and then, if a session transitions to a finished state, writes to a temp file in the same directory using `tempfile.mkstemp()` and performs an `os.replace()` rename. POSIX guarantees the replacement is atomic, preventing half-written YAML reads. A `.bak` backup copy is also preserved.
@@ -275,9 +275,9 @@ graph LR
User["User/Cron Client"] -->|submit| Wrap["multi-agent-mux-delegate-job (Bash)"]
Wrap -->|registers| Reg["registry.py (Live Registry)"]
Wrap -->|spawns background| Sub["job_subscriber.py"]
Wrap -->|spawns tmux pane| Tmux["tmux Session (Agent Pane)"]
Wrap -->|spawns herdr pane| Herdr["herdr Session (Agent Pane)"]
Tmux -->|executes agent| Agent["Claude / Codex Agent"]
Herdr -->|executes agent| Agent["Claude / Codex Agent"]
Agent -->|publish_event.py| Broker["MQTT Broker"]
Broker -->|delivers events| Sub
Broker -->|delivers events| Mon["reconcile.sh (Monitor Loop)"]
@@ -288,18 +288,18 @@ graph LR
### 5.1 Orchestration Wrappers (`multi-agent-mux-*`)
1. **`multi-agent-mux-delegate-job (submit)`**:
* Registers a job, spawns `job_subscriber.py` to capture standard output streams to `.mam/jobs/<job_id>.subscriber.out`, and sleeps for `1` second.
* Boots the agent pane in tmux:
* Boots the agent pane in herdr:
```bash
tmux new-session -d -s "$sess" -c "$WORKDIR" \
herdr new-session -d -s "$sess" -c "$WORKDIR" \
"printf '%s' \"$instructions\" | $bin --dangerously-skip-permissions; echo; read"
```
* Pre-seeds agent instruction headers via stdin to enforce that the agent runs `publish_event.py` for its transitions.
* Blocks on `wait $sub_pid`, and finally prints the audit log directory.
2. **`multi-agent-mux-monitor` (`reconcile.sh`)**:
* **Wildcard Monitor Integration**: Runs a unified background subscriber loop (`reconcile.sh --subscribe`) to capture progress, verify security tokens (HMAC) and sequences, write audit logs, and automatically clean up tmux sessions upon terminal events.
* **Reconciliation loop**: Subscribes to the global job topic. On terminal events, it invokes `lib.sh::atomic_dump_yaml` to sync status drifts (e.g. setting tmux sessions to `terminated` in `agent-sessions.yaml` once the agent exits).
* **Wildcard Monitor Integration**: Runs a unified background subscriber loop (`reconcile.sh --subscribe`) to capture progress, verify security tokens (HMAC) and sequences, write audit logs, and automatically clean up herdr sessions upon terminal events.
* **Reconciliation loop**: Subscribes to the global job topic. On terminal events, it invokes `lib.sh::atomic_dump_yaml` to sync status drifts (e.g. setting herdr sessions to `terminated` in `agent-sessions.yaml` once the agent exits).
3. **`multi-agent-mux-create / stop / resume`**:
* Integrates the job life status into session metadata updates, ensuring standard tmux cleanup triggers state updates in the registry and audit logs.
* Integrates the job life status into session metadata updates, ensuring standard herdr cleanup triggers state updates in the registry and audit logs.
---
@@ -312,7 +312,7 @@ graph LR
2. **Bearer Token Leakage over Plaintext (Public Broker)**:
The `auth_token` mechanism is a simple plaintext bearer comparison. If the transport layer is unencrypted (e.g., using `broker.hivemq.com` on port `1883`), any eavesdropper on the network can steal the token and spoof legitimate events.
3. **Subscriber Network Drop Orphanage**:
`job_subscriber.py` does not implement automatic reconnection loops. If the subscriber loses connection to the broker, it exits, leaving the running tmux agent orphaned and without a validation/collection hook.
`job_subscriber.py` does not implement automatic reconnection loops. If the subscriber loses connection to the broker, it exits, leaving the running herdr agent orphaned and without a validation/collection hook.
4. **Lack of Ordering Guarantees in QoS 1**:
QoS 1 guarantees delivery but not strict ordering. Under heavy backoff retries, a late-delivered progress event could land after a terminal event, causing state inconsistencies.
@@ -342,10 +342,10 @@ Valid values (see `lib.sh` valid-status set):
| State | Meaning | Set by |
|---|---|---|
| `running` | tmux session active, agent running | `create`, `resume` |
| `running` | herdr session active, agent running | `create`, `resume` |
| `stopped` | deliberately stopped via `--capture-id`/`--reason`/`--graceful`; conversation preserved for resume | `stop` (STOP mode) |
| `terminated` | hard-killed via `--mode hard`; tmux session destroyed | `stop` (hard mode), `monitor` reconcile |
| `archived` | soft-stopped via `--mode soft`; tmux left alive, YAML-only update | `stop` (soft mode) |
| `terminated` | hard-killed via `--mode hard`; herdr session destroyed | `stop` (hard mode), `monitor` reconcile |
| `archived` | soft-stopped via `--mode soft`; herdr left alive, YAML-only update | `stop` (soft mode) |
### Job States (Registry — `.mam/jobs/<id>.json`)
Managed by `.agents/skills/multi-agent-mux-delegate-job/scripts/registry.py`.
@@ -359,6 +359,6 @@ Valid values:
| `error` | terminal event — agent failed | `publish_event.py --event error` |
| `cancelled` | job cancelled by orchestrator | `registry.py cancel` |
**Key distinction**: Session states track the **tmux container lifecycle** (create→stop→resume).
**Key distinction**: Session states track the **herdr container lifecycle** (create→stop→resume).
Job states track the **delegated work lifecycle** (submit→run→complete/error).
A single session can host multiple sequential jobs; a job runs within exactly one session.