Skip to content

Wireframe extension: sync-wireframes.sh doesn't copy includes/ despite saying it does, and GENERAL_ISSUES.md was gitignored #581

Description

@TortoiseWolfe

Two documented-but-untrue behaviours in the wireframe extension, both silent, both found
while running the #556 gate — the first feature to hit the empty case.

1. sync-wireframes.sh does not copy includes/ into a feature dir

wireframe-config.yml:24-29 states:

The includes/ directory is maintained per-feature. scripts/sync-wireframes.sh
automatically copies shared chrome into each feature's wireframes/includes/ when it syncs
for the viewer — so forkers get working <use href> refs without any manual setup.

It does not. The script only mirrors an already-existing per-feature includes/ out to
public/:

if [ -d "$wf_dir/includes" ]; then
    mkdir -p "$DEST/$slug/includes"
    cp "$wf_dir"/includes/*.svg "$DEST/$slug/includes/" 2>/dev/null || true
fi

Direction is source → public/, and the script begins with rm -rf "$DEST". It never writes
into features/.

The failure is silent. If a feature's wireframes/includes/ is absent the guard skips,
public/wireframes/<slug>/includes/ is never created, and every <use href="includes/…">
404s in the viewer
— no error, no warning, just missing chrome.

The config's own last sentence contradicts its first ("copy the reference implementation's
includes/ to your feature's dir once"), which is the accurate instruction.

Why nobody hit it: all 27 existing feature dirs already carry a byte-identical copy
(md5 42f9f9579c80d0dfa895a3b5a4bf61a9). features/payments/ had zero wireframes across
six features, so 050 was the first to start from nothing.

Fix: either make the script do what the comment says, or correct the comment. Prefer the
former — a forker following the documentation gets a broken viewer.

2. GENERAL_ISSUES.md was gitignored, so it could never have existed

/speckit.wireframe.prep reads
.specify/extensions/wireframe/GENERAL_ISSUES.md to avoid repeating known mistakes across
features. The file did not exist — and .gitignore:104's .specify/extensions/** meant it
could not be committed if written.

Anyone creating it would produce a file that existed only on their machine while prep kept
reporting it missing for everyone else. That is why the same validator rules have been
relearned per feature from error messages.

Fixed in this PR by adding !.specify/extensions/*/GENERAL_ISSUES.md to the allowlist,
alongside the existing AUTHORING-AS-IS.md entry, and seeding the file.

Verification note worth keeping: git check-ignore -v prints negation matches and exits
0 either way, so it reports an allowlisted file as "ignored." Use git add --dry-run to
learn whether git will actually stage a path.

3. Minor: the validator rejects a directory argument

validate.py <dir> raises an unhandled IsADirectoryError traceback rather than a message.
It accepts a file or --all. A one-line guard would help.

Related: #556, #555.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:p2Medium — schedule (feature gaps, partial implementations)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions