Summary
spec/SKILL.md.tmpl uses {{PREAMBLE}} inside a sentence where it was meant to name the preamble section, not expand it. The build inlines the full 767-line preamble into the middle of the sentence, producing a spec/SKILL.md that is 2359 lines / 124 KB instead of 1591 lines / 80 KB — roughly 11k wasted tokens every time /spec loads, plus a sentence that is split in half and unreadable.
Affects v1.60.1.0 (and, from the shape of the generated output, every prior version that shipped this template line).
Root cause
spec/SKILL.md.tmpl:289:
Read `GSTACK_PLAN_MODE` from the environment (emitted by `{{PREAMBLE}}`'s
preamble bash). Then:
The author intended the backticked token to render as the literal section name ## Preamble (run first). But {{PREAMBLE}} is the expansion macro, so the resolver splices the whole preamble block in.
This is the only inline misuse in the repo. Every other {{PREAMBLE}} occurrence sits alone on its own line, which is the correct usage:
$ grep -rn '{{PREAMBLE}}' --include='*.tmpl' . | grep -v ':[0-9]*:{{PREAMBLE}}$'
./spec/SKILL.md.tmpl:289:Read `GSTACK_PLAN_MODE` from the environment (emitted by `{{PREAMBLE}}`'s
(spec/SKILL.md.tmpl:25 is the legitimate standalone use.)
Evidence in the generated file
In the built spec/SKILL.md, lines 31–797 are byte-identical to lines 1101–1867 (767 lines):
# offset 1070, exact match
lines 31-797 <-> 1101-1867 (len 767)
The sentence is torn apart across the injection:
1100: Read `GSTACK_PLAN_MODE` from the environment (emitted by `## Preamble (run first)
1101:
1102: ```bash
1103: _UPD=$(~/.claude/skills/gstack/bin/gstack-update-check ...
... 767 lines of preamble ...
1868: ...Writing the plan file is the one edit allowed in plan mode.`'s
1869: preamble bash). Then:
Note line 1868: the trailing `'s from the original sentence ends up glued to the last line of the preamble's Plan Status Footer.
Side effect: because the preamble is duplicated, ## Telemetry (run last), ## Voice, ## Context Recovery, ## Confusion Protocol etc. each appear twice in the same skill, giving the model two copies of every behavioural directive.
Fix
--- a/spec/SKILL.md.tmpl
+++ b/spec/SKILL.md.tmpl
@@ -286,7 +286,7 @@
#### Phase 5 dispatch logic (plan-mode-aware default)
-Read `GSTACK_PLAN_MODE` from the environment (emitted by `{{PREAMBLE}}`'s
+Read `GSTACK_PLAN_MODE` from the environment (emitted by `## Preamble (run first)`'s
preamble bash). Then:
I verified the equivalent splice on the built file locally: 2359 → 1591 lines, 124 KB → 80.3 KB, code fences still balanced, frontmatter and all 48 ## sections intact, sentence restored.
Suggested guard
A build-time assertion would catch this class of bug cheaply — either:
- reject expansion macros that appear anywhere other than at column 0 on their own line, or
- post-build check that no
SKILL.md contains the preamble's sentinel heading (## Preamble (run first)) more than once.
Option 2 also covers any future macro that expands large shared blocks.
Affected generated files
Same defect is present in all host variants built from this template:
spec/SKILL.md
.agents/skills/gstack-spec/SKILL.md
.cursor/skills/gstack-spec/SKILL.md
.factory/skills/gstack-spec/SKILL.md
.gbrain/skills/gstack-spec/SKILL.md
.hermes/skills/gstack-spec/SKILL.md
.kiro/skills/gstack-spec/SKILL.md
.openclaw/skills/gstack-spec/SKILL.md
.opencode/skills/gstack-spec/SKILL.md
.slate/skills/gstack-spec/SKILL.md
Related
#2214 raises the broader point that the shared preamble is duplicated across all skills. This issue is narrower and independent: a single template line that duplicates the preamble a second time within one skill.
Summary
spec/SKILL.md.tmpluses{{PREAMBLE}}inside a sentence where it was meant to name the preamble section, not expand it. The build inlines the full 767-line preamble into the middle of the sentence, producing aspec/SKILL.mdthat is 2359 lines / 124 KB instead of 1591 lines / 80 KB — roughly 11k wasted tokens every time/specloads, plus a sentence that is split in half and unreadable.Affects v1.60.1.0 (and, from the shape of the generated output, every prior version that shipped this template line).
Root cause
spec/SKILL.md.tmpl:289:The author intended the backticked token to render as the literal section name
## Preamble (run first). But{{PREAMBLE}}is the expansion macro, so the resolver splices the whole preamble block in.This is the only inline misuse in the repo. Every other
{{PREAMBLE}}occurrence sits alone on its own line, which is the correct usage:(
spec/SKILL.md.tmpl:25is the legitimate standalone use.)Evidence in the generated file
In the built
spec/SKILL.md, lines 31–797 are byte-identical to lines 1101–1867 (767 lines):The sentence is torn apart across the injection:
Note line 1868: the trailing
`'sfrom the original sentence ends up glued to the last line of the preamble's Plan Status Footer.Side effect: because the preamble is duplicated,
## Telemetry (run last),## Voice,## Context Recovery,## Confusion Protocoletc. each appear twice in the same skill, giving the model two copies of every behavioural directive.Fix
I verified the equivalent splice on the built file locally: 2359 → 1591 lines, 124 KB → 80.3 KB, code fences still balanced, frontmatter and all 48
##sections intact, sentence restored.Suggested guard
A build-time assertion would catch this class of bug cheaply — either:
SKILL.mdcontains the preamble's sentinel heading (## Preamble (run first)) more than once.Option 2 also covers any future macro that expands large shared blocks.
Affected generated files
Same defect is present in all host variants built from this template:
Related
#2214 raises the broader point that the shared preamble is duplicated across all skills. This issue is narrower and independent: a single template line that duplicates the preamble a second time within one skill.