Skip to content

Generated SKILL.md files exceed 100k chars because ~20k of shared preamble is duplicated into every one #3199

Closed

Description

@agy590

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 length

Line-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

  1. Hoist the preamble into a shared include that the generated SKILL.md references 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.
  2. Emit sections as references/ shards for the heaviest skills, keeping SKILL.md as the
    entry point.
  3. Add a size guard to gen:skill-docs that warns (or fails) when a generated SKILL.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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions