Retro council review — demo-integration landing (2026-08-05/06)¶
Written by WT-0f7d (Clahadore). Legend: Clahadore = Claude, Cedric = Codex, Jenny = Gemini, Gronktayvius = Grok.
Why this review exists¶
The 2026-08-05 demo integration landed to master under a deadline. Its constituent branches (WING-316, 322, 323, …) were each council-gated on their own branch, but three things were not: the merge-resolution commits themselves, a one-file persona-picker change that rode in on a merge, and the build-config edits made while chasing image builds. This is the retroactive pass over that remainder, plus the gate on the follow-up work it produced.
Seats¶
| Seat | Status | Note |
|---|---|---|
| Cedric (gpt-5.6-sol, high) | seated | found the highest-value defect (below) |
| Jenny (gemini-3.1-pro, high) | seated | required --effort high; see gotcha |
| Gronktayvius (Grok) | seated | correctly called the local-cloud runner dead on arrival |
| Clahadore (Opus) | not seated | advisory-only anyway (Claude authored); first attempt died at the 02:45 budget cut |
Three independent seats survived, so the gate stands. An earlier attempt produced two 0-byte seat outputs at the usage-window cut — recorded as FAILED seats, never as "no findings".
Findings and dispositions¶
| # | Seat | Severity | Finding | Disposition |
|---|---|---|---|---|
| 1 | Cedric | P1 | Picker failure path asserted "the demo workspace is still active". Desktop switches the world back to real in a finally even when the reset throws (DemoPersonaController.cs), so the toast could contradict reality. |
FIXED — re-reads world state, copy asserts neither outcome |
| 2 | Jenny | Medium | A synchronous throw from resetDemo() skipped .pipe(), so finalize never ran and loadBusy stuck true — card permanently disabled, no toast, no retry. |
FIXED — wrapped in defer() |
| 3 | Cedric | P1 | --ignore-file REPLACES the default ignore chain and never reads .gitignore, so .env / *.local.json / key material would ride into the Cloud Build source archive. |
FIXED — patterns added to .gcloudignore.app |
| 4 | Gronktayvius | High | Run-CloudLocally.ps1 could not boot at all; its comments overclaimed isolation. |
CONFIRMED by running it — see below |
| 5 | Gronktayvius | Medium | Build script tagged a dirty tree with HEAD's sha — a lying provenance label. | FIXED — fails closed, -Force to override |
| 6 | Gronktayvius | Low | Build script did not pin --project or check the ignore file exists. |
FIXED |
| 7 | Jenny | High | Runner published -p 8080:8080 (all interfaces) on a container with auth guards relaxed, while printing a reassuring 127.0.0.1 URL. |
FIXED — binds 127.0.0.1 explicitly |
The blocker: local server-edition verification is not possible today¶
Run-CloudLocally.ps1 exists to run the REAL cloud image locally so server-edition behaviour
(capability gates, tenant auth, edition guards) can be exercised without touching prod. Three
startup guards refused it in sequence. Verified by running image 406ff0217 — what prod serves:
Server edition requires WorkWingman:TenantStore:Provider=firestore— satisfiable.Deployment environment 'dev' resolves to the '(default)' Firestore database, which belongs to production— satisfiable, and a good guard (WING-219).Server edition refuses the Firestore emulator.— not satisfiable from a script.
Guard 3 has no explanatory comment, unlike guard 2. Its evident purpose is that no DEPLOYED server may run against an emulator. That purpose is worth keeping.
Decision needed (Andrew + council — security-adjacent startup guard, not a unilateral edit):
allow the emulator only when the deployment environment is dev AND an explicit opt-in such as
WorkWingman:TenantStore:AllowEmulator=true is set. No deployed rung is dev and none would set
the opt-in, so the guard's purpose survives intact.
Why this is worth a decision rather than a shrug: reaching an authenticated cloud surface on a deployed rung requires redeeming an invitation code — credential entry into a live surface, which an agent must always refuse. WT-8bd8 hit exactly this on WING-416 and correctly refused. Without a credential-free local server edition, "verify this cloud screen actually renders" is not a task any agent can complete; it always costs a human. That is the WING-305 failure class (97/97 green, two self-reviews passed, feature 100% unreachable) left permanently un-closeable by automation.
Validation¶
| Command | Exit | Evidence |
|---|---|---|
npx vitest run src/app/features/onboarding/demo-persona-picker |
0 | Test Files 1 passed, Tests 12 passed |
PowerShell ParseFile on both ops scripts |
0 | both parses OK |
ops/cloud-run/build-app-image.ps1 (dirty tree) |
1 | refused: Working tree has 5 uncommitted change(s); the image would be tagged 96d0ee7b5 while containing something else — the guard working |
Run-CloudLocally.ps1 -Sha 406ff0217 |
1 | container exit 139: Server edition refuses the Firestore emulator. |
Verdict: passed for the picker fix and the build tooling; BLOCKED for the local-cloud runner, which lands labelled as blocked rather than as a working tool.
Gotchas worth carrying¶
- agy
--effort:gemini-3.1-proREQUIRES--effort high; without it the seat exits 1 with an empty stdout. The council skill's note ("do NOT pass--effort") is inverted for this model. A 0-byte seat is a FAILED seat, never a clean pass. - Cloud Build is GLOBAL, not regional.
gcloud builds list --region us-central1shows nothing and makes a healthy build look lost. A build that has not appeared yet may still be uploading — check before resubmitting. - Verify at the served asset, not the revision. A revision can be Ready, on the right digest, and still not be what a user receives (cache/LB/ingress). Fetching and grepping the served bundle spans all of those at once. Adopted as the deploy receipt (WT-8bd8's method).