feat(gastown): add in_review bead state, fix triage auth and scheduling guards#1028
Open
feat(gastown): add in_review bead state, fix triage auth and scheduling guards#1028
Conversation
Contributor
Code Review SummaryStatus: 1 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Other Observations (not in diff)N/A Files Reviewed (22 files)
Reviewed by gpt-5.4-20260305 · 5,691,131 tokens |
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
| // 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) { |
Contributor
There was a problem hiding this comment.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
in_reviewbead state: Beads now transition fromin_progresstoin_reviewwhen a polecat callsgt_done, rather than going straight toclosed. The refinery review then closes the bead on merge or returns it toin_progressfor rework. Wired through all layers: DB schemas, Zod enums, SQL CHECK constraints, tRPC schemas, generatedrouter.d.tstypes, container pluginBeadStatustype, and mayorgt_list_beadstool.getOrCreateAgent(not the original, which may already be busy) and dispatched to rework the bead automatically.handleResolveTriagereturned 401 in development becauseauthMiddlewareis skipped andgetEnforcedAgentIdreturned null. Fixed with anENVIRONMENT === 'development'-gated fallback to theX-Gastown-Agent-Idheader.hookBeadnow rejects system-managed bead types (escalation,convoy,agent,message) andgt:triage-requestbeads, preventing polecats from accidentally being assigned to them.triage_resolvedbead event type with ShieldCheck icon (amber) so triage actions appear on affected beads' timelines. Updated triage system prompt to encouragegt_statuscalls for dashboard visibility.in_reviewis now counted inhealthCheck()pending beads,getAlarmStatus()bead counts (newinReviewfield), rig detail stats, town overview stats, and the TerminalBar status pane.Closes #895
Verification
pnpm typecheckpasses across all 28 workspace projectsVisual Changes
Reviewer Notes
getOrCreateAgentto avoid stranding when the original polecat has moved on to other work.ENVIRONMENT === 'development'— production always uses the verified JWT identity.hookBeadguard covers the HTTP API entry point (POST /agents/:agentId/hook) which was the only external vector for hooking agents to wrong bead types.