- 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
3.9 KiB
Box Loop + Strategy Writes over HTTPS (No SSH)
Box is the main surface. All operator work goes through Box (box.muse-dev.online). The web UI,
boxCLI, 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 a vars-name validator fix)
Scope: safe loop/strategy/variable mutations. Reads (loop-status,
loop-health, loop-breaks, strat-get, vars-get, ...) already ride
box.exec or typed read ops and are unchanged here.
1. Why
Agents watching loop health could see breaks but needed SSH to remediate
them, resolve stale followups, tune strategy overrides, or undo variable
changes. All of this now rides the agent HTTPS path
(https://exec.muse-dev.online/exec, signature or bearer auth, named-op
allowlist, audit log).
2. New ops (all known-identities-only, none in the read-only subset)
| Op | Args | Backend |
|---|---|---|
loop.remediate |
{dry_run?} (default false) |
box-ctl.py loop-remediate [--dry-run] |
loop.resolve |
{dm_id, note?} |
box-ctl.py loop-resolve |
strat.set |
{type!, subtype?, agent?, track?, priority?, timeout_s?, nudges?, escalate?} |
box-ctl.py strat-set (payload as argv JSON) |
strat.reset |
{type!, subtype?, agent?} |
box-ctl.py strat-reset |
vars.reset |
{name} |
box-ctl.py vars-reset (restore default) |
vars.rollback |
{name, revision?} (int step or timestamp) |
box-ctl.py vars-rollback |
New box-relay.sh client commands:
box loop remediate [--dry-run]
box loop resolve <dm_id> [note...]
box strat set <type> [--subtype S] [--agent A] [--track true|false] [--priority p] [--timeout N] [--nudges N] [--escalate E]
box strat reset <type> [subtype] [--agent <agent>]
box vars reset <name>
box vars rollback <name> [revision]
Raw op call (signature auth, no token):
exec-sign.sh loop.remediate '{"dry_run": true}'
exec-sign.sh strat.set '{"type": "job", "priority": "important", "nudges": 3}'
3. What remediate does (non-dry)
loop.remediate delegates to gravity.remediate_breaks: resolves
followups already answered in logs, re-arms expired followups with nudges
remaining (runs the followup sweeper once), auto-allows TRUSTED (non-key)
browser approvals, and on hard breaks appends a hard_break_alert to
job-log plus one DM to opm. Use {"dry_run": true} first to preview the
remediated / escalated lists with zero side effects.
4. Safety notes (same posture as existing ops)
- Fixed argv, validated values. Strategy types are a strict enum
(
wake|job|siphon|manual|health|heartbeat) — the backend silently maps typos to MANUAL, so the op rejects them instead. Priorities are a strict enum; timeouts/nudges must be integers (backend clamps); dm ids must be 6–64 hex; variable names mirror the engine identifier rule. All checks run before any side effect. - Stdin-free. Unlike
job.put,strat.setpasses its JSON payload as an argv token (strat-set <type> [JSON]), so no new stdin plumbing was needed. - Vars-name validator fix.
quality-validatefor all five vars verbs used the job-name regex (^[a-z0-9-]{1,64}$), rejecting every real variable name (max_nudge_count, ...). They now shareqv_var_name(^[A-Za-z0-9_.-]{1,64}$), mirroring theexec-constrained.pyrule. - Audited. Every execution records identity + op + args hash;
box-ctl.pyadditionally audits each mutation with its target.
5. Rollout notes
- Restart
exec-constrained.pyafter deploy for the new ops to appear inGET /ops. box-relay.shis served from bl (GET /box); agents re-fetch to get theloop/stratgroups andvars reset|rollback.- Non-goals: approvals, deletes,
main-loopenable/disable — future expansions, same pattern. (md drive files shipped separately; see BOX-MD-HTTPS.md.)