plan reviews prefer a root DESIGN.md over docs/designs/, so a design-system file shadows the feature design doc
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
The canonical design-doc discovery fragment prefers a repo-root `DESIGN.md` over `docs/designs/*.md` unconditionally. Since v1.84.0.0 those two paths hold different kinds of document, so a project that runs `/design-consultation` and also keeps feature design docs in `docs/designs/` loses the feature design doc from every plan review, silently.
## The block
`scripts/resolvers/design-doc-discovery.ts:30-45`:
```sh
_REPODOC=""
if [ -n "$_REPOTOP" ]; then
[ -f "$_REPOTOP/DESIGN.md" ] && _REPODOC="$_REPOTOP/DESIGN.md"
[ -z "$_REPODOC" ] && _REPODOC=$(ls -t "$_REPOTOP"/docs/designs/*.md 2>/dev/null | head -1)
fi
DESIGN="$_LOCALDOC"
if [ -n "$_REPODOC" ] && { [ -z "$_LOCALDOC" ] || [ "$_REPODOC" -nt "$_LOCALDOC" ]; }; then
DESIGN="$_REPODOC"
fi
```
When `DESIGN.md` exists, the `docs/designs/` glob is never evaluated — the second line is guarded on `_REPODOC` being empty. The `-nt` freshness test that follows compares `_REPODOC` against `_LOCALDOC` (the `~/.gstack/projects//` session doc) only. Between the two repo-local candidates there is no comparison at all: a `DESIGN.md` written months ago beats a `docs/designs/` doc written this morning.
The fragment's own doc comment (`design-doc-discovery.ts:6-9`) describes the intent as "lets a repo-local doc (DESIGN.md or docs/designs/*.md) win when it is at least as fresh … a stale old repo doc must never shadow a newer private session". That stale-shadow guard is applied against the private session copy but not between the two repo-local candidates.
## Why it matters now
The two paths hold different documents, and the split widened in v1.84.0.0:
- `docs/designs/*.md` is where `/office-hours` dual-writes a **feature design doc** — problem statement, constraints, alternatives, chosen approach.
- Repo-root `DESIGN.md` is where `/design-consultation` writes a **visual design system** — YAML front matter with five token groups plus the eight canonical spec sections (`Overview`, `Colors`, `Typography`, `Layout`, `Elevation & Depth`, `Shapes`, `Components`, `Do's and Don'ts`).
The plan reviews want the first kind. `plan-eng-review/SKILL.md:595`:
> If a design doc exists, read it. Use it as the source of truth for the problem statement, constraints, and chosen approach.
A token file answers none of those three. So on any project that has both, `/plan-eng-review`, `/plan-ceo-review`, `/plan-devex-review` and `/autoplan` review a backend refactor against a color palette and a type scale.
Two things make it quiet rather than obvious:
1. The block prints `Design doc found: /repo/DESIGN.md`, so it reads as working.
2. The "No design doc found" branch is what triggers the prerequisite offer to run `/office-hours` first (`plan-eng-review/SKILL.md:598-610`). A doc *was* found, so that offer never fires — the user is neither given the right document nor prompted to produce one.
Nothing is corrupted: `$DESIGN` is read-only input, and `## GSTACK REVIEW REPORT` is appended to the plan file (`plan-eng-review/SKILL.md:720-724`), not to the design doc. The cost is a review reasoning from the wrong document.
## Affected
One shared fragment, seven call sites:
- `plan-eng-review/SKILL.md:586` and `:654`
- `plan-ceo-review/SKILL.md:615` and `:699`
- `plan-devex-review/SKILL.md:610` and `:683`
- `autoplan/SKILL.md:530`
- plus `scripts/resolvers/review.ts:317`, which interpolates `DESIGN_DOC_DISCOVERY_BLOCK` for the prerequisite re-check
## Reproduce
```
repo/
DESIGN.md # written by /design-consultation
docs/designs/0001-some-feature.md # written by /office-hours
```
Touch `docs/designs/0001-some-feature.md` so it is newer than `DESIGN.md`, then run `/plan-eng-review` on a feature branch with no `~/.gstack/projects//*-design-*.md` present. It prints `Design doc found: /DESIGN.md` and reviews the plan against the design system.
## Note
`/design-consultation` writing to the repo root is what puts a project in this state, and it does so by default outside plan mode (`design-consultation/sections/proposal-and-preview.md:361`). Any project that follows both halves of the documented workflow — `/office-hours` for feature designs, `/design-consultation` for the design system — ends up here without doing anything unusual.
Contributor guide
Research direction
Start with scripts/resolvers/design-doc-discovery.ts:6-45 and inspect how its shared block is used by the listed plan-review skills and scripts/resolvers/review.ts:317. Reproduce the case with both DESIGN.md and a newer docs/designs/*.md, then verify the discovery output selects the appropriate feature design document without breaking the private session-doc freshness check.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell, typescript
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100