89 lines
4.4 KiB
Markdown
89 lines
4.4 KiB
Markdown
|
|
# 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-switch` validation (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.
|