feat(auth): M19 harness auth tooling — auth.sh checkpoint + per-launch account injection (#47)

Investigation (pi 0.84.4 docs + host auth.json metadata, values never
read): provider stacking is native (one auth.json keyed by provider;
resolution --api-key > auth.json > env > models.json; OAuth auto-refresh).
Multi-account per provider is NOT native -> named-file design:
auth.<account>.json + per-launch injection.

- scripts/auth.sh: status (provider names, credential types, perms,
  env-side names informational — never credential material) and accounts
  (named files, active marker). Exit codes per convention: 3 missing for
  a read, 2 unparseable, 4 file/environment (symlinks refuse).
- scripts/agent.sh --auth <account>: resolves auth.<account>.json and
  exports PI_AUTH_FILE (the existing compose read-only mount source — no
  new plumbing); missing/invalid account refuses pre-container.
- scripts/test-auth.sh: 13 no-Docker cases; core assertion is the safety
  property itself — fixture key/token/env VALUES never reach output.
- Docs: TOOLS.md Auth section, AGENTS.md command surface + suites.

Headless task runs keep the default credential (worker auth selection is
a separate policy decision). Real-host smoke: anthropic/openai-codex
oauth + zai api_key reported, perms 600, no named accounts yet.

Suites 24/90/14/17/13 + verify green. Agreed sequence M16-M19 complete;
M20 owner-gated.
This commit is contained in:
2026-09-03 19:58:50 -05:00
parent d1d7b5598d
commit 073bbfdb6a
8 changed files with 259 additions and 6 deletions
+31
View File
@@ -522,3 +522,34 @@ verify green.
Suites 24/90/14/17 + verify green. Seat resolution is now fail closed in
every direction: unknown seat under override, declared role without
contract, invalid contract, empty ceiling intersection.
## Phase 24: M19 — harness auth tooling (pi checkpoint)
- Investigation (pi 0.84.4 docs + host auth.json metadata; values never
read): provider stacking is native — one auth.json keyed by provider,
resolution `--api-key > auth.json > env > models.json`, OAuth entries
auto-refresh. Multi-account per provider is NOT native (one entry per
provider, no namespacing) → named-file design confirmed:
auth.<account>.json + per-launch injection.
- scripts/auth.sh: `status` (provider names + credential types + perms +
env-side credential-like NAMES, informational; never credential
material) and `accounts` (named files, active marker). Exit codes per
convention: 3 missing for a read, 2 unparseable, 4 file/environment
(symlink refuses).
- scripts/agent.sh --auth <account>: resolves auth.<account>.json and
exports PI_AUTH_FILE — the compose read-only mount source, so no new
plumbing. Missing/invalid account refuses before any container work.
- scripts/test-auth.sh (13 cases, no Docker): the core assertion is the
safety property itself — fixture key/token/env VALUES never reach
output — plus the exit-code paths and the accounts listing.
- Scope note: headless task runs keep the default credential; worker auth
selection is a separate policy decision.
- Real-host smoke: 3 providers reported (anthropic/openai-codex oauth,
zai api_key), perms 600, no named accounts yet.
## Result (M19)
Auth is checkpointable without exposing credentials, and multi-account has
a per-launch path. Suites 24/90/14/17/13 + verify green. The agreed
ROADMAP sequence M16M19 is complete; M20 (packages/* restructure +
unified CLI) is owner-gated.