feat(supervision): add choice watcher daemon, HTTPS spec docs, and test suites

- bin/muse_choice_watcher.py + systemd/muse-choices-reconcile.*: automatic choice answering and timer reconciliation
- bin/digest.py: fleet log and health summarization
- docs/BOX-*-HTTPS.md: comprehensive HTTPS execution contracts and API documentation
- docs/MUSE-CHOICES-POLICY.md & docs/SUPERVISION-SPEC.md: autonomous execution specs
- tests/test_*.py: unit test suites for HTTPS API, choice watcher, fleet heal, and swarm pruning
This commit is contained in:
operator
2026-10-07 00:25:46 +00:00
parent 04339bad14
commit 0065d11e97
29 changed files with 6419 additions and 7 deletions
+109
View File
@@ -0,0 +1,109 @@
# Box Md Drive Files over HTTPS (No SSH)
> **Box is the main surface.** All operator work goes through Box (box.muse-dev.online). The web UI, `box` CLI, and agents share the same API endpoints. No UI-only powers.
**Date:** 2026-10-06
**Status:** implemented on bl (`exec-constrained.py` + `box-relay.sh`;
`box-ctl.py` verbs pre-existed, plus traversal hardening, output caps,
`--stdin` content plumbing, and hyphenated amend/append/pull aliases)
**Scope:** md reads (audit/list/read/diff) + governed writes
(amend/append/pull/inject-drive/sync-all). Raw container writes
(`md-write`) stay SSH-only by design.
## 1. Why
Agents shaping fleet behavior could see drive scores but needed SSH to
read an agent's `SOUL.md`, diff it against the canonical template, or
push updated operator files. All of this now rides the agent HTTPS path
(`https://exec.muse-dev.online/exec`, signature or Bearer [REDACTED], named-op
allowlist, audit log).
## 2. New ops
Reads (all `side_effecting: false`, all in `DEFAULT_PERMS`):
| Op | Args | Backend |
|---|---|---|
| `md.audit` | `{accounts?}` (default all) | `box-ctl.py md-audit [accounts...]` |
| `md.list` | `{account!, path?}` | `box-ctl.py md-list` (capped, see §4) |
| `md.read` | `{account!, filename!}` | `box-ctl.py md-read` (capped, see §4) |
| `md.diff` | `{account!, filename!}` (shared template only) | `box-ctl.py md-diff` (capped, see §4) |
Governed writes (all known-identities-only, none in the read-only subset):
| Op | Args | Backend |
|---|---|---|
| `md.pull` | `{account!, filename!}` (shared template only) | `box-ctl.py md-pull` |
| `md.inject_drive` | `{account!}` | `box-ctl.py md-inject-drive` |
| `md.sync_all` | `{}` | `box-ctl.py md-sync-all` |
| `md.amend` | `{filename!, content!, author?, reason?}` | `box-ctl.py md-amend --stdin` (content on stdin) |
| `md.append` | `{filename!, text!, author?, section?}` | `box-ctl.py md-append --stdin` (text on stdin) |
New `box-relay.sh` client commands:
```bash
box md audit [accounts...]
box md list <account> [path]
box md read <account> <filename>
box md diff <account> <filename>
box md pull <account> <filename>
box md inject-drive <account>
box md sync-all
box md amend <filename> (--content <text>|--file <path>) [--author <name>] [--reason <why>]
box md append <filename> (--content <text>|--file <path>) [--author <name>] [--section <header>]
```
Raw op calls (signature auth, no token):
```bash
exec-sign.sh md.audit '{"accounts": ["646", "opm"]}'
exec-sign.sh md.read '{"account": "646", "filename": "SOUL.md"}'
exec-sign.sh md.diff '{"account": "pip", "filename": "HEARTBEAT.md"}'
exec-sign.sh md.append '{"filename": "AGENTS.md", "text": "lesson ...", "author": "646"}'
```
## 3. What the governed writes do
- `md.amend` rewrites a `shared/operators/` template after the
drive-safety checks (HEARTBEAT checklist not gutted,
PROACTIVE_PREFERENCES not blanked, SOUL not reverted to stock),
then git-commits it. Full-file content rides stdin (up to 256KB).
- `md.append` appends a timestamped, attributed note (optional section)
via the same validated + committed path (up to 64KB).
- `md.pull` / `md.inject_drive` / `md.sync_all` push canonical
templates *out* to containers; no agent-supplied content crosses.
Injection always overwrites (AGENTS.md preserves remote `## Lessons`).
## 4. Safety notes (same posture as existing ops)
- **Traversal hardening (single-copy in `agent_md.py`).** Account,
filename, and list-path validation now lives in `agent_md.py`
(`MDValidationError`, raised before any gateway call or write);
`box-ctl.py` maps it to `BAD_NAME`, and exec ops + quality-validate
mirror the same shapes. Previously `md-read 646 ../x` reached the
gateway and `md amend ../../x` could escape `shared/operators/`.
Template flows (diff/amend/append/pull) additionally require one of
the 8 known template names.
- **Fixed argv, validated values.** Unknown arg keys rejected; author /
reason / section are control-char-free with length caps; amend
content must be non-empty.
- **Caps with `truncated` flags.** Reads cap at 64KB, diffs at 64KB,
listings at 200 entries — same convention as git/tests verbs.
- **No raw `md-write` op.** Arbitrary content-to-container stays
SSH-only; remote writes go through the validated template flows.
- **Timeouts.** Audit 300s, sync-all 600s, single-file ops 120s.
- **Audited.** Every execution records identity + op; `box-ctl.py`
additionally audits each verb with its target.
- **Retry-safe reads.** `md-audit` / `md-list` / `md-read` / `md-diff`
joined `IDEMPOTENT_ACTIONS`; all ten md verbs have
`quality-validate` dry-run branches.
## 5. Rollout notes
- Restart `exec-constrained.py` after deploy for the 9 new ops to
appear in `GET /ops` (repo total becomes 79).
- `box-relay.sh` is served from bl (`GET /box`); agents re-fetch to
get the `md` group.
- Non-goals: deletes, `main-loop` enable/disable, policy writes,
swarm kill/prune — future expansions, same pattern. (Approvals
shipped separately; see BOX-APPROVALS-HTTPS.md.)