Repository navigation
Description
What happens
Every generated SKILL.md in this repo opens with essentially the same ~20k chars of preamble
(upgrade flow, telemetry prompts, routing prompts, lake intro, artifacts sync) copied verbatim out
of SKILL.md.tmpl. Across the repo, 49.9% of all skill text is duplicated line-for-line between
skills, and seven SKILL.md files now exceed 100,000 characters:
| skill | chars | preamble | after hoisting preamble |
|---|---|---|---|
ship |
167,242 | 20,087 | ~147,155 |
plan-ceo-review |
131,500 | 21,031 | ~110,469 |
office-hours |
112,715 | 21,273 | ~91,442 |
plan-design-review |
107,718 | 20,148 | ~87,570 |
plan-devex-review |
106,421 | 20,468 | ~85,953 |
spec |
103,973 | 20,052 | ~83,921 |
plan-eng-review |
103,031 | 20,315 | ~82,716 |
(Median SKILL.md across all 58 files: 48,612 chars.)
Why it matters beyond file size
Several agent runtimes and skill loaders cap a single SKILL.md at 100,000 characters. One
concrete failure mode: the Hermes skill editor refuses every edit — patch, rewrite, anything —
on a skill whose SKILL.md exceeds 100k chars, and the rejection message does not mention size, so
the file silently becomes read-only. Independent of tooling, a 167k-char skill consumes a large
share of a context window when loaded on demand.
Measurements
for f in */SKILL.md; do printf "%-30s %8d\n" "$f" "$(wc -m < "$f")"; done | sort -k2 -rn | head
grep -n '^# /' */SKILL.md | head # offset of the first skill-specific heading = preamble lengthLine-level duplication across all 58 SKILL.md files:
import os
from collections import Counter
sk = {d: open(f"{d}/SKILL.md", encoding="utf-8").read()
for d in os.listdir(".") if os.path.exists(f"{d}/SKILL.md")}
cnt = Counter()
for t in sk.values():
for line in {x.strip() for x in t.split("\n") if len(x.strip()) > 25}:
cnt[line] += 1
common = {l for l, c in cnt.items() if c >= len(sk) * 0.7}
tot = sum(len(t) for t in sk.values())
shared = sum(len(l) for t in sk.values() for l in t.split("\n") if l.strip() in common)
print(f"{len(common)} lines in >={int(len(sk)*0.7)} files; {shared}/{tot} chars = {shared/tot:.1%}")
# -> 404 lines in >=40 files; 1600571/3210730 chars = 49.9%Suggested fixes
- Hoist the preamble into a shared include that the generated
SKILL.mdreferences instead of
inlining. Five of the seven offenders drop under 100k immediately (office-hours,
plan-design-review,plan-devex-review,spec,plan-eng-review);ship(~147k) and
plan-ceo-review(~110k) would still need real splitting. - Emit sections as
references/shards for the heaviest skills, keepingSKILL.mdas the
entry point. - Add a size guard to
gen:skill-docsthat warns (or fails) when a generatedSKILL.md
crosses ~90k chars, so this surfaces at generation time rather than in a downstream tool.
spec is a special case worth a look: 65% of its lines are shared with other skills, so it likely
carries more extractable duplication than the common preamble alone.
Activity
v1.91.117.0 fix: pregate bats lanes, WTREE_UNAVAILABLE, doctor rows, …
v1.91.157.0 perf(gen-skill-docs): drop the "When to invoke" body sect…