Files
mcode-sl/docs/DECISIONS.md
T
aygea fd8e8cbbd7 docs: AGENTS.md + evidence-backed scaffold (state, trials, decisions, handoff)
- AGENTS.md operating rules incl. Gitea SSH port-2222 note + known_hosts incident
- CURRENT_STATE / TODO / CHANGELOG / TRIALS
- trials: endpoint-key pairing; config-merge safety matrix 14/14 (verify.sh + output)
- docs: DECISIONS (mcode 0.6.12 bundle facts, digest-pinned), FEATURE-MATRIX, PROJECT-HANDOFF
- handoffs: TEMPLATE + 2026-10-19 initial-install record
2026-10-19 23:25:21 -07:00

5.0 KiB
Raw Blame History

DECISIONS

Stable IDs; newest at the bottom. Each records context, choice, alternatives, consequences.

D1 — Vault-first credentials, api.zai direct; credential.json fallback

  • Context: the Aygea Claude statusline used ~/.secretvault/credential.json (url + clientKey → vault.itsaygea.com proxy). The user wants this repo public and machines to need nothing but their existing SecretVault (zai_api_key).
  • Choice: read zai_api_key via secretvault run (name from env, default zai_api_key), hit https://api.z.ai/api/monitor/usage/quota/limit; fall back to credential.json → ${url}/proxy/zai/.... Key reaches curl via a 0600 header file (--header @file), never argv.
  • Alternatives: bake the proxy URL + require credential.json everywhere (rejected: repo would document private infra as a requirement); store JSON {url,key} in the vault (rejected: existing secret is a plain key).
  • Consequences: one secret per machine is the only setup; trial mcode-endpoint-key-pairing-2026-10-19 pins the pairing. Proxy users still work.

D2 — mcode statusline mechanics (verified facts, release-pinned)

Confirmed by reading the 0.6.12 bundle — re-verify after every mcode update. Files (SHA-256): chunks/launcher-AVQRYDKB.js 2c4337e3…edfbe3, chunks/chunk-X3PES5WL.js 600c23d…09ee5 under ~/.minimax-code/releases/0.6.12/lib/node_modules/@minimax-ai/code/.

  • Config source: <dataDir>/config.yaml → tui.statusLine (array) + tui.customStatusLine (Pv() in launcher chunk).
  • Valid statusLine items: current-dir, session-title, git-branch, review-link, plan-mode, approval-mode, model-with-reasoning, model, context-window, subagent, token-quota, cache-read-ratio, context-remaining, context-meter, custom-command.
  • Custom command runner: only active when custom-command is in statusLine and build-mode is not; command required (non-empty). Schema: display: inline|block, position: above|below, colorMode: plain|ansi, intervalSeconds (default 0 = off, clamp ≥10), timeoutMs (default 5000, clamp 500–30000), block maxLines default 3 (clamp 1–5).
  • Invocation: {command} parsed + spawned with cwd = workspace_dir, JSON on stdin ({protocol, event: startup|interval|session-change|workspace-change, session_id, workspace_dir, model, session_title, tui_version}), stdout capped ~8 KiB (exact cap expression Q1 not disambiguated: 8*1024 vs 8e3 — inferred). stdout becomes the custom-command item only on exit 0 without timeout; inline mode renders the first line; colorMode: ansi keeps escape codes when the terminal color level > 0, strips otherwise.
  • Consequence: our script must be silent-fail (exit 0, empty output when unknown) and must not rely on stdin content.

D3 — mcode is the scheduler; refresh decoupled in-process

  • Context: the Claude statusline needed a systemd timer because Claude Code has no interval hook. mcode's customStatusLine.intervalSeconds re-runs the command itself.
  • Choice: no cron/systemd. On each call: fresh cache (≤150s) → print; stale → spawn detached (setsid, fallback & disown) flock-guarded refresh (--refresh-bg) and show the still-valid value (≤360s) or nothing.
  • Consequences: zero extra services; segment self-heals; offline machines just hide the segment after 6 min. Timer coexistence is harmless (same cache file).

D4 — Shared cache with the Claude Aygea statusline

  • Choice: keep schema {pct, reset_iso, ts} at ~/.cache/aygea-sl/quota.json exactly as the Claude refresher writes it (reset written as local ISO; epoch conversions have GNU/BSD branches).
  • Consequence: both ecosystems interop; any writer refreshes both. Constrained the parser to ISO strings instead of the internally simpler reset_ms.

D5 — Config merge safety rails

  • Context: user requirement: atomic, previous-entry aware, must never break a config holding API keys. Two early bugs (in-place write; backup taken after merge) proved the point.
  • Choice: python3 stdlib line surgery limited to the tui: block; refuses multiple tui: blocks or duplicate keys; validates result (structural + PyYAML when available); writes temp + fsync + os.replace; preserves mode (0600 for new); timestamped backup copied before first modification; byte-exact elsewhere (incl. trailing newline).
  • Alternatives: PyYAML full round-trip (rejected: reformats/comments lost); yq (rejected: extra dependency on every machine).
  • Consequences: merge is monotonic and reviewable; docs/FEATURE-MATRIX.md gates remaining platform risk.

D6 — Public repo + Gitea over SSH port 2222

  • Choice: repo git.itsaygea.com/admin/mcode-sl (main); remote via SSH; the curl one-liner points at …/raw/branch/main/install.sh. No secrets in the repo by design (D1).
  • Consequences: see AGENTS.md → "SSH to Gitea" for the port-22 incident record, accepted host-key fingerprint, and the repeat guard.