feat: triage agent — deep root cause analysis for reproduced bugs #258

Closed
opened 2026-04-05 20:15:02 +00:00 by dev-bot · 1 comment
Collaborator

What

A triage agent that picks up reproduced bugs where the reproduce-agent could not find an obvious cause. It runs in the same sidecar container as the reproduce-agent (same Docker/Playwright capabilities) but with a different formula focused on deep investigation.

Design decisions (resolved)

Question Decision
Time budget No hard limit — run until Claude hits its turn limit. Complex bugs (like #1193 with 3 compounding causes) need room to investigate
Modify code Yes, on a throwaway branch — can add console.log, change log levels, restart services. Branch deleted after triage
Stack lock Hold for the full run — triage is rare enough that blocking CI/other agents is acceptable
Label update on completion Both — update original to bug-report + in-progress AND create backlog sub-issues for each root cause

Trigger

bug-report + in-triage label combination, set by the reproduce-agent when:

  • Bug was confirmed (reproduced)
  • Quick log analysis did not reveal an obvious root cause
  • Reproduce-agent documented all steps taken and logs examined

What it does

  1. Read context — the reproduce-agent already posted: reproduction steps, screenshots, logs examined, observations. Start from there, do not repeat work.
  2. Deep trace — follow the data flow from symptom to source:
    • UI component → composable → API/GraphQL → indexer → chain
    • Compare what the code expects vs what APIs actually return
    • Create a throwaway branch, add debug instrumentation (console.log, verbose logging)
    • Restart services, re-run reproduction, observe new output
    • Delete throwaway branch when done
  3. Decompose — identify all root causes (may be 1 or multiple compounding):
    • For each root cause, create a separate backlog issue with:
      • Which cause it is (1 of N)
      • Specific code path and fix suggestion
      • Depends-on: #X if causes are layered
  4. Link back — update the original bug issue:
    • Post summary: "Found N root causes, tracked as #X, #Y, #Z"
    • Replace in-triage with in-progress on the original issue
    • Dev-agent picks up the backlog sub-issues

Example: codeberg#1193 (stats zero)

Reproduce-agent confirmed: stats show zero, logs clean → labeled bug-report + in-triage

Triage agent:

  1. Reads reproduce findings — zeros confirmed, no errors in logs
  2. Queries GraphQL API, sees holderCount=2 but everything else zero
  3. Checks ponder config, finds LM_ADDRESS missing from .env.local
  4. Creates throwaway branch, adds logging to ponder event handlers
  5. Restarts ponder, sees LM events are never triggered
  6. Cast calls the actual LM address, finds 5 events on chain
  7. Checks POOL_ADDRESS — hardcoded to wrong address
  8. Finds ring buffer threshold skips early events
  9. Deletes throwaway branch
  10. Files 3 backlog issues:
    • #A: bootstrap missing LM_ADDRESS in ponder env
    • #B: POOL_ADDRESS hardcoded to Base Sepolia address
    • #C: ring buffer threshold too high for local dev
  11. Updates original: "Found 3 root causes: #A, #B, #C" → bug-report + in-progress

Architecture

Dispatcher (60s poll) sees `bug-report` + `in-triage`
  → Starts sidecar: docker run disinto-reproduce:latest (same image)
  → Acquires stack lock (holds for full run)
  → Reads reproduce-agent findings from issue comments
  → Creates throwaway branch for debug instrumentation
  → Deep investigation: trace data flow, add logging, restart, observe
  → Decomposes root causes into separate backlog issues
  → Deletes throwaway branch
  → Updates original issue: summary + `bug-report` + `in-progress`
  → Releases stack lock

Dependencies

  • #256 — reproduce sidecar container (same image, different formula)
  • #255 — stack lock protocol
  • #319in-triage label
  • #320 — reproduce formula reframe (defines the handoff contract)

Files

  • New: formulas/triage.toml — triage formula with investigation steps
  • Modify: docker/edge/dispatcher.sh — dispatch on bug-report + in-triage combo
## What A triage agent that picks up reproduced bugs where the reproduce-agent could not find an obvious cause. It runs in the same sidecar container as the reproduce-agent (same Docker/Playwright capabilities) but with a different formula focused on deep investigation. ## Design decisions (resolved) | Question | Decision | |----------|----------| | Time budget | **No hard limit** — run until Claude hits its turn limit. Complex bugs (like #1193 with 3 compounding causes) need room to investigate | | Modify code | **Yes, on a throwaway branch** — can add console.log, change log levels, restart services. Branch deleted after triage | | Stack lock | **Hold for the full run** — triage is rare enough that blocking CI/other agents is acceptable | | Label update on completion | **Both** — update original to `bug-report` + `in-progress` AND create backlog sub-issues for each root cause | ## Trigger `bug-report` + `in-triage` label combination, set by the reproduce-agent when: - Bug was confirmed (reproduced) - Quick log analysis did not reveal an obvious root cause - Reproduce-agent documented all steps taken and logs examined ## What it does 1. **Read context** — the reproduce-agent already posted: reproduction steps, screenshots, logs examined, observations. Start from there, do not repeat work. 2. **Deep trace** — follow the data flow from symptom to source: - UI component → composable → API/GraphQL → indexer → chain - Compare what the code expects vs what APIs actually return - Create a throwaway branch, add debug instrumentation (console.log, verbose logging) - Restart services, re-run reproduction, observe new output - Delete throwaway branch when done 3. **Decompose** — identify all root causes (may be 1 or multiple compounding): - For each root cause, create a separate `backlog` issue with: - Which cause it is (1 of N) - Specific code path and fix suggestion - `Depends-on: #X` if causes are layered 4. **Link back** — update the original bug issue: - Post summary: "Found N root causes, tracked as #X, #Y, #Z" - Replace `in-triage` with `in-progress` on the original issue - Dev-agent picks up the backlog sub-issues ## Example: codeberg#1193 (stats zero) Reproduce-agent confirmed: stats show zero, logs clean → labeled `bug-report` + `in-triage` Triage agent: 1. Reads reproduce findings — zeros confirmed, no errors in logs 2. Queries GraphQL API, sees holderCount=2 but everything else zero 3. Checks ponder config, finds LM_ADDRESS missing from .env.local 4. Creates throwaway branch, adds logging to ponder event handlers 5. Restarts ponder, sees LM events are never triggered 6. Cast calls the actual LM address, finds 5 events on chain 7. Checks POOL_ADDRESS — hardcoded to wrong address 8. Finds ring buffer threshold skips early events 9. Deletes throwaway branch 10. Files 3 backlog issues: - #A: bootstrap missing LM_ADDRESS in ponder env - #B: POOL_ADDRESS hardcoded to Base Sepolia address - #C: ring buffer threshold too high for local dev 11. Updates original: "Found 3 root causes: #A, #B, #C" → `bug-report` + `in-progress` ## Architecture ``` Dispatcher (60s poll) sees `bug-report` + `in-triage` → Starts sidecar: docker run disinto-reproduce:latest (same image) → Acquires stack lock (holds for full run) → Reads reproduce-agent findings from issue comments → Creates throwaway branch for debug instrumentation → Deep investigation: trace data flow, add logging, restart, observe → Decomposes root causes into separate backlog issues → Deletes throwaway branch → Updates original issue: summary + `bug-report` + `in-progress` → Releases stack lock ``` ## Dependencies - #256 — reproduce sidecar container (same image, different formula) - #255 — stack lock protocol - #319 — `in-triage` label - #320 — reproduce formula reframe (defines the handoff contract) ## Files - New: `formulas/triage.toml` — triage formula with investigation steps - Modify: `docker/edge/dispatcher.sh` — dispatch on `bug-report` + `in-triage` combo
dev-bot added the
vision
label 2026-04-05 20:15:02 +00:00
dev-bot added
backlog
and removed
vision
labels 2026-04-07 08:03:47 +00:00
dev-bot self-assigned this 2026-04-07 08:04:02 +00:00
dev-bot added
in-progress
and removed
backlog
labels 2026-04-07 08:04:02 +00:00
dev-qwen added
blocked
and removed
in-progress
labels 2026-04-07 08:04:07 +00:00
Collaborator

Stale in-progress issue detected

Field Value
Detection reason no_active_session_no_open_pr
Timestamp 2026-04-07T08:04:08Z

Status: This issue was labeled in-progress but no active tmux session exists.
Action required: A maintainer should triage this issue.

### Stale in-progress issue detected | Field | Value | |---|---| | Detection reason | `no_active_session_no_open_pr` | | Timestamp | `2026-04-07T08:04:08Z` | **Status:** This issue was labeled `in-progress` but no active tmux session exists. **Action required:** A maintainer should triage this issue.
dev-bot removed their assignment 2026-04-07 08:19:03 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: disinto-admin/disinto#258
No description provided.