# Packet W2 receipt — grants, identity, honest catalog, destination-render gate **Actor:** Helios (Cursor on Icarus, `centaur-macmini-1`) **Composer:** Mitchell Burns **Date:** 2026-09-13 **Work order:** [`ASTRA_WORK_ORDERS.md`](ASTRA_WORK_ORDERS.md) W2 **Contract:** [`ASTRA_INTERFACE_CONTRACT.md`](ASTRA_INTERFACE_CONTRACT.md) §3–5, §7–8 This file is a chip receipt. It does not rewrite [`ASTRA_DESIGN.md`](ASTRA_DESIGN.md) or the freeze JSON zip identity. --- ## Context snapshot | Field | Value | |---|---| | `plan_branch` | `cursor/w2-identity-grants-0101` | | `base` / `master_sha` | `48c8bd5b7acc376426c6cc99ece877b6c4dc5ad9` (W1 tip `cursor/w1-durable-host-0101`) | | `freeze` | `4d355a5994467bbe64dc28b9b5817037e25a02ce` (W0; not the implementation base) | | `tip` | branch `cursor/w2-identity-grants-0101` HEAD (Helios handback names the live SHA) | | `sync_method` | bootstrap (isolated worktree from W1 tip; no rebase onto W5/W6) | | `colliding_prs` | W5 audio (`cursor/w5-audio-import-0101`), W6 export (`cursor/w6-movie-export-0101`) — separate worktrees. This chip did not touch `wav.ts` or `mux-webm-av.ts`. | | `blocking_owner_items` | W3 in-app OpenAI operator; W4 keep/guide/correct marks + Studio chrome | | `non_claims` | listed below | Worktree: `/Users/icarus/.cursor/worktrees/korgi-w2-identity-grants-20260913` Remote: **gdrive only**. No `origin` push. No FF `main`. No Railway. Freeze zip/tgz untouched. PixelLab $0. No paid Higgsfield/OpenAI still run. --- ## What landed 1. **Better Auth on.** `.grok/app-env.json` no longer sets `VITE_AUTH_ENABLED: "false"`. Email/password is on. `/login` is a real TanStack route that can mint a session (`authClient.signIn.email` / `signUp.email` + Grok OAuth). Better Auth catch-all lives at `/api/auth/$`. `SIGN_IN_PATH` remains `/login`. 2. **Fail-closed production.** Auth-off + `DATABASE_URL` still throws. Auth-off in `NODE_ENV=production` does not return `dev-user` (even with no database). Production without `GROK_AUTH_CLIENT_ID` + `GROK_AUTH_CLIENT_SECRET` + `BETTER_AUTH_SECRET` throws at process start (`assertProductionAuthConfig` on `server.ts` / `verify.server.ts` import). Signed-out mutate → 401. `"dev-user"` is local no-database convenience only. 3. **User-minted bindings from session identity.** HTTP host `bind` / `bind-grant` and HTTP MCP mint from `requireSession()` (`userId` + `sessionId`). Client-supplied actor is ignored. Origin must be `user` or `studio`. Model / operator / llm cannot mint `studio *`. `dev-user` cannot mint origin=`user` bindings. 4. **Honest catalog.** After Packet A bind, `tools/list` length is **exactly 2** (`korgi_settings_setName`, `korgi_peg_setFollow`), not 69. Unbound studio catalog is still the full registry. 5. **Confirmation.** Delegated grants do not auto-set `confirmed: true`. Studio origin may. `ActionDef.confirm` is honored (`korgi.film.setClock` prompt refused until confirmed). `korgi.gen.accept` is `confirm: "prompt"`. 6. **Session revocation.** `invalidateSession` / `revokeHostSession` invalidates bindings minted for that session. Subsequent execute refuses (`invalidated binding`). Sign-out calls host `op: "revoke"` before clearing the cookie. Packed `host/authority.json` restores `sessionId` / `userId` / members so revoke still applies after reopen. 7. **Server-validated membership.** First authenticated bind bootstraps members. A later user who is not a member cannot mint. 8. **Destination-render quality gate.** Dest apply keeps candidate RGBA on the cel (`EncodedCel.picture`). Overlay uses that picture instead of the 4-color indexed scan. Indexed `hydrateCelFromRgba` remains the accepted-frame2 defect class (posterize / paper holes). Corrected apply: dest pixels match the prepared candidate at shot size. Packet C hashes are recorded; PNGs were not regenerated. Known-bad / known-size hashes (gallery / packet-c; not approved art): | Frame | Size | sha256 | |---|---|---| | original | 2048×1152 | `f5a75e91be1a673229dfeec55773873cbe813625d504dbb452cbb70f879cc79c` | | prepare | 1280×720 | `dc777b9489abdbc8236fd8440599e2e0aaf163bb6d970522f961def30ad249cb` | | accepted-frame2 (defect class) | 1280×720 | `128f129bea116c45c85636518942db3f26b16ba3ec7888b731252c8a1f7e726a` | --- ## Login route proof - `src/routes/login.tsx` — `createFileRoute("/login")`, email sign-in/sign-up, Grok providers. - `src/routes/api/auth/$.ts` — `auth.handler(request)` for GET/POST. - `src/routeTree.gen.ts` — `/login` and `/api/auth/$` registered. - `src/lib/auth/fail-closed.test.ts` asserts those files and `SIGN_IN_PATH = "/login"`. --- ## Catalog length proof `src/lib/korgi/mcp/packet-a.test.ts` HTTP MCP `tools/list` after Packet A bind: - `tools.length === 2` - names `korgi_peg_setFollow`, `korgi_settings_setName` `src/lib/korgi/host/project-host.w2.test.ts` in-process user-minted Packet A binding: same length and action ids. --- ## Revoke proof `src/lib/korgi/host/project-host.w2.test.ts`: - `invalidateSession("sess-17")` → Packet A execute refuses; studio binding on a different session still works. - `revokeHostSession("sess-17")` after HTTP `bind-grant` → execute refuses. - Pack / reopen / `invalidateSession` still refuses. --- ## Destination-render gate status | Fixture | Result | |---|---| | Indexed scan-grey apply vs photoreal candidate | defect class (`isPosterizeOrBlackClass` true); dest pixels do **not** match | | Corrected apply (`korgi.gen.prepare` + `accept` with `candidate-rgba` + cel `picture`) | dest pixels **match** prepared PNG at shot size | | Packet C PNG hash check | constants recorded; files hashed when present (not in this worktree; no paid regenerate) | Dest A2 Higgsfield stills remain rejected as art. This gate is compositor/apply, not a shop approval. --- ## Files changed | Path | Why | |---|---| | `.grok/app-env.json` | Auth on (drop `VITE_AUTH_ENABLED: "false"`) | | `scripts/with-app-env.test.mjs` | Workspace no longer ships auth-off | | `src/lib/auth/production.ts` | Fail-closed helpers; no production `dev-user` | | `src/lib/auth/mutate-guard.ts` | Signed-out mutate 401 | | `src/lib/auth/verify.server.ts` | Session id; `requireSession`; production assert | | `src/lib/auth/server.ts` | Production auth config assert at startup | | `src/lib/auth/email-password.ts` | Email/password on so `/login` can mint | | `src/lib/auth/client.ts` | Sign-out revokes host session first | | `src/lib/auth/fail-closed.test.ts` | Auth + `/login` proofs | | `src/routes/login.tsx` | Real `/login` route | | `src/routes/api/auth/$.ts` | Better Auth HTTP | | `src/routeTree.gen.ts` | Register `/login` and `/api/auth/$` | | `migrations/0001_auth.sql` | Better Auth tables for PGLite/Postgres | | `src/lib/korgi/host/project-host.ts` | Session/user on bindings, members, revoke, delegated confirm | | `src/lib/korgi/host/host-http.server.ts` | Session mint, membership, revoke | | `src/routes/api/korgi/host.ts` | Mutate requires session; bind-grant; revoke | | `src/routes/api/korgi/mcp.ts` | POST requires session | | `src/lib/korgi/mcp/studio-http.server.ts` | Mint from session identity | | `src/lib/korgi/mcp/server.ts` | Grant-filtered list; host confirm passthrough | | `src/lib/korgi/mcp/packet-a.test.ts` | `tools/list` length exactly 2 | | `src/lib/korgi/host/project-host.w2.test.ts` | Identity, catalog, confirm, revoke, membership | | `src/lib/korgi/actions/registry.ts` | `korgi.gen.accept` confirm prompt | | `src/lib/cel-paint.ts` | Dest picture attach/decode | | `src/lib/korgi/ingest-commit.ts` | Attach dest picture on PNG ingest | | `src/lib/stage-render.ts` | Overlay blit from dest picture | | `src/lib/korgi/generation-job.ts` | Prepare palette `candidate-rgba` | | `src/lib/korgi/generation-types.ts` | Parse `candidate-rgba` | | `src/lib/korgi/dest-render.ts` | Gate helpers + packet-c hashes | | `src/lib/korgi/dest-render.w2.test.ts` | Defect class then corrected apply | | `docs/oss/PACKET_W2_RECEIPT.md` | This receipt | Did not edit `wav.ts`, `mux-webm-av.ts`, Studio chrome, freeze JSON, `ASTRA_DESIGN.md` verdict, `EVALUATOR_DECISION.md`. Did not add a second host class. W1 pack/authority remains. --- ## Tests (this tip) Commands (worktree tip; not a historical total): ```bash ./node_modules/.bin/tsc --noEmit node --experimental-strip-types --test \ src/lib/korgi/mcp/packet-a.test.ts \ src/lib/korgi/mcp/mcp.test.ts \ src/lib/korgi/generation-recovery.test.ts \ src/lib/korgi/host/project-host.w1.test.ts \ src/lib/korgi/host/project-host.w2.test.ts \ src/lib/korgi/dest-render.w2.test.ts \ src/lib/auth/fail-closed.test.ts ``` | Gate | Result | |---|---| | `./node_modules/.bin/tsc --noEmit` | pass | | `packet-a.test.ts` | pass (HTTP `tools/list` length 2) | | `mcp.test.ts` | pass | | `generation-recovery.test.ts` | pass | | `project-host.w1.test.ts` | pass | | `project-host.w2.test.ts` | pass (catalog 2, revoke, membership, confirm) | | `dest-render.w2.test.ts` | pass (indexed defect; corrected apply matches) | | `fail-closed.test.ts` | pass (401, auth-off+DB throw, `/login` exists) | `node --test scripts/with-app-env.test.mjs` also pass (auth-on workspace). SHA of the commit that contains these results is the branch tip after this receipt is committed. --- ## non_claims - Not a creator product. Not a release. No `main` land. No KORGI Railway redeploy. - W3 in-app OpenAI Responses operator is not done. - W4 keep/guide/correct marks and Studio chrome restyle are not done. - Audio matrix (W5) and VP9/Opus export (W6) were not implemented here. - IndexedDB/OPFS remains a local replica. It is not the hosted document. - Unbound studio `tools/list` is still the full registry (69). Honest catalog is the **bound grant**. - Dest A2 Higgsfield stills are not approved art. PixelLab $0. No paid still run on this chip. - `dev-user` remains a local no-database convenience and still must not mint origin=`user` bindings. - Dockerfile still bakes `VITE_AUTH_ENABLED=false`; production process start throws rather than minting `dev-user`. This chip did not redeploy that image. --- Helios, Icarus, 2026-09-13.