4.4 KiB
MUSE-AUTH-CLI Decision Record
Status: Draft — taken over in this checkout 2026-10-07 per user choice. Only explicit user acceptance moves this document (or any decision) to Final.
Handoff note: a prior grill session settled D1–D11 and U1 and reportedly marked its own record Final, but that file lives in another checkout (absent here; this repo has no MUSE-AUTH-CLI.md, PI-AGENT-AUTH.md, OPERATORS.md, or agy-auth-switch). D1–D11 details below are CARRIED, not verified — their full text needs a paste or peer handoff before this record can go Final.
Goal
Define the muse-auth CLI: per-profile credential switcher
(~/.config/muse/accounts/<name>/auth.json), tailnet push/pull of profiles
between nodes, and a session spend logger — without stranding live sessions
(the 2026-10-07 fleet-wide 400 outage was a mid-stream credential swap).
Non-goals (proposed)
- Implementation of
muse-auth(needs a separate explicit request). agy-auth-switchvalidation (Track B, separate lane; PI-AGENT-AUTH.md is Final).- OPERATORS.md amendment for agent-invokable keys (U2 follow-on, own delta).
Settled (from prior-session transcript, unverified here)
U1. Allowance reset period — SETTLED (calendar month)
Profile token allowances reset on the 1st of each month UTC, matching standard billing cycles (not a rolling 30-day window).
D10/D11. Agent-invokable key handling — SETTLED in principle, amendment pending
Decisions exist; codification as an OPERATORS.md amendment delta is the U2 follow-on and is UNRESOLVED.
D1–D11 (remaining detail) — CARRIED, text unavailable
Full decision text was settled in the prior session but is not present in this checkout. CARRIED as-is; paste or peer handoff required to verify. This record cannot go Final until they are quoted or re-settled here.
Scope contract (ACCEPTED 2026-10-07; user chose "accept the scope as written")
- Artifact boundary: IN — this decision record only. OUT — runtime code, tests, OPERATORS.md amendment, Track B validation.
- Done means: (1) push/pull file-set decision settled; (2) live-session guard decision settled; (3) D1–D11 text verified or re-settled; (4) user explicitly accepts this record as Final.
- Later stages (implementation, U2 amendment) each return for their own interview; accepting this record never approves them.
- "Go"/"do it all" authorize only the boundary above.
Settled Decisions (New)
P1. Push/pull transfer file set — SETTLED (Credentials + Metadata)
Transfer auth.json (cookies, tokens, session identity) and metadata.json (plan tier, spend watermarks, profile label). Ephemeral caches, runtime logs, and local locks are omitted from transfer. (profile.json in the earlier grill options was shorthand for this file and is superseded; confirmed 2026-10-07.)
P2. Live-session switch guard — SETTLED (Block with Force Override)
Refuse to switch credentials if active muse-bin or worker processes are detected holding the old profile identity. Operators must either terminate active processes first or explicitly pass --force to override, preventing mid-stream 400 outages caused by stale in-memory tokens. (Confirmed in this interview 2026-10-07.)
Pending
None. (All pending architectural decisions P1 and P2 are settled).
Session credential isolation (P3 — BUILT 2026-10-07, user-ordered)
Each muse session runs with an isolated config dir
/tmp/muse-session-<pid>/muse: symlinks to ~/.config/muse/* except
auth.json, which is replaced with the bound profile's credentials;
refreshed tokens sync back to the profile on session exit/save.
Implications (unresolved): this largely obsoletes P2's block (switching stops disturbing live sessions; the guard becomes a backstop for legacy non-isolated sessions). Open risks: token sync-back races when two sessions share a profile (solved: newest-wins by mtime), sessions killed -9 never syncing (solved: reap-by-scan, no exit hook), symlink fragility (accepted: rebuilt per launch).
Implementation: bin/muse_session_bind.py (launch builds the dir and
execs with XDG_CONFIG_HOME; save/reap sync back; status lists).
Key integration choice: exec, not supervise, so panes keep their
muse-bin identity and watcher coverage is untouched. Tests:
tests/test_muse_session_bind.py (13). Follow-ups for the owning lanes:
wire box runtime launch / resume-pool resume through the binder,
and arm a reap timer once the profile store (P1) exists.