garrytan / garrytan/gstack

plan-completion: the fallback matches plans by branch name, which plan-mode files never contain — so it reliably selects the eng-review test plan instead

Open
#2,800 0 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

`review/sections/plan-completion.md` and `ship/sections/plan-completion.md`, Plan File Discovery step 2.

The fallback search matches candidate plans by grepping for the branch name. Plan-mode plan files don't contain the branch name, so the grep can't match the file it most wants — while a different, always-present file does match, and wins.

## The search

```bash
for PLAN_DIR in "$HOME/.gstack/projects/$_PLAN_SLUG" "$HOME/.claude/plans" "$HOME/.codex/plans" ".gstack/plans"; do
[ -d "$PLAN_DIR" ] || continue
PLAN=$(ls -t "$PLAN_DIR"/*.md 2>/dev/null | xargs grep -l "$BRANCH" 2>/dev/null | head -1)
[ -z "$PLAN" ] && PLAN=$(ls -t "$PLAN_DIR"/*.md 2>/dev/null | xargs grep -l "$REPO" 2>/dev/null | head -1)
[ -z "$PLAN" ] && PLAN=$(find "$PLAN_DIR" -name '*.md' -mmin -1440 -maxdepth 1 2>/dev/null | xargs -r ls -t 2>/dev/null | head -1)
[ -n "$PLAN" ] && break
done
```

## Two problems that compound

**1. Plan-mode files don't contain the branch name.** Plan mode names the file from the first user message (`~/.claude/plans/let-s-start-working-on-kind-shannon.md`) and its content is the plan. Neither carries the branch — usually because the branch doesn't exist yet when the plan is written. On a 44 KB plan for branch `t16-start`, `grep -c t16-start` is **0**, as it is for every other file in that directory.

**2. `~/.gstack/projects//` is searched first and always matches — with a QA test plan.** Every `/plan-eng-review` writes a `*-test-plan-*.md` there carrying a literal `Branch: ` line, so it matches the branch grep on the first directory and `break`s the loop. `~/.claude/plans/` is never reached.

Traced on a real branch:

```
BRANCH=t16-start
_PLAN_SLUG=

dir: ~/.gstack/projects/
by BRANCH : dgrant-t16-start-eng-review-test-plan-20260903-013606.md <- 1.7 KB QA checklist

PLAN_FILE: .../dgrant-t16-start-eng-review-test-plan-20260903-013606.md
```

The 44 KB implementation plan with the actual `- [ ]` items sits unread in `~/.claude/plans/`.

## Why the capture is worse than finding nothing

The selected file is a QA checklist for `/qa`, not an implementation plan: 0 checkboxes, no file specifications. But it doesn't trigger the "no extractable actionable items → skip" escape either, because the extraction rules match `Verify`/`Confirm` imperatives and it is full of them ("Confirm the sidebar is absent when DEBUG is off"). So the audit cross-references a dozen *manual browser steps* against a git diff and reports the ones no diff can satisfy.

Step 3's validation doesn't catch it: "read the first 20 lines and verify it is relevant to the current branch's work" passes, because the test plan genuinely is about that branch. It's the right topic and the wrong kind of document.

Net effect: the audit reports confident false negatives, and the signal is one you learn to ignore.

## Suggested fix

Drop the content-grep heuristic. Try conversation context, and if that misses, **ask**:

1. Conversation context (unchanged, and already the reliable path).
2. Otherwise, list the candidate `*.md` files across the four directories with their mtimes and ask the user which is the plan — or to confirm there isn't one.

Guessing by grep is what produces the confident-wrong outcome above; one question is cheap, deterministic, and lets the user say "none" so the audit skips honestly. If an automatic path is still wanted, matching on plan *shape* (presence of `- [ ]` items or an `## Implementation` heading) would at least exclude test plans — but a prompt seems better than a second heuristic.

A smaller, independent improvement: have plan mode's file, or the skills that consume it, record the branch once it exists — that would make the existing grep work as intended.

## Related

#2768 — same audit, different defect (`docs/designs/` is on none of the four search paths). This one is about the matching within the paths that *are* searched, so fixing #2768 alone wouldn't help: the first directory still wins with the test plan.

## Environment

gstack 1.79.0.0

Contributor guide

Open the contributing guide

Research direction

Read Plan File Discovery step 2 in review/sections/plan-completion.md and ship/sections/plan-completion.md, then reproduce the fallback against the four listed plan directories using the branch and repository examples in the issue. Trace how the selected file reaches extraction and validation. Done means the audit no longer confidently selects an eng-review test plan when an implementation plan is available, and the no-plan case remains explicit.

Written by the indexing model from the issue text.

Assessment

Tech stack
markdown, shell
Domain
developer-experience, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.