Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 50 additions & 8 deletions retro/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -823,7 +823,7 @@ When the user types `/retro`, run this skill.

Parse the argument to determine the time window. Default to 7 days if no argument given. All times should be reported in the user's **local timezone** (use the system default — do NOT set `TZ`).

**Midnight-aligned windows:** For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if today is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows.
**Midnight-aligned windows:** Treat the shell system date (`date +%Y-%m-%d`) as the source of truth for "today"; do not derive today from session reminders, model memory, or prior conversation context. For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if the system date is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows.

**Argument validation:** If the argument doesn't match a number followed by `d`, `h`, or `w`, the word `compare` (optionally followed by a window), or the word `global` (optionally followed by a window), show this usage and stop:
```
Expand Down Expand Up @@ -888,11 +888,50 @@ Check for non-git context that should be included in the retro:

If `RETRO_CONTEXT_FOUND`: read `~/.gstack/retro-context.md`. This file is user-authored and may contain meeting notes, calendar events, decisions, and other context that doesn't appear in git history. Incorporate this context into the retro narrative where relevant.

### Step 1: Gather Raw Data
### Date/window pre-flight

Run this dedicated pre-flight after resolving the requested window and before the main data-gathering commands. For `/retro compare`, run it against the current window before computing the prior window. For `/retro global`, run it once per discovered repo after detecting that repo's default branch and before collecting its git-log data.

Resolve:
- `<window>` to the exact `--since` value used for the current window, such as `2026-05-13T00:00:00`.
- `<window_days>` to the numeric current-window length in days. Use `7` for the default window, `N` for `Nd`, `N * 7` for `Nw`, and `ceil(N / 24)` with a minimum of `1` for `Nh`.

First, fetch origin and identify the current user:
```bash
git fetch origin <default> --quiet

_RETRO_SYSTEM_DATE=$(date +%Y-%m-%d)
_RETRO_WINDOW_DAYS="<window_days>"
case "$_RETRO_WINDOW_DAYS" in ''|*[!0-9]*) _RETRO_WINDOW_DAYS=7 ;; esac
if [ "$_RETRO_WINDOW_DAYS" -lt 1 ]; then _RETRO_WINDOW_DAYS=1; fi
_ORIGIN_LATEST_UNIX=$(git log origin/<default> -1 --format="%at" 2>/dev/null || echo 0)
_ORIGIN_LATEST_DATE=$(git log origin/<default> -1 --format="%ad" --date=short 2>/dev/null || echo unknown)
case "$_ORIGIN_LATEST_UNIX" in ''|*[!0-9]*) _ORIGIN_LATEST_UNIX=0 ;; esac
if [ "$_ORIGIN_LATEST_UNIX" -gt 0 ]; then
_ORIGIN_GAP_DAYS=$(( ($(date +%s) - _ORIGIN_LATEST_UNIX) / 86400 ))
else
_ORIGIN_GAP_DAYS=9999
fi
_WINDOW_COMMITS=$(git rev-list --count origin/<default> --since="<window>" 2>/dev/null || echo 0)
case "$_WINDOW_COMMITS" in ''|*[!0-9]*) _WINDOW_COMMITS=0 ;; esac
echo "RETRO_SYSTEM_DATE: $_RETRO_SYSTEM_DATE"
echo "RETRO_WINDOW_DAYS: $_RETRO_WINDOW_DAYS"
echo "ORIGIN_DEFAULT_LATEST: $_ORIGIN_LATEST_DATE (${_ORIGIN_GAP_DAYS}d before system date)"
echo "RETRO_WINDOW_COMMIT_COUNT: $_WINDOW_COMMITS"
if [ "$_ORIGIN_GAP_DAYS" -gt "$_RETRO_WINDOW_DAYS" ]; then
echo "STALE-BASE WARNING: latest origin/<default> commit is ${_ORIGIN_GAP_DAYS} days before the system date, which is older than the ${_RETRO_WINDOW_DAYS}d retro window. Confirm the 'today' anchor and whether origin/<default> is current before writing the retro."
fi
if [ "$_WINDOW_COMMITS" -eq 0 ]; then
echo "EMPTY-WINDOW WARNING: origin/<default> has zero commits in the requested retro window. Treat this as a possible wrong today/window anchor, not proof that no work happened."
fi
```

If the date you used to compute a day/week window does not match `RETRO_SYSTEM_DATE`, print `TODAY-ANCHOR WARNING`, recompute the window from `RETRO_SYSTEM_DATE`, and rerun the pre-flight. If `STALE-BASE WARNING` or `EMPTY-WINDOW WARNING` appears, call it out before any normal retro narrative. Do not produce a clean-looking "nothing happened" retro without explaining the suspect system date/window/base-branch evidence. This window-aware threshold intentionally catches the #1624 9-day-gap/7d reproducer: if the latest default-branch commit is 9 days before the system date and the current retro window is 7 days, the pre-flight must print `STALE-BASE WARNING`.

### Step 1: Gather Raw Data

First, identify the current user:

```bash
# Identify who is running the retro
git config user.name
git config user.email
Expand Down Expand Up @@ -1440,6 +1479,8 @@ git -C <path> fetch origin --quiet 2>/dev/null

Detect the default branch for each repo: first try `git symbolic-ref refs/remotes/origin/HEAD`, then check common branch names (`main`, `master`), then fall back to `git rev-parse --abbrev-ref HEAD`. Use the detected branch as `<default>` in the commands below.

Run the **Date/window pre-flight** for each repo before the commands below. For remote repos, use `origin/$DEFAULT` where that pre-flight says `origin/<default>`. For local-only repos, use `HEAD` in place of `origin/<default>`, skip the fetch line, and label warnings with the repo name. In the global summary, list any repos that emitted `STALE-BASE WARNING` or `EMPTY-WINDOW WARNING` before presenting aggregate totals.

```bash
# Commits with stats
git -C <path> log origin/$DEFAULT --since="<start_date>T00:00:00" --format="%H|%aN|%ai|%s" --shortstat
Expand Down Expand Up @@ -1687,11 +1728,12 @@ Use the Write tool to save JSON to `~/.gstack/retros/global-${today}-${next}.jso

When the user runs `/retro compare` (or `/retro compare 14d`):

1. Compute metrics for the current window (default 7d) using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`)
2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`)
3. Show a side-by-side comparison table with deltas and arrows
4. Write a brief narrative highlighting the biggest improvements and regressions
5. Save only the current-window snapshot to `.context/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.
1. Run the **Date/window pre-flight** for the current window (default 7d). If it emits `TODAY-ANCHOR WARNING`, `STALE-BASE WARNING`, or `EMPTY-WINDOW WARNING`, show that warning before any comparison output.
2. Compute metrics for the current window using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`)
3. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`)
4. Show a side-by-side comparison table with deltas and arrows
5. Write a brief narrative highlighting the biggest improvements and regressions
6. Save only the current-window snapshot to `.context/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.

## Tone

Expand Down
58 changes: 50 additions & 8 deletions retro/SKILL.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ When the user types `/retro`, run this skill.

Parse the argument to determine the time window. Default to 7 days if no argument given. All times should be reported in the user's **local timezone** (use the system default — do NOT set `TZ`).

**Midnight-aligned windows:** For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if today is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows.
**Midnight-aligned windows:** Treat the shell system date (`date +%Y-%m-%d`) as the source of truth for "today"; do not derive today from session reminders, model memory, or prior conversation context. For day (`d`) and week (`w`) units, compute an absolute start date at local midnight, not a relative string. For example, if the system date is 2026-03-18 and the window is 7 days: the start date is 2026-03-11. Use `--since="2026-03-11T00:00:00"` for git log queries — the explicit `T00:00:00` suffix ensures git starts from midnight. Without it, git uses the current wall-clock time (e.g., `--since="2026-03-11"` at 11pm means 11pm, not midnight). For week units, multiply by 7 to get days (e.g., `2w` = 14 days back). For hour (`h`) units, use `--since="N hours ago"` since midnight alignment does not apply to sub-day windows.

**Argument validation:** If the argument doesn't match a number followed by `d`, `h`, or `w`, the word `compare` (optionally followed by a window), or the word `global` (optionally followed by a window), show this usage and stop:
```
Expand Down Expand Up @@ -95,11 +95,50 @@ Check for non-git context that should be included in the retro:

If `RETRO_CONTEXT_FOUND`: read `~/.gstack/retro-context.md`. This file is user-authored and may contain meeting notes, calendar events, decisions, and other context that doesn't appear in git history. Incorporate this context into the retro narrative where relevant.

### Step 1: Gather Raw Data
### Date/window pre-flight

Run this dedicated pre-flight after resolving the requested window and before the main data-gathering commands. For `/retro compare`, run it against the current window before computing the prior window. For `/retro global`, run it once per discovered repo after detecting that repo's default branch and before collecting its git-log data.

Resolve:
- `<window>` to the exact `--since` value used for the current window, such as `2026-05-13T00:00:00`.
- `<window_days>` to the numeric current-window length in days. Use `7` for the default window, `N` for `Nd`, `N * 7` for `Nw`, and `ceil(N / 24)` with a minimum of `1` for `Nh`.

First, fetch origin and identify the current user:
```bash
git fetch origin <default> --quiet

_RETRO_SYSTEM_DATE=$(date +%Y-%m-%d)
_RETRO_WINDOW_DAYS="<window_days>"
case "$_RETRO_WINDOW_DAYS" in ''|*[!0-9]*) _RETRO_WINDOW_DAYS=7 ;; esac
if [ "$_RETRO_WINDOW_DAYS" -lt 1 ]; then _RETRO_WINDOW_DAYS=1; fi
_ORIGIN_LATEST_UNIX=$(git log origin/<default> -1 --format="%at" 2>/dev/null || echo 0)
_ORIGIN_LATEST_DATE=$(git log origin/<default> -1 --format="%ad" --date=short 2>/dev/null || echo unknown)
case "$_ORIGIN_LATEST_UNIX" in ''|*[!0-9]*) _ORIGIN_LATEST_UNIX=0 ;; esac
if [ "$_ORIGIN_LATEST_UNIX" -gt 0 ]; then
_ORIGIN_GAP_DAYS=$(( ($(date +%s) - _ORIGIN_LATEST_UNIX) / 86400 ))
else
_ORIGIN_GAP_DAYS=9999
fi
_WINDOW_COMMITS=$(git rev-list --count origin/<default> --since="<window>" 2>/dev/null || echo 0)
case "$_WINDOW_COMMITS" in ''|*[!0-9]*) _WINDOW_COMMITS=0 ;; esac
echo "RETRO_SYSTEM_DATE: $_RETRO_SYSTEM_DATE"
echo "RETRO_WINDOW_DAYS: $_RETRO_WINDOW_DAYS"
echo "ORIGIN_DEFAULT_LATEST: $_ORIGIN_LATEST_DATE (${_ORIGIN_GAP_DAYS}d before system date)"
echo "RETRO_WINDOW_COMMIT_COUNT: $_WINDOW_COMMITS"
if [ "$_ORIGIN_GAP_DAYS" -gt "$_RETRO_WINDOW_DAYS" ]; then
echo "STALE-BASE WARNING: latest origin/<default> commit is ${_ORIGIN_GAP_DAYS} days before the system date, which is older than the ${_RETRO_WINDOW_DAYS}d retro window. Confirm the 'today' anchor and whether origin/<default> is current before writing the retro."
fi
if [ "$_WINDOW_COMMITS" -eq 0 ]; then
echo "EMPTY-WINDOW WARNING: origin/<default> has zero commits in the requested retro window. Treat this as a possible wrong today/window anchor, not proof that no work happened."
fi
```

If the date you used to compute a day/week window does not match `RETRO_SYSTEM_DATE`, print `TODAY-ANCHOR WARNING`, recompute the window from `RETRO_SYSTEM_DATE`, and rerun the pre-flight. If `STALE-BASE WARNING` or `EMPTY-WINDOW WARNING` appears, call it out before any normal retro narrative. Do not produce a clean-looking "nothing happened" retro without explaining the suspect system date/window/base-branch evidence. This window-aware threshold intentionally catches the #1624 9-day-gap/7d reproducer: if the latest default-branch commit is 9 days before the system date and the current retro window is 7 days, the pre-flight must print `STALE-BASE WARNING`.

### Step 1: Gather Raw Data

First, identify the current user:

```bash
# Identify who is running the retro
git config user.name
git config user.email
Expand Down Expand Up @@ -624,6 +663,8 @@ git -C <path> fetch origin --quiet 2>/dev/null

Detect the default branch for each repo: first try `git symbolic-ref refs/remotes/origin/HEAD`, then check common branch names (`main`, `master`), then fall back to `git rev-parse --abbrev-ref HEAD`. Use the detected branch as `<default>` in the commands below.

Run the **Date/window pre-flight** for each repo before the commands below. For remote repos, use `origin/$DEFAULT` where that pre-flight says `origin/<default>`. For local-only repos, use `HEAD` in place of `origin/<default>`, skip the fetch line, and label warnings with the repo name. In the global summary, list any repos that emitted `STALE-BASE WARNING` or `EMPTY-WINDOW WARNING` before presenting aggregate totals.

```bash
# Commits with stats
git -C <path> log origin/$DEFAULT --since="<start_date>T00:00:00" --format="%H|%aN|%ai|%s" --shortstat
Expand Down Expand Up @@ -871,11 +912,12 @@ Use the Write tool to save JSON to `~/.gstack/retros/global-${today}-${next}.jso

When the user runs `/retro compare` (or `/retro compare 14d`):

1. Compute metrics for the current window (default 7d) using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`)
2. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`)
3. Show a side-by-side comparison table with deltas and arrows
4. Write a brief narrative highlighting the biggest improvements and regressions
5. Save only the current-window snapshot to `.context/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.
1. Run the **Date/window pre-flight** for the current window (default 7d). If it emits `TODAY-ANCHOR WARNING`, `STALE-BASE WARNING`, or `EMPTY-WINDOW WARNING`, show that warning before any comparison output.
2. Compute metrics for the current window using the midnight-aligned start date (same logic as the main retro — e.g., if today is 2026-03-18 and window is 7d, use `--since="2026-03-11T00:00:00"`)
3. Compute metrics for the immediately prior same-length window using both `--since` and `--until` with midnight-aligned dates to avoid overlap (e.g., for a 7d window starting 2026-03-11: prior window is `--since="2026-03-04T00:00:00" --until="2026-03-11T00:00:00"`)
4. Show a side-by-side comparison table with deltas and arrows
5. Write a brief narrative highlighting the biggest improvements and regressions
6. Save only the current-window snapshot to `.context/retros/` (same as a normal retro run); do **not** persist the prior-window metrics.

## Tone

Expand Down
16 changes: 16 additions & 0 deletions test/gen-skill-docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,22 @@ describe('Retro plan completion section', () => {
expect(retroSkill).toContain('plan_items_total');
expect(retroSkill).toContain('Plan Completion This Period');
});

test('retro SKILL.md warns on stale base or empty windows', () => {
expect(retroSkill).toContain('### Date/window pre-flight');
expect(retroSkill).toContain('RETRO_SYSTEM_DATE');
expect(retroSkill).toContain('RETRO_WINDOW_DAYS');
expect(retroSkill).toContain('ORIGIN_DEFAULT_LATEST');
expect(retroSkill).toContain('RETRO_WINDOW_COMMIT_COUNT');
expect(retroSkill).toContain('TODAY-ANCHOR WARNING');
expect(retroSkill).toContain('STALE-BASE WARNING');
expect(retroSkill).toContain('EMPTY-WINDOW WARNING');
expect(retroSkill).toContain('$_ORIGIN_GAP_DAYS" -gt "$_RETRO_WINDOW_DAYS');
expect(retroSkill).toContain('#1624 9-day-gap/7d reproducer');
expect(retroSkill).toContain('For `/retro compare`, run it against the current window');
expect(retroSkill).toContain('For `/retro global`, run it once per discovered repo');
expect(retroSkill).toContain('git rev-list --count origin/<default> --since="<window>"');
});
});

// --- Plan status footer in preamble ---
Expand Down
Loading