gosalyn: Case 2 row A brief (ZAI_API_KEY in ENV_ALLOW) and row B brief (#428, held to after 10-27) (sage-1457, sage-1469)

This commit is contained in:
2026-10-20 15:41:07 -05:00
parent 29404f9964
commit f325657c7a
+89
View File
@@ -842,3 +842,92 @@ Any live host or real model call.
### Gate
Dewey runs the script and approves. It is green on Sage's gate with every `scripts/test-*.sh`.
---
## Brief: row A, ZAI_API_KEY in the session env allowlist
### Problem
For 10-27, Bean and Chet both run pi with provider `zai` on `glm-5.3` (Q186, mos-1090, sage-1469). Pi
reads the zai key from `ZAI_API_KEY` (pi-ai `env-api-keys.js:89`, with `glm-5.3` in `data/zai.json`).
`ENV_ALLOW` (`packages/seat/src/session.mjs:83-88`) doesn't hold that name, so `sessionEnv` (`:97-99`)
drops it. A pi launch has no credential check (`packages/plugins/harness/pi/index.mjs:42`
`countsAccount: false`, `packages/cli/src/launcher.mjs:299`), so today a zai role launches and fails at
its first turn, as `packages/cli/README.md:439-444` says.
### Owner and reviewer
- Owner: a Haiku 5.5 subagent at high effort, dispatched by Sage (lead decision 129). Size XS.
- Reviewer: Webby.
- After: nothing. It doesn't wait on any Case 2 row.
### Files owned
`packages/seat/src/session.mjs`, `packages/seat/tests/session.test.mjs` and `packages/cli/README.md`.
### What ships
- `"ZAI_API_KEY"` joins the provider line of `ENV_ALLOW` (`session.mjs:86`), after `OPENROUTER_API_KEY`.
Nothing else in the list changes. `SESSION_CREDENTIALS` and `hasSessionCredential` (`:94-95`) don't
change. They are Claude Code's login sets, and a zai key isn't one.
- `packages/cli/README.md`, after "A Pi session gets the same variables through the allowlist." (`:435`),
one sentence: a Pi session on provider `zai` logs in with `ZAI_API_KEY`, which the allowlist passes. Like
every allowlist variable, it reaches every session the host starts, Claude Code ones included, and a
shell inside any of them can read it.
- One test in `session.test.mjs`: `ENV_ALLOW` includes `ZAI_API_KEY`, and
`sessionEnv({ ZAI_API_KEY: "fixture-zai", ZAI_TOKEN: "t" }, run)` returns `ZAI_API_KEY` with the fixture
value and no `ZAI_TOKEN`. The existing allowlist test (`:51-59`) stays as it is.
- One mutant: the same file with `"ZAI_API_KEY"` removed from `ENV_ALLOW`. The new test fails on it.
### Out of scope
Placing a key anywhere. The hub's own key on the Z.ai account is design 10 step 2, and it is Jason's.
Any pi launch or live check: running a pi role waits on #383. Chet's Codex login (row B, #428). A
credential check for pi launches.
### Gate
Webby approves the manifest. The mutant is killed. The seat suite and the cli suite are green on
Sage's gate with every `scripts/test-*.sh`.
---
## Brief: row B, a per-instance pi agent dir for Chet's Codex login (#428)
### Problem
After 10-27, Chet moves from Bean's Z.ai account to his own ChatGPT/Codex login (Q186). Pi's
`openai-codex` provider logs in with OAuth and a refresh token, and keeps both in `auth.json` under
`PI_CODING_AGENT_DIR` (pi `config.js:405-438`). A role session's `HOME` is the run's own, so pi never
sees an agent dir from the host (`packages/cli/README.md:439-441`), and `ENV_ALLOW` doesn't pass
`PI_CODING_AGENT_DIR`. So no env variable can carry this login. Each instance needs its own agent dir
that survives runs, because a refresh rewrites the file.
Chet's Hermes profile uses the same login today. Until Hermes stops, two clients would hold one
refresh token. If a refresh by one revokes the other's, one of them drops out mid-session.
### Owner and reviewer
- Design: Gosalyn owns it (sage-1469). The build owner and reviewer are named when the design is
approved.
- Starts after 10-27. Nothing in this row is built or tested before then.
### Files owned
None yet. The design names them.
### What ships
The design first. It settles where the dir lives and who can read it, how the launcher mounts it into
the sandbox writable for one instance only, how a refresh write survives the run, what a shell in the
session can read, and how a launch with no login refuses. Build rows follow from it.
### Out of scope
Bean's model path. Any change to row A. Any change to Hermes or her server.
### Gate
A live check, run with Jason's or Mos's go, showing that two clients on one ChatGPT login don't revoke
each other's refresh tokens. Until that check passes, no build row for this design starts.