garrytan / garrytan/gstack

plan reviews prefer a root DESIGN.md over docs/designs/, so a design-system file shadows the feature design doc

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

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.