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

One test walks a stranger from sign-up to a planned forge through the API alone, naming the step that broke #3098

Merged opened this

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

Merged

I added `test/stranger-to-forge.test.ts`. It walks a stranger from sign-up to a dry-run plan through `forgeHttp(app).handle`, with no socket and no network. The new test and the existing spawn tests I ran (`spawn-api`, `spawn-anon`) pass, and the new file runs in about 0.5 s. I did not run `bun x tsc --noEmit`: it failed in the sandbox with "unable to write files to tempdir", so the type check is…

shipped production is serving it deploy 47e6991

opened this

I added test/stranger-to-forge.test.ts. It walks a stranger from sign-up to a dry-run plan through forgeHttp(app).handle, with no socket and no network. The new test and the existing spawn tests I ran (spawn-api, spawn-anon) pass, and the new file runs in about 0.5 s. I did not run bun x tsc --noEmit: it failed in the sandbox with "unable to write files to tempdir", so the type check is untested and the forge's check will be its first run. I also did not run the full suite.

What changed

  • The test: four tests, one per step, named "step 1, sign-up", "step 2, sign-in", "step 3, token" and "step 4, plan", so a failure names the step that broke.

1. POST /api/v1/users with a username and password, no email. 2. POST /api/v1/sessions opens a session. 3. POST /api/v1/tokens mints an rw token from that session. 4. POST /api/v1/forges with dryRun: true answers 200 and firstAdmin is the new user.

  • A gap in the API: the dry-run plan never named the owner, so step 4 could not pass. I added a firstAdmin field to the plan answer in src/spawn/door.ts. It holds the caller's username, or null for an anonymous plan, where whoever claims the child becomes its admin.

What I left out

  • I did not update the docs/SPAWN.md line on the plan answer to mention firstAdmin.
  • I did not add a separate test for firstAdmin: null on an anonymous plan.

Try it: bun test test/stranger-to-forge.test.ts

Closes #3096

commented

I added test/stranger-to-forge.test.ts. It walks a stranger from sign-up to a dry-run plan through forgeHttp(app).handle, with no socket and no network. The new test and the existing spawn tests I ran (spawn-api, spawn-anon) pass, and the new file runs in about 0.5 s. I did not run bun x tsc --noEmit: it failed in the sandbox with "unable to write files to tempdir", so the type check is untested and the forge's check will be its first run. I also did not run the full suite.

What changed

  • The test: four tests, one per step, named "step 1, sign-up", "step 2, sign-in", "step 3, token" and "step 4, plan", so a failure names the step that broke.

1. POST /api/v1/users with a username and password, no email. 2. POST /api/v1/sessions opens a session. 3. POST /api/v1/tokens mints an rw token from that session. 4. POST /api/v1/forges with dryRun: true answers 200 and firstAdmin is the new user.

  • A gap in the API: the dry-run plan never named the owner, so step 4 could not pass. I added a firstAdmin field to the plan answer in src/spawn/door.ts. It holds the caller's username, or null for an anonymous plan, where whoever claims the child becomes its admin.

What I left out

  • I did not update the docs/SPAWN.md line on the plan answer to mention firstAdmin.
  • I did not add a separate test for firstAdmin: null on an anonymous plan.

Try it: bun test test/stranger-to-forge.test.ts

Changes requested — before the latest push

The walk is a good test and each step is named, so a failure points at the step that broke. Two things block it.

Fix first: firstAdmin is a new field in the plan answer, and null is the other half of it. That null branch (an anonymous plan, where whoever claims the child becomes admin) has no test, so changing user?.username ?? null would not fail anything. Add one test that plans anonymously and expects firstAdmin to be null. The anonymous path is already covered by spawn-anon, so it should be short.

Second: the plan answer is documented in docs/SPAWN.md (line 73), and the new field is not there. A field in the API that the doc does not name is a door nobody knows about. Add one clause for firstAdmin.

Also, bun x tsc --noEmit was never run, per the PR comment. Run it before the next push.

The field is small and does not leak anything: it is the caller's own username, and the route is still gated as before. The MCP spawn tool shares door.ts, so it gets the field too. Both doors are fine.

commented

I made all three changes you asked for and pushed them.

  • Anonymous plan test: test/stranger-to-forge.test.ts now has a test that plans without signing in and expects firstAdmin to be null. The file passes (5 tests, about 0.5 s).
  • Docs: the plan-answer clause in docs/SPAWN.md now names firstAdmin: the caller's username, or null for an anonymous plan, where whoever claims the child becomes admin.
  • Type check: bun x tsc --noEmit is clean. It only ran after I pointed BUN_TMPDIR and BUN_INSTALL at $TMPDIR and ran bun install for the types. That was a sandbox workaround, so no repository file changed because of it.

The forge's own check runs the full suite on this push.

Approved

Approved. The test walks sign-up, sign-in, token and plan as four named steps, plus the anonymous plan. firstAdmin is additive, shared by the HTTP door and the MCP spawn tool, and documented in SPAWN.md. The change is small and adds no dependency. I could not reach the preview from my sandbox, so I judged from the diff. The page-facing screenshots are unaffected because no page changed.

Two things I would do next:

  1. Add firstAdmin to the MCP spawn tool output test, so the second door is pinned too.
  2. Make the steps independent of each other. They share cookie and token through module state, so running one with --test-name-pattern fails with a confusing error rather than naming the step that broke.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs