CI check-freshness failed because scripts/proactive-suggestions.json
serialized differently on local vs CI:
1. Root-skill key leaked the directory name. processTemplate's outer loop
computed `dir = path.basename(path.dirname(tmplPath))`. For the root
SKILL.md.tmpl at ROOT/SKILL.md.tmpl, that returns the repo-checkout
directory name — "seville-v3" in a Conductor worktree, "gstack" on
GitHub Actions, anything-else for a fork. Fix: detect root via
`path.dirname(tmplPath) === ROOT` and hardcode the key to "gstack"
for that one case.
2. Aggregate key order was filesystem-iteration order. discoverTemplates
doesn't guarantee stable ordering across platforms, so the JSON
`skills` object came out shuffled between machines. Fix: sort
Object.keys(proactiveAggregate) alphabetically before serializing.
After the fix, the generated file is identical on every machine and
matches what's committed. CI freshness check (bun run gen:skill-docs &&
git diff --exit-code) now passes.
Test plan:
- bun run gen:skill-docs && bun run gen:skill-docs --dry-run: all FRESH
- node -e 'verify keys sorted': sorted match: true
- grep -c '"seville-v3"' scripts/proactive-suggestions.json: 0
- Focused test suite: 704 pass, 0 fail
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>