garrytan / garrytan/gstack

/retro silently produces empty/misleading output when 'today' anchor is wrong (no stale-base warning)

Open
#1,624 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
133k
Forks
19.9k
Avg merge
18h 46m
Merged PRs (30d)
26

Description

## Failure mode

When `/retro` runs on a worktree-style setup (Conductor, etc.) and the agent's understanding of "today" is off by enough days, the skill silently produces a clean-looking retro that misses recent reality. The `git log --since=""` window quietly returns zero or near-zero commits, but nothing in the output flags that the window is wrong.

Both inputs to the window can be wrong:
1. **"today" anchor drift** — the agent computes `today` from session-context cues that don't match the actual system date (model error, session-reminder mismatch, etc.).
2. **Stale worktree base** — the Conductor/`claude/...` branch is days/weeks behind `origin/`, and although the skill does `git fetch origin --quiet`, nothing surfaces that the latest commit is materially older than "today" would suggest.

Either way, the retro renders successfully, the metrics table looks legitimate, and the user gets a confidently-wrong report.

## Reproducer

I hit this on a real project today:
- `today` per system date: 2026-05-20
- Agent computed `today` (incorrectly): 2026-05-15
- `/retro` (default 7d): analyzed `--since="2026-05-08T00:00:00"`, returned 18 commits (all from May 8-11), missed 4 commits on `origin/main` from May 19-20 including the latest version bump
- Output: a clean retro narrative ending "Streak: 0d (4-day burst May 8-11)" — looks coherent, completely missed v0.21.0 → v0.22.0 work that had already shipped

The user caught it only when version-bumping for the next PR: "version number is way old."

## Why it's silent

`Step 1: Gather Raw Data` runs `git fetch origin --quiet` and then immediately starts gathering commits via `git log origin/ --since=""`. There's no sanity-check on the gap between "today" and `origin/`'s latest commit. If the gap exceeds the window length, the window is empty — but the retro keeps going and the model fills in narrative from whatever (possibly zero) commits it found.

## Suggested fix (sketch)

Inject a stale-base sanity check right after the fetch, before the data-gathering. Always echo the latest commit date + gap so the agent has the data point; escalate to an explicit warning when the gap is suspect:

```bash
git fetch origin --quiet

_LATEST_COMMIT_TS=$(git log origin/ -1 --format="%at" 2>/dev/null || echo 0)
_LATEST_COMMIT_DATE=$(git log origin/ -1 --format="%ad" --date=short 2>/dev/null || echo unknown)
_GAP_DAYS=$(( ($(date +%s) - _LATEST_COMMIT_TS) / 86400 ))
echo "ORIGIN__LATEST: $_LATEST_COMMIT_DATE (${_GAP_DAYS}d before today)"
if [ "$_GAP_DAYS" -gt 3 ]; then
echo "⚠ STALE-BASE WARNING: latest commit is ${_GAP_DAYS} days before today."
echo " If your window is shorter than ${_GAP_DAYS}d, the retro will contain few or zero commits."
echo " Sanity-check the 'today' anchor against the actual system date before proceeding —"
echo " a clean-looking retro on the wrong window silently misses recent reality."
fi
```

Plus a prose follow-up after the bash block: *"If the stale-base warning fires: confirm that `today` matches the system date, and that `origin/` actually has the recent activity you expect. If the gap exceeds the window length, the retro will report empty or near-empty results — that's evidence the anchor or fetch is wrong, not that the team didn't ship."*

Always echoing the data point (even when no warning fires) gives the agent a fact to cross-check against. The 3-day threshold is comfortably above typical weekly cadence (so weekend gaps don't false-positive) but low enough to catch the 9-day case I hit. The threshold is debatable — could be window-aware (e.g., `gap > window_days`) if the skill exposes the parsed window length as a bash var.

## Why I'm filing an issue instead of a PR

I have a working local patch (tested against the repo where the bug surfaced) but want to confirm with you whether:
- The 3-day threshold is right, or whether it should be window-aware
- The warning text matches gstack's voice/conventions
- This belongs in `Step 1: Gather Raw Data` or as its own pre-flight step before Step 1
- The fix should also apply to `/retro compare` and `/retro global` (the global mode has its own multi-repo discovery — the same failure mode could occur there)

Happy to send a PR shaped however you'd prefer. Context: hit while running `/retro` from a Claude Code (Conductor) worktree branch that was 4 commits behind `origin/main`.

---

If helpful: the lesson also landed in my local project memory as "high-confidence 'obviously fine' moments are exactly when the second pair of eyes catches the thing that isn't" — same pattern across the stale-base miss, a self-judged bug diagnosis, and a `/ship` declaring-done gate where I skipped the advisor. The `/retro` skill is the most fixable of these because the check is mechanical.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.