Skip to content

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:

  1. Server edition requires WorkWingman:TenantStore:Provider=firestore — satisfiable.
  2. Deployment environment 'dev' resolves to the '(default)' Firestore database, which belongs to production — satisfiable, and a good guard (WING-219).
  3. 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-pro REQUIRES --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-central1 shows 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).