Skip to content

feat(gastown): show admin bead failure reasons#3432

Open
evanjacobson wants to merge 1 commit into
gastown-stagingfrom
improvement/gastown-admin-failure-reasons-staging
Open

feat(gastown): show admin bead failure reasons#3432
evanjacobson wants to merge 1 commit into
gastown-stagingfrom
improvement/gastown-admin-failure-reasons-staging

Conversation

@evanjacobson
Copy link
Copy Markdown
Contributor

Summary

Failed Gastown beads previously gave admins little actionable context, especially after later audit events could bury the original failure metadata. This adds failure-reason plumbing from the Town DO through the admin tRPC/UI surfaces so admins can see the recorded failure message, code, source, and details directly in bead lists and inspectors.

Implementation notes
  • Follows the existing Town DO RPC pattern by adding failure-reason-aware bead getters alongside the existing bead list/get methods.
  • Keeps response validation aligned with existing Zod output schemas and admin router parsing.
  • Preserves failure reason lookup even when later field-update events are appended after the failed transition.

Verification

No separate manual browser verification was performed; this change was validated with targeted API/DO regression coverage.

Visual Changes

Admin bead list and inspector now show failure-reason fields for failed beads. Screenshots were not captured.

Reviewer Notes

Focus areas: the failure reason is reconstructed from the latest failed status-change event metadata rather than persisted on the bead row, matching the existing event-audit model and avoiding a schema change.

sql: SqlStorage,
filter: BeadFilter
): BeadWithFailureReason[] {
return listBeads(sql, filter).map(bead => attachFailureReason(sql, bead));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: N+1 query pattern — one extra SQL query per bead

listBeadsWithFailureReasons calls attachFailureReason for every bead, and attachFailureReason calls failureReasonForBead which issues its own SQL query (SELECT metadata FROM bead_events WHERE bead_id = ? AND event_type = 'status_changed' AND new_value = 'failed' LIMIT 1). With the default limit of 200 beads, this results in up to 201 SQL queries for a single adminListBeads call.

This is a Durable Object SQLite context so the queries are local/in-process, but it still generates significant per-bead overhead. Consider a single bulk query joining beads with bead_events filtered to the latest failed status-change event per bead, using MAX(created_at) or a window function, to fetch all failure reasons in one pass.

@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented May 22, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The listBeadsWithFailureReasons function issues one extra SQL query per bead, creating an N+1 query pattern on the admin bead list endpoint.

Overview

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

WARNING

File Line Issue
services/gastown/src/dos/town/beads.ts 324 N+1 query pattern: up to 201 SQL queries per adminListBeads call (one per bead for failure reason lookup)
Other Observations (not in diff)

adminForceFailBead in services/gastown/src/trpc/router.ts (lines 1839–1847): updateBeadStatus is a silent no-op when the bead is already in a terminal state (closed or failed). If an admin calls this on an already-closed bead, no error is returned — the closed bead is fetched and returned with its existing closed status, which passes the RpcBeadOutput schema. Callers receive a valid-looking response without knowing the force-fail was a no-op. Consider whether the mutation should raise a PRECONDITION_FAILED TRPCError when the bead is not in a transitionable state.

Files Reviewed (7 files)
  • services/gastown/src/dos/town/beads.ts — 1 issue
  • services/gastown/src/dos/Town.do.ts
  • services/gastown/src/trpc/router.ts
  • services/gastown/src/trpc/schemas.ts
  • apps/web/src/routers/admin/gastown-router.ts
  • apps/web/src/app/admin/gastown/towns/[townId]/BeadsTab.tsx
  • apps/web/src/app/admin/gastown/towns/[townId]/beads/[beadId]/BeadInspectorDashboard.tsx
  • services/gastown/test/integration/rig-do.test.ts

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-4.6 · 634,278 tokens

Review guidance: REVIEW.md from base branch gastown-staging

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.

1 participant