[triage-generated] [bug] Cycle retro records issue=null for all cycles despite active work #492

Closed
opened 2026-03-19 20:00:18 +00:00 by Timmy · 2 comments
Owner

Problem

The dev loop cycle retro (.loop/retro/cycles.jsonl) records issue=null and success=false for all recent cycles (521-539), yet the loop IS doing productive work:

  • 31 PRs merged in the measurement window
  • 4776 lines added
  • Issues filed, assigned, and closed

The disconnect: the cycle runner is not linking its work to queue items. When it picks up an issue, it does not record which issue it worked on. This causes:

  1. 0% measured success rate despite real progress
  2. Queue starvation detection fails (looks starved when it is not)
  3. Deep triage cannot evaluate which issue types succeed

Root cause hypothesis

The cycle runner picks issues from queue.json but does not write the issue number to the cycle retro entry. Or the queue items have stale/closed issue numbers so the runner falls through to ad-hoc work without recording it.

Acceptance criteria

  • Each cycle retro entry has a non-null issue field when work was done
  • success field accurately reflects whether the cycle achieved its goal
  • The summary.json success_rate reflects actual loop productivity

Files to investigate

  • .loop/ directory — the cycle runner script
  • .loop/retro/cycles.jsonl — output format
  • .loop/queue.json — input format

Impact

This is the #1 meta-issue for the dev loop. Without accurate metrics, triage is flying blind and the loop cannot self-improve.

## Problem The dev loop cycle retro (`.loop/retro/cycles.jsonl`) records `issue=null` and `success=false` for all recent cycles (521-539), yet the loop IS doing productive work: - 31 PRs merged in the measurement window - 4776 lines added - Issues filed, assigned, and closed The disconnect: the cycle runner is not linking its work to queue items. When it picks up an issue, it does not record which issue it worked on. This causes: 1. 0% measured success rate despite real progress 2. Queue starvation detection fails (looks starved when it is not) 3. Deep triage cannot evaluate which issue types succeed ## Root cause hypothesis The cycle runner picks issues from `queue.json` but does not write the issue number to the cycle retro entry. Or the queue items have stale/closed issue numbers so the runner falls through to ad-hoc work without recording it. ## Acceptance criteria - Each cycle retro entry has a non-null `issue` field when work was done - `success` field accurately reflects whether the cycle achieved its goal - The summary.json `success_rate` reflects actual loop productivity ## Files to investigate - `.loop/` directory — the cycle runner script - `.loop/retro/cycles.jsonl` — output format - `.loop/queue.json` — input format ## Impact This is the #1 meta-issue for the dev loop. Without accurate metrics, triage is flying blind and the loop cannot self-improve.
Author
Owner

Root Cause Found

The log_retro() function in ~/hermes-config/bin/timmy-loop.sh (lines ~162-175) calls cycle_retro.py but only passes:

  • --cycle N
  • --success or --failure
  • --duration SECONDS
  • --reason "..." (on failure)

It does NOT pass:

  • --issue (which issue was worked on)
  • --tests-passed (test count)
  • --lines-added / --lines-removed (diff stats)
  • --files-changed
  • --pr (PR number if merged)
  • --main-green (smoke test result)
  • --type (bug/feature/refactor)

All of these default to null/0 in cycle_retro.py, which is why every cycle entry shows issue=null, success=false (success requires --main-green), and tests_passed=0.

Fix

The log_retro() function needs to extract metadata after the cycle completes:

  1. Read state.json to get the current issue number from the cycle
  2. Parse git diff --stat on main to get lines/files changed
  3. Run tox -e unit count or parse last test output for test count
  4. Check if a PR was merged this cycle
  5. Run a smoke test and pass --main-green if it passes

This is an infrastructure fix in timmy-loop.sh, not a codebase change.

## Root Cause Found The `log_retro()` function in `~/hermes-config/bin/timmy-loop.sh` (lines ~162-175) calls `cycle_retro.py` but only passes: - `--cycle N` - `--success` or `--failure` - `--duration SECONDS` - `--reason "..."` (on failure) It does NOT pass: - `--issue` (which issue was worked on) - `--tests-passed` (test count) - `--lines-added` / `--lines-removed` (diff stats) - `--files-changed` - `--pr` (PR number if merged) - `--main-green` (smoke test result) - `--type` (bug/feature/refactor) All of these default to null/0 in `cycle_retro.py`, which is why every cycle entry shows `issue=null`, `success=false` (success requires `--main-green`), and `tests_passed=0`. ## Fix The `log_retro()` function needs to extract metadata after the cycle completes: 1. Read `state.json` to get the current issue number from the cycle 2. Parse `git diff --stat` on main to get lines/files changed 3. Run `tox -e unit` count or parse last test output for test count 4. Check if a PR was merged this cycle 5. Run a smoke test and pass `--main-green` if it passes This is an infrastructure fix in `timmy-loop.sh`, not a codebase change.
Author
Owner

Root Cause Found

The loop runner (~/.hermes/bin/timmy-loop.sh) calls log_retro success with zero data arguments.

The log_retro function correctly passes --cycle and --duration, but there is no mechanism for hermes to communicate back what issue it worked on, type, tests, files, PR number, etc.

The gap: hermes runs as a subprocess and never writes structured output. So cycle_retro.py gets called without --issue, --type, --pr, etc. — all fields default to null/0.

Fix: Cycle Result File

  1. Hermes writes .loop/cycle_result.json at end of each cycle
  2. timmy-loop.sh reads it in log_retro() and passes contents as args
  3. This is a loop infrastructure fix (timmy-loop.sh + loop prompt), not repo code
## Root Cause Found The loop runner (`~/.hermes/bin/timmy-loop.sh`) calls `log_retro success` with zero data arguments. The `log_retro` function correctly passes `--cycle` and `--duration`, but there is no mechanism for hermes to communicate back what issue it worked on, type, tests, files, PR number, etc. The gap: hermes runs as a subprocess and never writes structured output. So `cycle_retro.py` gets called without `--issue`, `--type`, `--pr`, etc. — all fields default to null/0. ## Fix: Cycle Result File 1. Hermes writes `.loop/cycle_result.json` at end of each cycle 2. `timmy-loop.sh` reads it in `log_retro()` and passes contents as args 3. This is a loop infrastructure fix (timmy-loop.sh + loop prompt), not repo code
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Rockachopa/Timmy-time-dashboard#492