brief: codex writes the code, we make the commits
The first run wrote 679 lines of tests and could not commit one of them: codex holds .git read-only by design, and a worktree's metadata lives in the parent repo's .git, outside the workspace entirely. Fighting that is the wrong instinct — the protection is right, and the division it implies (the model writes code, the orchestrator commits) is the one we want. So the brief now asks for a commit plan instead of commits, points the next run at the test drafts already sitting in the tree, and tells it not to trust them: they never ran, because the same sandbox refused the console fixture a listener. Copy gets the same treatment as commits — write it, list it, review it as a batch afterwards, rather than deadlocking a build on a gate that wants a human in front of a browser.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CfUNFHm89j2mj5q7vBHsfH
1 file changed,
+44
−7
docs/superpowers/specs/CODEX-BUILD-BRIEF-store-self-serve.md+44 −7
diff --git a/docs/superpowers/specs/CODEX-BUILD-BRIEF-store-self-serve.md b/docs/superpowers/specs/CODEX-BUILD-BRIEF-store-self-serve.md| index c4cacb3dd..c8be6e728 100644 |
| --- a/docs/superpowers/specs/CODEX-BUILD-BRIEF-store-self-serve.md |
| +++ b/docs/superpowers/specs/CODEX-BUILD-BRIEF-store-self-serve.md |
| @@ -5,7 +5,7 @@ commit. **Reviewer:** a second model reads the result afterwards; write for that |
| reading. |
| **Repo:** carlos/platform. **Branch:** `worktree-store-self-serve`. |
| -**Base commit:** `af8d996`. **Spec:** |
| +**Base commit:** `4e6ea53`. **Spec:** |
| `docs/superpowers/specs/2026-09-02-object-storage-self-serve-design.md` — |
| read it whole before writing anything. It is the contract; this brief only |
| scopes the slice and names the traps. |
| @@ -82,11 +82,48 @@ changes here. Everything before it is inert. |
| server. §13 lists the cases; treat that list as the minimum, not the target. |
| - `AGENTS.md` governs — read it. In particular: `go build ./...`, |
| `go vet ./...`, `go test ./... -count=1` and `gofmt -l .` all clean before |
| - any commit. Sandbox note in its Build & test section: |
| - `GOCACHE=/tmp/claude-1001/gocache GOFLAGS=-mod=mod GOPROXY=off`. |
| -- One commit per stage, in order, each one green on its own. Commit messages in |
| - this repo's voice: what changed and the reasoning that made it that shape — |
| - read `git log` for the register. |
| -- If the spec is wrong or underdetermined, say so in the commit message and in |
| + you call a stage done. Use |
| + `GOCACHE=/home/paulca/.claude/tmp/gocache-codex GOFLAGS=-mod=mod GOPROXY=off`. |
| +- **Do not run `git commit`, `git add`, or any other writing git command.** |
| + Your sandbox holds `.git` read-only on purpose and that is the right |
| + division of labour: you write the code, the orchestrator makes the commits. |
| + Leave the tree dirty and finish with a **commit plan** — for each stage, the |
| + exact file list and a commit message in this repo's voice (read `git log` for |
| + the register: what changed, and the reasoning that made it that shape). |
| +- **User-facing copy.** This repo's owner gates new user-facing wording behind |
| + a review he runs himself. The wording the spec already fixes — §6's two |
| + changed sentences at `store.go:261` and `:348`, and any string the spec |
| + quotes — is settled; write it as specified. For any string you must invent |
| + (a new CLI message, a new error), write the clearest thing you can and |
| + **list every one of them in your final summary** under a heading |
| + `NEW USER-FACING COPY`, with its file and line. They go to review as a batch |
| + after the build. Do not block on this, and do not start a review server. |
| +- If the spec is wrong or underdetermined, say so in the commit plan and in |
| your final summary rather than inventing a rule silently. A named gap is |
| worth more than a guess. |
| + |
| +## Resuming from the first run |
| + |
| +A first run (2026-09-08) was stopped by sandbox blockers before it could |
| +commit. Its test drafts are **already applied to the working tree**, uncommitted: |
| + |
| +- `internal/edge/storedoor_test.go` — the §4 implementation-gate test. It found |
| + that stage 3 *claimed* this test and it did not exist; the test now exists |
| + and passes, and `aclRead` already excludes `store/entitlements/`, so no |
| + policy change is needed. |
| +- `internal/console/apistore_entitlement_test.go` — stage 4 door tests. |
| +- `internal/console/apistore_provision_test.go` — stage 5 provision tests. |
| +- `internal/console/svcroutes_test.go` — four closed routes, count 17 → 21. |
| + |
| +**These drafts never ran** — the console fixture could not open a listener in |
| +that run. Treat them as a starting point to be run, corrected and extended, |
| +not as verified work. The first run's own notes flag two gaps in them: stage 5 |
| +still needs a concurrent *two successful provisions* regression that mints one |
| +key (the existing queued test revokes before the second request), and stage 6 |
| +has no tests yet. |
| + |
| +That run's full findings — twelve of them, including that the spec's route |
| +paths (`/a/{sqid}/apps/{app}/store/provision`) do not match the actual CLI |
| +route family (`/api/cli/...`) — are in `/tmp/store-self-serve-resume.md`. |
| +**Read that file.** Where it proposes a resolution, the proposal is sound |
| +unless the spec contradicts it; say in your commit plan which ones you took. |