Skip to content

feat(gastown): add in_review bead state, fix triage auth and scheduling guards#1028

Open
jrf0110 wants to merge 8 commits intomainfrom
895-in-review
Open

feat(gastown): add in_review bead state, fix triage auth and scheduling guards#1028
jrf0110 wants to merge 8 commits intomainfrom
895-in-review

Conversation

@jrf0110
Copy link
Contributor

@jrf0110 jrf0110 commented Mar 11, 2026

Summary

  • in_review bead state: Beads now transition from in_progress to in_review when a polecat calls gt_done, rather than going straight to closed. The refinery review then closes the bead on merge or returns it to in_progress for rework. Wired through all layers: DB schemas, Zod enums, SQL CHECK constraints, tRPC schemas, generated router.d.ts types, container plugin BeadStatus type, and mayor gt_list_beads tool.
  • Rework re-dispatch: On review failure or conflict, a polecat is assigned via getOrCreateAgent (not the original, which may already be busy) and dispatched to rework the bead automatically.
  • Triage handler 401 fix: handleResolveTriage returned 401 in development because authMiddleware is skipped and getEnforcedAgentId returned null. Fixed with an ENVIRONMENT === 'development'-gated fallback to the X-Gastown-Agent-Id header.
  • Scheduling guard: hookBead now rejects system-managed bead types (escalation, convoy, agent, message) and gt:triage-request beads, preventing polecats from accidentally being assigned to them.
  • Activity feed: Added triage_resolved bead event type with ShieldCheck icon (amber) so triage actions appear on affected beads' timelines. Updated triage system prompt to encourage gt_status calls for dashboard visibility.
  • Dashboard stats: in_review is now counted in healthCheck() pending beads, getAlarmStatus() bead counts (new inReview field), rig detail stats, town overview stats, and the TerminalBar status pane.
  • UI: BeadBoard has 4 columns (Open, In Progress, In Review, Closed) with responsive loading skeleton. Town overview stats strip uses 5 columns with inline grid-template-columns. Purple theming for In Review throughout.

Closes #895

Verification

  • pnpm typecheck passes across all 28 workspace projects
  • Rebase onto main — no conflicts
  • All 6 code review threads addressed and resolved

Visual Changes

Before After
BeadBoard: 3 columns (Open, In Progress, Closed) BeadBoard: 4 columns (Open, In Progress, In Review, Closed)
Rig stats: 3 cells Rig stats: 4 cells (added In Review, purple)
Town stats: 4 cells Town stats: 5 cells (added In Review with Eye icon)
TerminalBar beads: Open, In Progress, Failed, Triage TerminalBar beads: Open, In Progress, In Review, Failed, Triage
Activity feed: no triage events Activity feed: triage_resolved with ShieldCheck icon (amber)

Reviewer Notes

  • No data migration needed — cloud Gastown hasn't deployed to production.
  • The rework re-dispatch uses getOrCreateAgent to avoid stranding when the original polecat has moved on to other work.
  • The triage auth fallback is explicitly gated on ENVIRONMENT === 'development' — production always uses the verified JWT identity.
  • hookBead guard covers the HTTP API entry point (POST /agents/:agentId/hook) which was the only external vector for hooking agents to wrong bead types.

@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Mar 11, 2026

Code Review Summary

Status: 1 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
cloudflare-gastown/src/dos/Town.do.ts 765 Auto-redispatch runs for all failed reviews, including refinery and PR workflow failures that do not require source-bead rework
Other Observations (not in diff)

N/A

Files Reviewed (22 files)
  • cloudflare-gastown/container/plugin/mayor-tools.ts - 0 issues
  • cloudflare-gastown/container/plugin/types.ts - 0 issues
  • cloudflare-gastown/src/db/tables/bead-events.table.ts - 0 issues
  • cloudflare-gastown/src/db/tables/beads.table.ts - 0 issues
  • cloudflare-gastown/src/db/tables/rig-beads.table.ts - 0 issues
  • cloudflare-gastown/src/dos/Town.do.ts - 1 issue
  • cloudflare-gastown/src/dos/town/agents.ts - 0 issues
  • cloudflare-gastown/src/dos/town/review-queue.ts - 0 issues
  • cloudflare-gastown/src/handlers/rig-triage.handler.ts - 0 issues
  • cloudflare-gastown/src/prompts/mayor-system.prompt.ts - 0 issues
  • cloudflare-gastown/src/prompts/polecat-system.prompt.ts - 0 issues
  • cloudflare-gastown/src/prompts/triage-system.prompt.ts - 0 issues
  • cloudflare-gastown/src/trpc/router.ts - 0 issues
  • cloudflare-gastown/src/trpc/schemas.ts - 0 issues
  • cloudflare-gastown/src/types.ts - 0 issues
  • cloudflare-gastown/src/ui/dashboard.ui.ts - 0 issues
  • src/app/(app)/gastown/[townId]/TownOverviewPageClient.tsx - 0 issues
  • src/app/(app)/gastown/[townId]/rigs/[rigId]/RigDetailPageClient.tsx - 0 issues
  • src/components/gastown/ActivityFeed.tsx - 0 issues
  • src/components/gastown/BeadBoard.tsx - 0 issues
  • src/components/gastown/TerminalBar.tsx - 0 issues
  • src/lib/gastown/types/router.d.ts - 0 issues

Reviewed by gpt-5.4-20260305 · 5,691,131 tokens

jrf0110 added 8 commits March 11, 2026 16:04
Beads now transition to in_review when a polecat calls gt_done, rather
than going straight to closed. The refinery review then closes the bead
on merge or returns it to in_progress for rework. This prevents the bead
board from showing beads as done before the refinery has actioned them.

Changes:
- Add in_review to BeadStatus enum (schema + types)
- gt_done transitions source bead to in_review instead of closed
- Review failure/conflict returns bead to in_progress and re-dispatches
  the original polecat for rework
- Mayor and polecat prompts updated to reflect the new lifecycle
- BeadBoard UI adds In Review column with purple styling
- Dashboard badge styling for in_review state

Closes #895
The listBeads tRPC route was returning 500 (output validation failed)
because beads with in_review status didn't pass the output schema.
Add in_review to BeadOutput, the listBeads input filter, the rig-beads
table Zod enum + SQL CHECK constraint, and the generated router types.
…header

In development, authMiddleware is skipped so agentJWT is never set on
the Hono context. The triage handler used getEnforcedAgentId() as a
hard requirement (returning 401 on null), unlike other handlers which
treat it as optional. Fall back to the X-Gastown-Agent-Id header that
the container client sends with every request.
…age gt_status in triage prompt

Triage actions (RESTART, CLOSE_BEAD, ESCALATE, etc.) now emit a
triage_resolved bead event on the target bead, making them visible in
the activity feed. Previously only a status_changed event was logged on
the triage request bead itself, which doesn't appear in the affected
bead's timeline.

- Add triage_resolved to BeadEventType enum
- Log triage_resolved on the target bead in resolveTriage with action
  and resolution notes in metadata
- Add ShieldCheck icon (amber) and description formatting in ActivityFeed
- Update triage system prompt to instruct agents to call gt_status at
  the start and end of their batch for dashboard visibility
… beads

hookBead had no bead-type validation — any agent could be hooked to any
bead, including system-managed types like escalation, convoy, agent, and
message beads. Triage-request beads (type='issue' with gt:triage-request
label) were also unguarded, letting polecats accidentally pick them up.

Add two guards in hookBead:
- Reject beads with system-managed types (escalation, convoy, agent,
  message) since no agent should work on these directly
- Reject beads with the gt:triage-request label since those are resolved
  via gt_triage_resolve, not by hooking an agent
…anding, responsive layout

Address all four review comments and four code review observations:

- Wire in_review through container plugin types, mayor gt_list_beads
  tool, rig detail stats, town overview stats, healthCheck pending count,
  and getAlarmStatus bead counts
- Fix rework stranding: use getOrCreateAgent instead of re-hooking the
  original polecat (which may already be working on something else)
- Fix BeadBoard loading skeleton to use responsive grid-cols-1/sm:4
  matching the loaded layout
- Add In Review stat cell to both rig detail and town overview pages
Tailwind's grid-cols-5 was being purged or not applying correctly.
Use an inline style to guarantee the 5-column layout.
…gh alarm status

- Gate X-Gastown-Agent-Id header fallback in handleResolveTriage on
  ENVIRONMENT === 'development' to prevent header spoofing in production
- Add inReview to AlarmStatusOutput tRPC schema, router.d.ts types,
  and TerminalBar UI so the new bead count is visible in the status pane
@jrf0110 jrf0110 changed the title feat(gastown): add in_review bead state between in_progress and closed feat(gastown): add in_review bead state, fix triage auth and scheduling guards Mar 11, 2026
// returned to in_progress. Re-hook a polecat and re-dispatch so the
// rework starts automatically. The original polecat may already be
// working on something else, so fall back to getOrCreateAgent.
if ((input.status === 'failed' || input.status === 'conflict') && sourceBeadId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: failed reviews are not always source-bead rework

This block re-dispatches a polecat for every failed review, but completeReviewWithResult(..., { status: 'failed' }) is also used for refinery-side failures like an invalid pr_url and for PRs that were closed without merge. In those cases the source bead's code may already be correct, so auto-reopening it here can send a polecat back onto finished work and create duplicate review loops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In-Review Bead State — Beads Stay Open Until Refinery Actions

1 participant