Skip to content

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

Open
evanjacobson wants to merge 9 commits into
gastown-stagingfrom
improvement/gastown-admin-failure-reasons-staging
Open

feat(gastown): show admin bead failure reasons#3432
evanjacobson wants to merge 9 commits 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.

jrf0110 and others added 9 commits May 19, 2026 20:32
…rm (#3372)

Bug 1: @kilocode/cli@7.2.14 doesn't read KILO_AUTH_CONTENT, causing all
kilo serve session-ingest to silently no-op. Bumped to 7.3.1 which has the
feature. Verified KILO_AUTH_CONTENT present in binary strings.

Bug 2: buildPrewarmEnv didn't set KILO_AUTH_CONTENT, KILO_PLATFORM, or
KILO_ORG_ID, so mayor sessions (which go through prewarm) were invisible.
Extracted buildKiloAuthEnv helper from buildAgentEnv and used it in both
buildAgentEnv and buildPrewarmEnv.

Refs #3307

Co-authored-by: John Fawcett <john@kilcoode.ai>
* perf(gastown): shorten mayor cold start path

* fix(gastown): address mayor latency review feedback

* fix(gastown): remove stale mayor setup parameter

* fix(gastown): remove stale mayor setup comment
* feat(cloud-agent): add Gastown filter option to ChatSidebar and mobile modal

* fix(cloud-agent-next): remove stale comment in default branch handling

---------

Co-authored-by: John Fawcett <john@kilcoode.ai>
Make worktree creation tolerate an existing local branch with a missing worktree directory, and allow internal @kilocode package updates to bypass release-age delays.
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

@jrf0110 jrf0110 force-pushed the gastown-staging branch from 8e60feb to c52272a Compare May 28, 2026 16:08
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.

2 participants