Handoff
Developer evaluation brief — ten checks to run before anyone buys
Who this is for
Buying this kit for your developer? Send them this page before you decide anything. Every check below runs against the live demo at demo.buildgrain.com — no signup wall, no sales call, nothing to install. The full repository arrives with the kit; the demo is built from the same source, so what your developer measures here is what they would maintain.
1. Measure the response envelope yourself
curl -i https://demo.buildgrain.com/api/meExpect a 401 JSON envelope carrying a req_-prefixed requestId and the reason signin-required. Compare it against the documented envelope at /docs/api — they must match, because both come from the same wrapper.
2. Check the security headers with one command
curl -sI https://demo.buildgrain.com/ | grep -iE 'x-frame|x-content-type|referrer-policy|content-security|permissions-policy'Five baseline headers, exactly the table at /docs/security. If the live response and the docs ever disagree, that is a finding — report it via /contact.
3. Read the route wrapper, not a diagram
Open the Code tab on the demo's developer surface (/admin/developer) and read apps/web/src/lib/api.ts — the withApi() wrapper every route handler runs through: request id stamping, session injection, deny-by-default RBAC, zod 422 mapping, audit hook. The excerpt is drift-tested against the live file, so what you read is what runs.
4. Read the RBAC matrix and its contract test
In the same Code tab: packages/rbac/src/permission-matrix.ts (the role table as data — an absent cell denies) and packages/rbac/tests/permission-matrix.test.ts (a full role × action × resource sweep encoded independently of the production matrix). ADR-002 at /docs/concepts explains why systemAdmin only wins on admin resources.
5. Count the test surface
The kit ships 18 Playwright spec files under e2e/specs, covering OAuth start, route guards, tenant isolation with malicious payloads, CRUD flows, admin reflection, mail enqueue, and the nightly reset — plus unit suites in every workspace package. The spec list ships with the repo; checks 6 and 7 let you replay the two most important ones against the demo right now.
6. Probe tenant isolation with two accounts
Sign in with two different Google accounts. Each gets its own workspace; confirm account B never sees account A's projects, tasks, or files — then read e2e/specs/16-tenant-isolation-malicious-payload.spec.ts (with the repo) for the adversarial version: foreign account ids in request bodies are refused server-side. The mechanism is scopedQuery() — see /docs/security.
7. Check the 401 reason split
Visit /app signed out: you land on /login?reason=signin-required, not a generic bounce. The APIs return the same split in the envelope — signin-required when no session signal exists, session-expired when credentials are present but stale. Precise failure semantics are something you feel every day of maintenance.
8. Exercise the API explorer
Open /admin/api on the demo: download the OpenAPI document, send live requests against the product API, and inspect the envelope, error examples, and pagination defaults (perPage: 20). The explorer talks to the same handlers the app uses — there is no separate demo API.
9. Inspect the mail boundary
Open /admin/mail: the preview shows the exact rendered subject, HTML, and plain-text parts, because the preview and the sender share one render source (ADR-005 at /docs/concepts). In demo mode every message stays in a local queue — if you can find a path that sends real mail from the demo, that is a finding.
10. Read the ADRs and the stack, then answer one question
Read the five ADRs at /docs/concepts and the generated dependency table in the Stack section at /docs — every runtime dependency with its license listed, zero copyleft, regenerated from the installed packages. Then answer the only question that matters: would you want to live in this codebase?
If your developer says no
Send this to your developer first. If they say no, don't buy it. The kit only pays off if your developer wants to maintain it.