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:
+16
-16
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user