Public: anyone can read this; the crew can change it.
An admin makes gift codes in the forge: a code gives a plan for free, with or without a payment provider #11166
Check · Review · Land · Live — Its check is running.
Gift codes work end to end. An admin makes one in Settings → Billing, and a visitor redeems it on `/forges/new`. The new tests (`test/gift-codes.test.ts`), the neighbouring suites, `bun x tsc --noEmit`, `bun scripts/gate.ts`, `bun scripts/design-lint.ts` and `bun test test/mcp-size.test.ts` all pass. I didn't run the full suite or boot the app; the forge runs the full check on push. I also couldn'…
22 files · +886 −15
working checking now deploy 15a672a
Check running · 3 min · 555 of 2296 files · 3318 passed, 0 failedCheck of 15a672achecked against main at 8011647fast tier: running · full gate runs on land
Website spec: 19 findings (report only)
- /board http://127.0.0.1:43441/board answered 303 — https://specification.website/
- /notes http://127.0.0.1:43441/notes answered 303 — https://specification.website/
- /feed http://127.0.0.1:43441/feed answered 303 — https://specification.website/
- /review http://127.0.0.1:43441/review answered 303 — https://specification.website/
- /new http://127.0.0.1:43441/new answered 303 — https://specification.website/
- /pinned http://127.0.0.1:43441/pinned answered 303 — https://specification.website/
- /releases http://127.0.0.1:43441/releases answered 303 — https://specification.website/
- /repos http://127.0.0.1:43441/repos answered 303 — https://specification.website/
- /map http://127.0.0.1:43441/map answered 303 — https://specification.website/
- /system http://127.0.0.1:43441/system answered 303 — https://specification.website/
- /talk http://127.0.0.1:43441/talk answered 303 — https://specification.website/
- /flow http://127.0.0.1:43441/flow answered 303 — https://specification.website/
- /resilience http://127.0.0.1:43441/resilience answered 303 — https://specification.website/
- /settings http://127.0.0.1:43441/settings answered 303 — https://specification.website/
- /preview-admin/sample expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/next expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/bets expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/waves expected exactly one <h1>, found 2 — headings
- /preview-admin/sample/milestones expected exactly one <h1>, found 2 — headings
Gift codes work end to end. An admin makes one in Settings → Billing, and a visitor redeems it on /forges/new. The new tests (test/gift-codes.test.ts), the neighbouring suites, bun x tsc --noEmit, bun scripts/gate.ts, bun scripts/design-lint.ts and bun test test/mcp-size.test.ts all pass. I didn't run the full suite or boot the app; the forge runs the full check on push. I also couldn't call the keep_plan tool, so this issue has no plan kept.
What changed
- Codes: a code looks like
forge-7kq4-m2xp, and only its SHA-256 is stored. The plain code and its…/?code=<code>link appear once, in the answer that makes it. - Billing page: the Codes section is above Plans. It has a make form (plan, uses, note, expiry), the one-time code and link with copy buttons, and one line per code showing plan, note, used of limit, who redeemed it, and Revoke. A test checks that ten codes render as ten one-line rows; I didn't measure the first view in a browser.
- Redeeming:
/?code=redirects to/forges/new?code=. That page is prefilled and says "A gift from alice: a medium forge, free." A wrong, used-up, expired or revoked code is said beside the field, and the form stays.POST /api/v1/forgesand the MCPspawnacceptcodetoo. - What redeeming does: the forge is made on the code's plan with no checkout. This works for strangers and for signed-in non-admins, who were previously refused paid plans. The entitlement source is
code:<id>. - Spending a use: the use is claimed in one statement just before the forge is made. It goes back if the forge isn't made, so two visitors can't share the last use.
- Rate limit: each client gets 10 code attempts per 10 minutes, stored in the database; past that the API answers 429.
- API and MCP:
GET/POST /api/v1/codes(dryRunis true unlessfalse) andDELETE /api/v1/codes/{id}. The MCPforgestool gainedcodes,codeandrevokeinstead of a new tool.test/mcp-size.test.tspasses and no ceiling moved. - Audit: every make, redeem and revoke is a
billing.code.*event, visible to admins only. - Migration, docs and tests: one additive migration with its pin. The how-to is in
docs/features/billing.md. - Spawn change:
spawnForgetakes agiftflag that skips the admin-only paid-plan check; it is set only after a code has been claimed.
What I left out or decided
- #11153 (home form), #11138 (
/pricing) and the Stripe provider aren't onmain. The code field and the gift line are on/forges/newinstead, and/?code=redirects there. The/pricingand home-form wiring is still to do once those exist. - Because no provider exists, the "none and stripe both redeem" test can't be written literally. The test shows a redemption makes no outbound call and writes the entitlement with provider
none. - A code can't give the free plan, since that gives nothing.
- I added no terminal screen for codes and no
/agentsform field.
Try it
Open /settings/billing as an admin and press Make a code. Then open the link signed out. Or run POST /api/v1/codes {"plan":"medium","dryRun":false}.
Gift codes: an admin can now make, list and revoke them. A code gives a plan for free, with or without a payment provider. This push fixes the three failing checks.
- Session phase:
GET /api/v1/codesnow records asessionphase like the other timed GET routes. That clears the route-timing test, which had flagged it as answering 200 without one. - Tag:
/api/v1/codesnow belongs to thebillingtag. Before, it produced acodestag that had no description line. - Unused function: I removed
claimGiftfromsrc/actions/codes.ts. Nothing called it, because the door callsclaimCodedirectly, and the hollow-work audit flagged it. I also dropped the now-unusedclaimCodeimport there.
I did not re-run the three failing tests after the final import edit. After the first fix I re-ran them together with the gift-codes tests and all 48 passed. After the import edit, tsc, bun scripts/gate.ts and the gift-codes tests (12) were clean. The forge's full check runs on this push.
To try it: sign in as an admin, open /settings/billing, choose Make a code, then open the /?code= link signed out.
Gift codes work end to end. An admin makes one in Settings → Billing, and a visitor redeems it on
/forges/new. The new tests (test/gift-codes.test.ts), the neighbouring suites,bun x tsc --noEmit,bun scripts/gate.ts,bun scripts/design-lint.tsandbun test test/mcp-size.test.tsall pass. I didn't run the full suite or boot the app; the forge runs the full check on push. I also couldn't call thekeep_plantool, so this issue has no plan kept.What changed
forge-7kq4-m2xp, and only its SHA-256 is stored. The plain code and its…/?code=<code>link appear once, in the answer that makes it./?code=redirects to/forges/new?code=. That page is prefilled and says "A gift from alice: a medium forge, free." A wrong, used-up, expired or revoked code is said beside the field, and the form stays.POST /api/v1/forgesand the MCPspawnacceptcodetoo.code:<id>.GET/POST /api/v1/codes(dryRunis true unlessfalse) andDELETE /api/v1/codes/{id}. The MCPforgestool gainedcodes,codeandrevokeinstead of a new tool.test/mcp-size.test.tspasses and no ceiling moved.billing.code.*event, visible to admins only.docs/features/billing.md.spawnForgetakes agiftflag that skips the admin-only paid-plan check; it is set only after a code has been claimed.What I left out or decided
/pricing) and the Stripe provider aren't onmain. The code field and the gift line are on/forges/newinstead, and/?code=redirects there. The/pricingand home-form wiring is still to do once those exist.none./agentsform field.Try it Open
/settings/billingas an admin and press Make a code. Then open the link signed out. Or runPOST /api/v1/codes {"plan":"medium","dryRun":false}.Closes #11157