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:
@@ -0,0 +1,80 @@
|
||||
# Box Dev + Comms 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-ctl.py` + `box-relay.sh`)
|
||||
**Scope:** git visibility, test runs, notify, work-order acks. Read-only lookups
|
||||
live in `docs/BOX-API-READ-HTTPS.md`.
|
||||
|
||||
## 1. Why
|
||||
|
||||
Agents developing the box must inspect the tree, run the suite, nudge peers,
|
||||
and acknowledge work orders without SSH. All of this now rides the existing
|
||||
agent HTTPS path (`https://exec.muse-dev.online/exec`, signature or bearer
|
||||
auth, named-op allowlist, audit log) — no new trust model.
|
||||
|
||||
## 2. New ops
|
||||
|
||||
| Op | Args | Backend | Write? | Who |
|
||||
|---|---|---|---|---|
|
||||
| `git.status` | `{}` | `box-ctl.py git-status` | no | any valid signer |
|
||||
| `git.diff` | `{path?, stat?}` | `box-ctl.py git-diff [--stat] [--path p]` | no | any valid signer |
|
||||
| `git.log` | `{limit?, path?}` (1..50, default 10) | `box-ctl.py git-log` | no | any valid signer |
|
||||
| `tests.run` | `{test?, filter?}` (`tests.<module>` or full suite; `filter` is unittest `-k`) | `box-ctl.py tests-run [module] [--filter p]` | yes (executes) | known identities only |
|
||||
| `notify.send` | `{agent, message≤1000, sidechat?, sender?}` | `box-ctl.py notify ...` | yes (sends DM) | known identities only |
|
||||
| `dm.ack` | `{id, to, sender!, sidechat?, allow_main_chat?}` | `box-ctl.py ack ...` | yes (sends DM) | known identities only |
|
||||
|
||||
New `box-ctl.py` verbs: `git-status`, `git-diff`, `git-log`, `tests-run`,
|
||||
`ack` (all in `USAGE`, `quality-validate`, and — for the git reads —
|
||||
`IDEMPOTENT_ACTIONS`).
|
||||
|
||||
New `box-relay.sh` client commands:
|
||||
|
||||
```bash
|
||||
box git status
|
||||
box git diff [--stat] [--path <path>] # path also accepted positionally
|
||||
box git log [<limit=10>] [--path <path>]
|
||||
box tests run [tests.<module>] [--filter <pattern>] # full suite (~2-3 min) when omitted; filter is -k
|
||||
box notify <agent> [--sidechat <n>] [--sender <a>] <message...>
|
||||
box dm ack <id> --to <agent> --sender <agent> [--sidechat <name>]
|
||||
```
|
||||
|
||||
Raw op call (signature auth, no token):
|
||||
|
||||
```bash
|
||||
exec-sign.sh git.log '{"limit": 5, "path": "bin/dm.py"}'
|
||||
exec-sign.sh tests.run '{"test": "tests.test_box_dev_https"}'
|
||||
exec-sign.sh dm.ack '{"id": "bdf7beb6", "to": "pip", "sender": "opm"}'
|
||||
```
|
||||
|
||||
## 3. Safety notes (same posture as existing ops)
|
||||
|
||||
- **Fixed argv, validated values.** Clients influence only whitelisted argument
|
||||
values. Git paths must be repo-relative without `..` (plus symlink-escape
|
||||
check in box-ctl); test modules must match `^tests\.[a-z0-9_]+$` and exist;
|
||||
ack ids must be 6–64 hex; notify messages ≤1000 chars.
|
||||
- **Caps.** `git diff` output capped at 64KB, status at 200 entries, test
|
||||
output at 32KB tail; every capped response carries `truncated: true`.
|
||||
- **Sidechat-first.** `notify.send` and `dm.ack` default to the recipient's
|
||||
sidechat and never touch Main Chat unless `allow_main_chat` is set —
|
||||
mirroring `box-ctl.py notify` and the WO dispatcher.
|
||||
- **Attribution.** `sender` is caller-asserted (validated ∈ fleet agents),
|
||||
same as the existing `dm.send` op; the HTTPS identity is recorded
|
||||
separately in the exec audit log. `dm.ack` requires an explicit sender —
|
||||
no silent default.
|
||||
- **tests.run executes repo code** (whatever is in `tests/`), so it is
|
||||
`side_effecting`, excluded from the read-only default permission subset,
|
||||
and capped at a 600s timeout. Test failures report as
|
||||
`{"ok": false, "returncode", "output"}` — the op itself succeeded.
|
||||
- New `box-ctl.py` fail codes `GIT_ERROR` / `TESTS_ERROR` are registered in
|
||||
`KNOWN_ERROR_CODES`, so `quality-check` stays at its baseline.
|
||||
|
||||
## 4. Rollout notes
|
||||
|
||||
- Restart `exec-constrained.py` after deploy for the new ops to appear in
|
||||
`GET /ops`.
|
||||
- `box-relay.sh` is served from bl (`GET /box`); agents re-fetch to get
|
||||
`git` / `tests` / `notify` / `dm ack`.
|
||||
- Non-goals: git commit/push, service restarts for box itself, live
|
||||
streaming tails — future expansions, same pattern.
|
||||
Reference in New Issue
Block a user