docs(readme): round-2 review fixes (00aa4a4c / 09bf3e77)

- exit 5: a busy or missing target cancels the job; a superseded attempt
  leaves the record to its new owner, unchanged
- install.sh copies a legacy .env to .mam.env and keeps the original
- restore-off fallback: without tomllib the file keeps only that key
  (restore off, other settings lost, warning); restore on only when no
  file can be written
- PoC: no token only when none is passed; tests: every test gets a temp
  registry and log dir, most also the sandbox HOME and mock herdr

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-13 11:32:01 +09:00
1 parent 423abc7844
commit ae2813773c
2 files changed
+10 -10

No files matched your search

+5 -5
View File
@@ -35,7 +35,7 @@ bash deploy/install.sh
- checks that herdr and Python 3.9+ are installed, and that the system `python3` has PyYAML;
- copies `.agents/` and `.mam.env.example` into the workspace;
- creates `.venv` and installs `paho-mqtt` and PyYAML into it;
- writes a starter `.mam.env` with `MQTT_BROKER=localhost`. An existing `.mam.env` is kept, and a legacy `.env` is renamed to `.mam.env`;
- writes a starter `.mam.env` with `MQTT_BROKER=localhost`. An existing `.mam.env` is kept. If only a legacy `.env` exists, it is copied to `.mam.env` and the original stays;
- adds `.venv`, `.mam/` and `.mam.env` to `.gitignore`.
Point `MQTT_BROKER` in `.mam.env` at a broker you run (see [MESSAGING.md](MESSAGING.md) for a private broker). If `MQTT_BROKER` is not set at all, the code falls back to the public `broker.hivemq.com`. That is fine for a trial, but not for real work. `deploy/generate-env.sh` recreates `.mam.env` from `.mam.env.example`. `deploy/update.sh` and `deploy/remove.sh` update and uninstall. `deploy/install_mam.sh` is a separate installer that copies from a local clone into another directory.
@@ -89,7 +89,7 @@ MAM has two layers, each with its own registry:
- **A dedicated server per workspace.** By default `create` runs the agents on a herdr server named after the workspace (its slug), with its own socket, separate from your default herdr. `--herdr-session <name>` or `HERDR_SESSION_NAME` picks another name. The server name is recorded on the session row, and every later command routes to it.
- **The shim.** Sourcing `lib.sh` writes `<workspace>/.mam/shim/herdr` and puts it first on `PATH`. The shim provides the tmux-style commands the scripts use (`new-session`, `has-session`, …) on top of herdr's agent API. For a named server it adds `--session <server>` to each call, and it starts that server headless if it is not running. It does not start one when `MAM_NO_AUTOSTART=1`, which `status` and `monitor` set, so looking never starts a server. Calls for the `default` server go to your ambient herdr unchanged.
- **No surprise relaunches.** A server MAM starts normally uses your herdr config plus `resume_agents_on_restore = false`. A herdr restart therefore does not relaunch saved agents without their permission flags. If that config cannot be built, the bootstrap prints a warning and the server starts with restore on.
- **No surprise relaunches.** A server MAM starts normally uses your herdr config plus `resume_agents_on_restore = false`. A herdr restart therefore does not relaunch saved agents without their permission flags. With a Python that has no `tomllib` (such as macOS's 3.9), the file holds only that key, so restore stays off but your other herdr settings are not carried over; the bootstrap warns about this. Only if no config file can be written at all does the server start with restore on, again with a warning.
- **One pane claim at a time.** Pane placement holds a per-server lock (`lib_py/pane_lock.py`, `flock` on macOS and Linux). Concurrent `create` calls in one folder each get their own pane.
### 🛡️ Registry writes and concurrency
@@ -117,7 +117,7 @@ The full specification is in [MESSAGING.md §2.5](MESSAGING.md).
| `1` | failure, or no `started` within T |
| `2` | no event for K×N (`deadline_timeout`) or budget spent (`wall_clock_timeout`) |
| `3` | broker unavailable, and no terminal status on disk |
| `5` | not delivered (`cancelled`): the session was busy, the target was not found, or the record was taken over while waiting |
| `5` | this attempt did not deliver the prompt: the session was busy or the target was not found (the job is `cancelled`), or another attempt took the record over while this one waited (the record is left to its new owner, unchanged) |
---
@@ -157,7 +157,7 @@ sequenceDiagram
## 🔐 Security
- **Signed events**: a job gets its own token (`auth_token`) when you pass one, or automatically when the broker uses TLS or a username. Each event and each retained state message then carries an HMAC-SHA256 signature made with it, and the subscriber drops anything that fails verification. Events and state messages carry only the signature, not the token. On a broker with neither TLS nor a username (the PoC setup), a job has no token and signatures are not checked.
- **Signed events**: a job gets its own token (`auth_token`) when you pass one, or automatically when the broker uses TLS or a username. Each event and each retained state message then carries an HMAC-SHA256 signature made with it, and the subscriber drops anything that fails verification. Events and state messages carry only the signature, not the token. If no token is passed and the broker has neither TLS nor a username (the PoC setup), a job has no token and signatures are not checked.
- **Remote dispatch carries the token**: the `remote:<name>` dispatch message includes the job's token (signed with `MAM_DISPATCH_SECRET`, not encrypted). Use it only on an access-controlled private broker.
- **Replay and ordering**: each event carries an increasing `seq`. The subscriber accepts only sequence numbers higher than any it has seen and records gaps as `seq_gap`. Timestamps are informational only.
- **Credentials**: broker credentials live only in `.mam.env`, never in a job record.
@@ -172,7 +172,7 @@ sequenceDiagram
- The suite has about 1,900 tests, and a full run takes over an hour.
- It runs its own in-process MQTT broker, so it never needs `.mam.env`. Don't export `.mam.env` for tests.
- Tests run in sandboxes, with a temporary HOME, registry and audit-log directory, and a mock herdr:
- Every test gets a temporary job registry and audit-log directory. Most tests also use the sandbox fixtures, which set a temporary HOME and a mock herdr:
- the tests that drive a real herdr start their own throwaway herdr server;
- after the run, session-level guards check the real control plane and your agent homes (`~/.claude/projects`, `~/.codex`, `~/.gemini`, …) and fail the run if a test left entries there.
- Some tests are platform-specific. A few need Python 3.11+ (`tomllib`), Linux (`/proc`) or the `nats-docker` submodule; elsewhere they are skipped.