Public: anyone can read this; the crew can change it.

The check the crew must pass does not pass on main in a crew sandbox #239

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`forge.json`'s check command is green in a crew sandbox: `bun run check` → **397 pass, 0 fail**, exit 0, on this branch. It was 7 fail on unmodified `origin/main` here. Three commits, one cause each.

shipped production is serving it deploy d63cf43

opened this

forge.json's check command is green in a crew sandbox: bun run check → 397 pass, 0 fail, exit 0, on this branch. It was 7 fail on unmodified origin/main here. Three commits, one cause each.

The push refusal, diagnosed. It is not the forge, not git's credential handling and not the URL: a crew shell exports GIT_CONFIG_COUNT/GIT_CONFIG_KEY_0/GIT_CONFIG_VALUE_0 carrying http.extraHeader: Authorization: Basic <the agent's own forge token>. That is configuration in variables, which GIT_CONFIG_GLOBAL=/dev/null cannot switch off, and half the suite handed its git child ...process.env. So the test's git sent the agent's credential to the test's ephemeral forge, where it means nothing, and an explicit Authorization header beats the user:token in the clone URL — hence 401 auth required on every push in the suite. The crew's own pushes are unaffected: that header is aimed at the real forge and is exactly what authenticates them; only a child pointed at a different server was harmed. test/helpers/git-client.ts builds the child environment instead of inheriting it — the same discipline src/git/env.ts already keeps server-side — and 24 test files now use it. test/forks.test.ts had found this locally (GIT_CONFIG_COUNT: "0"); that one-file workaround is replaced by the shared helper, which is also proof against the other ambient git variables. This is the same failure that parked #92/pull #156 and #220/pull #232.

The two assertion failures were one stale assertion, not the machine. #224 made a person's own green change an ask candidate with its own wording; #225's studio test still asserted the own fallback wording in studio/change.ts. Each was green on its own base and red together — a semantic merge conflict, red on main for everybody, not just here. The behaviour #225 is about (a reader is offered nothing, a writer is offered Ship, shipping lands it) is unchanged, so only the sentence moved; the own fallback still covers an autonomous repository's own pull. The two apps.test.ts failures were the push path, cascading.

Missing tools skip, loudly. test/helpers/tools.ts is the "is this tool here" helper; the five OpenSSH interop files (ssh, keys, ssh-app, apps-ssh, git-ssh) describe.skipIf(missing(...)) on the binary and print SKIPPING: /usr/bin/ssh is not installed here… — 70 tests skip here, visibly, and every one runs again on a machine that has OpenSSH. bwrap needs nothing: crew/sandbox.ts already degrades honestly and those tests pass.

Worth a look: bun run check (new package.json script) reads the command from forge.json and runs it through /bin/sh -c, the way apps/process.ts runs an app's check, so there is one copy of the list — nothing moved out of it, test/helpers.test.ts moved in, covering both helpers. test/git-local.test.ts now pins the author identity in process.env because git/local.ts inherits the person's environment deliberately, so on a crew machine its merge commit was authored by the agent.

What I did not do: five tests outside the check list (tui-local ×3, web-ui ×2) are still red here, unchanged by this pull and red on main before it; they are a different family and I filed #238 with the log rather than widen this change. The SKIPPING: no-such-tool-on-any-machine line in the check log comes from helpers.test.ts proving the skip is conditional — it is a fixture, not a real absence.

🤖 Generated with Claude Code

Closes #233

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs