Product Owner
Product Owner and Deploy-flow review delegator. Refines tickets, sets po_size, confirms product-acceptance, then selects the two senior reviewers (domain fit + a logged random tiebreak; 1 heavy + 1 light). Owns the ship gate — full e2e on the frozen ship SHA, then the operator gate before prod.
No skills assigned.
Backfill pokemon mascots
DevOps scout run control and dashboard
DevOps scout launcher
Add release notes API
DevOps scout decision summary
DevOps scout report intake
DevOps scout review packets
DevOps batch review planner
DevOps queue snapshot command
DevOps test lanes and fresh-session workflow v1
Investigate QA navbar regressions across Studio and Turf
Add task conversation feedback
Clarify task-board DevOps handoff contract
Ship Turf Monster sidebar back-navigation fix
Ship McRitchie Studio sidebar back-navigation fix
Require task-board items for feature handoff
QA verdict: BLOCK (CI red). Core fix in bin/agent-worktree is CORRECT — verified the boundary math: the longest minted identifier (the _development_ name) lands at exactly 63 (never 64) for both mcritchie-studio and the shorter turf-monster prefix (max_len = 63 - prefix.length); fitting slugs pass through byte-for-byte (no churn); long slugs get a deterministic 8-hex SHA256 suffix; distinct long slugs sharing a 25-char prefix do NOT collide; dev/test share an identical base so db:test:prepare resolves. The 3 unit tests PASSED on CI. The block is ONE broken test, not the fix. DEFECT: the new [integration] 'db:test:prepare provisions a findable long-slug test DB' (test/commands/agent_worktree_test.rb ~L531-553) hardcodes credential-less connection strings — DATABASE_URL/TEST_DATABASE_URL = 'postgresql://localhost/<db>' and bare psql/dropdb with psql_env={PATH only}. On CI Postgres requires a password (CI sets DATABASE_URL=***localhost:5432), so the subprocess dies with 'fe_sendauth: no password supplied' BEFORE exercising the fix → 1 failure / 1565 runs (run 28146111302). It passes locally on trust-auth PG, which masked the gap. FIX: derive host/port/user/password from the CI-provided ENV['DATABASE_URL'] (URI.parse, swap only the database-name path segment) for both the db:test:prepare child env AND the trailing psql/dropdb (pass PGHOST/PGPORT/PGUSER/PGPASSWORD or a full conninfo) — or skip when ENV['DATABASE_URL'] is blank, but prefer deriving so the regression actually runs on CI. Re-run until the test job is green. Also update the stale claim — PR body + devops.checks_run say '[suite] ... 31 runs green' / 'CI green', but CI is red; correct that on resubmit. No rebase needed: branch is 0 behind origin/release with a clean merge-tree. PR left as DRAFT.
Post-merge review sign-off (cascade finished after the parallel conductor merged this): carl[heavy] APPROVE (ensure-adopt half-state guard proven red-before-fix via source mutation; preflight catches wrong-branch AND dirty-tree; overlap planner degrades gracefully), jasper[light] APPROVE. Non-blocking fast-follow: ship preflight is too strict on UNTRACKED files — git status --porcelain counts ?? entries, so the untracked retro-rel-*.md on the primary checkout would abort the NEXT ship even though --ff-only is safe with non-colliding untracked files. Exclude untracked (or downgrade untracked-only to a warning; keep tracked-modified + wrong-branch as hard aborts); fix-text should say 'stash -u'/'git clean'.
Post-merge review sign-off (cascade finished after the parallel conductor had already merged this onto rel-20260624-6f6638): carl[heavy] APPROVE (full regex probe — BARE_SEED_TASK has no hole; lookbehind/lookahead kill mydb:seed/db:seed_fund), shannon[light] APPROVE. Non-blocking follow-ups: (1) exempt-kind + zero-diff task hits exit 0 before the gate — move the post_deploy check ABOVE the exempt early-exit to close it; (2) db:setup/db:reset/db:prepare also seed but are out of this task's scope.
Review cascade (my session): steffon[heavy] APPROVE — built_by precedence correct (actor-soul>keep-existing>agent_slug, UUIDs rejected), busy exclusion sound (--busy + --busy-auto rescues SystemExit+StandardError), starve guard mathematically correct (never below MIN_CANDIDATES), seed reproducibility byte-for-byte (excluded_busy folds in only when non-empty). alex[light] APPROVE — docs accurate, no stale --builder-by-hand wording. 2/2 APPROVE, CI green, MERGEABLE. READY TO MERGE — no re-review needed. HELD per operator: parallel conductor (rel-20260624-6f6638) owns the merge/deploy lane.
Block resolved (9d262fb): color: mascot.signature_color added to all 4 MascotAgent.new sites (271 stage_timeline + 162 + the 2 already-correct), so the consolidated timeline mascot matches the build board. Regression test RED->GREEN (name-palette #3B82F6 -> signature #6F35FC); target suites 133 runs 0F. dor-check ✓. carl[deep] APPROVE stands. Merge-gated on CI test green.
shannon[heavy]: acceptance #7 partial miss — stage_agents_helper.rb:271 (stage_timeline) builds MascotAgent without color:, so the mascot on the /tasks/:id consolidated timeline shows the name-palette color while the build board shows the type (signature) color — same mascot, two colors. REQUIRED: add color: mascot.signature_color at line 271 (and line 162 for consistency; harmless there but align). Add a regression test asserting the consolidated-timeline mascot avatar carries the type color (mirror the build-board test). Non-blocking (defer): text-white low-contrast on light type colors (Electric/Ice/Steel/Fairy/Flying). Everything else approved.
Review cascade: carl[deep] APPROVE (gem 0.9.0 lock clean, migration matches engine reference, model sound, turf unaffected, seed correctly narrow via enumerals:seed); shannon[heavy/UI] BLOCK.
Review cascade: shannon[heavy] APPROVE (all 4 criteria met, clean revert of #163's crew-demotion bits while keeping operator-wanted gem/label/chip changes, no dead :strip/2xs/STRIP_CAP, theme+mobile parity improved via alpha mask-image) + carl[light] APPROVE (scope contained, dead-code cleanup complete, CI green). Non-blocking: stale :stack flex-wrap docstring (now grid). CI green.
Rework verified (7c270b03): board_mascot rewritten to read via subprocess (`task field <slug> mascot 2>/dev/null`, shellescaped) mirroring resolve_mascot — SystemExit from a non-2xx board read is now contained in the child, can never abort bin/task. + board-fallback regression test (fail_get knob → non-2xx → asserts exit 0 + marker written + no mascot). RED->GREEN (1 fail → 32/115 + 6/9). dor-check ✓. carl[heavy] block resolved; shannon[light] had approved. Merge-gated on CI test green.
Block resolved (cd3848b): bin/reviewer-select:13 stale ref alex-docs->alex (verified, comment-only). carl[light] APPROVE + alex-docs[heavy] block addressed. dor-check ✓. Merge-gated on CI test green.
Review cascade: shannon[heavy] APPROVE (migration safe/reversible/indexed, duration-spine protected, no N+1, ui+db coverage complete) + carl[light] APPROVE. Non-blocking nits deferred (kind filters in reviewer_selector/retro). CI green.
Review cascade: shannon[heavy] APPROVE (ranking deterministic, filter correct, no N+1, no traps, ui+db coverage complete) + carl[light] APPROVE. Non-blocking nits deferred (id-tiebreak, board_apps scoping). CI green.
Review cascade: shannon[heavy] APPROVE (all 4 criteria met in markup, no logic regression, no ERB/Alpine traps, theme+mobile parity) + alex-docs[light] APPROVE. Non-blocking nits deferred (dead :stack branch, STRIP_CAP comment). CI green.
Review: carl[light] APPROVE (migration reversible/idempotent, no broken refs); alex-docs[heavy] BLOCK on one stale ref — bin/reviewer-select:13 still says 'alex-docs=Documentation'. Fixing in-place (comment-only).
carl[heavy]: board_mascot calls api(:get) in-process; on a non-2xx board read api->die!->exit 1 raises SystemExit, which is NOT StandardError, so it escapes board_mascot's rescue AND write_feature_marker's rescue — aborting the whole bin/task move/create with exit 1 AFTER the server op succeeded (false failure; churn under the rate-limit epic). REQUIRED: make board_mascot incapable of terminating the process — mirror bin/agent-worktree resolve_mascot (shell out: `bin/task field <slug> mascot 2>/dev/null` in a subprocess) OR rescue SystemExit/Exception->nil around the api call. ADD an integration test: board-fallback path returns non-2xx -> command still exits 0 AND writes the marker. (Also: checks_run says unit(7); actual 6 tests/9 assertions.)
Review cascade: shannon[light] APPROVE; carl[heavy] BLOCK.
Excluded from rel (2026-06-24 QA release). CI fully red: Gemfile requires studio-engine (~> 0.9) but Gemfile.lock still pins 0.8.0, and frozen/deployment bundle refuses to update because studio-engine 0.9.0 (the Enumeral gem) is not published to RubyGems. Ordering: publish studio-engine 0.9.0 (eng#8) first, then bundle update studio-engine in mcr#157 to relock 0.9.0, push, confirm CI green + un-draft. Then resubmit.
Review cascade: carl[heavy] APPROVE — no residual fail-open (full gate set verified: contests/entries/wallets/cdp all route through geo_blocked?), blank-US branch reachable, no over-blocking (CO + non-US pass), kill-switch intact, current is find_or_initialize_by so no stale-read. shannon[light] APPROVE — kill-switch holds, CO positive control real, scope tight. Non-blocking nits (deferred): reorder geo_blocked? cheap-checks before enforcing? DB hit; add non-US+blank test.
alex-docs BLOCK resolved by rework (commit 195c71f): release.rb comment reworded to label the txn wrapper as defense-in-depth vs a distinct never-observed mode (verified on PR head); + elsif clarifying comment + no-op-without-reopen regression test. shannon[heavy] had APPROVEd the logic. Review satisfied; merge gated on CI test job green + PR marked ready.
Review cascade: shannon[heavy] APPROVE — reconcile breadth (!= assembled) is CORRECT, do not tighten (tightening makes adopt! inconsistent: new blocked task raises, existing blocked member silently no-ops); atomicity/idempotency/tests sound. alex-docs[light] BLOCK — release.rb 'Atomic:' comment misattributes the incident half-state to the txn wrapper (incident is fixed by adopt! reconciliation; the txn guards a distinct never-observed mode). Rework: comment fix + elsif clarifying comment + no-op-without-reopen regression test.
We emailed a one-tap sign-in link to . It expires shortly and can only be used once.
No email? Check spam, or close this and try again.