Friction Source
Operator-reanchored 2026-05-13 against the substrate-graduation-failure pattern:
"the ticket sounded like 'ensure files INSIDE skills do not bloat'" — pointing at #11275
V-B-A confirms the drift:
- #11275 Context line 1 (operator's pre-graduation intent): "JSON definition for capping files INSIDE skills" — per-file size caps inside skill folders
- Convergence shifted to: machine-readable skill capability manifest + per-skill aggregate governance
- PR #11278 shipped: uniform 80,000-byte
payloadBudget aggregate per skill across references/** only
Empirical gap (same-session sweep 2026-05-13):
| Skill |
references/ Files |
Largest File |
% Skill Budget |
| pr-review |
3 |
pr-review-guide.md 61,079 B / 45 sections |
87% |
| pull-request |
5 |
pull-request-workflow.md 33,833 B + review-response-protocol.md 13,461 B |
66% |
| ideation-sandbox |
1 |
ideation-sandbox-workflow.md 23,025 B |
29% |
| structural-pre-flight |
1 |
-workflow.md 18,989 B |
24% |
| 21 other skills |
varies |
<20 KB monoliths |
<25% |
21 of 25 skills are under 50% of the uniform 80K budget — generous slack invisible to the lint. 2 skills (pr-review + pull-request) hold 37% of all skill-payload bytes. Atlas monoliths inside references/ (single-file 60KB books with 45 sections) pass the aggregate check cleanly.
Adjacent gaps:
- AGENTS.md byte budget — zero coverage in any workflow
- Lint audit scope — only
<skill>/references/; ignores assets/, audits/, scripts, anywhere else under skill folder
- CI workflow —
--base origin/dev passed only on pull_request event; push event branch fires without it, disabling diff-aware downstream-doc check
Why This Extends #11275 vs Closes-Then-Resupersedes
PR #11278 faithfully implemented #11275's ACs (the aggregate-only spec was inside the ticket scope). The substrate-evolution gap is between operator's pre-graduation intent and the converged ticket spec, not between the ticket and PR #11278. This is a scope-extension Cycle 2 (additive ACs on top of the now-merged #11275 baseline), not a corrective-supersede of #11275.
The Fix
Extend ai/scripts/lint-skill-manifest.mjs + .agents/skills/skills.manifest.json + .agents/skills/skills.manifest.schema.json + .github/workflows/skill-manifest-lint.yml with:
1. Per-file Size Cap Inside references/
Add perFileByteBudget field to manifest schema. Default empirical floor (~25 KB / 250 lines per file?) calibrated against current floor + 10-15% headroom. Lint walks <skill>/references/ and flags any individual file exceeding the per-file budget — surfaces atlas-monoliths that the aggregate check misses.
2. AGENTS.md Byte Audit
Add agentsMdByteBudget to manifest defaults block; lint compares AGENTS.md size against the budget. Calibrate to current size + 10% headroom (so substrate-mutation PRs need explicit budget bump if they net-expand AGENTS.md beyond the headroom).
3. Calibrated Per-skill payloadBudget
Replace uniform 80,000 default with per-skill calibrated budgets sized to current-payload + 10-15% headroom. Force conscious budget-bump on PRs that net-grow substrate beyond the headroom (per pull-request-workflow.md §1.1 slot-rationale discipline).
4. Lint Audit Scope Expansion
Walk the entire skill folder (<skill>/**) for payload-byte aggregation, not just <skill>/references/. Currently lints ignore <skill>/assets/, <skill>/audits/, scripts. Aggregate payloadBudget should reflect actual loaded-surface, not just one subdirectory.
5. CI Workflow --base Parity
Workflow YAML currently passes --base origin/${{ github.base_ref }} only on pull_request event. Add equivalent for push event (use --base HEAD~1 OR the prior commit), OR explicitly document that downstream-docs-update check is PR-only by design.
Acceptance Criteria
Out of Scope
- Semantic / LLM-quality scoring — bytes/counts only, per #11275 §Out of Scope (carried forward)
- Per-token semantic analysis — same
- Cross-server MCP tool-count governance — sibling concern; future-extension
- Per-section trigger-frequency audit (heuristic detection of "should-be-sub-rule" sections inside atlas monoliths) — separate substrate concern; might warrant its own ticket once we have per-file byte enforcement landing
- Migration of existing atlas monoliths to split sub-rules — handled in separate cleanup tickets (e.g., split pr-review-guide.md §5.3 MCP-tool-description audit into a sub-rule sibling file)
Avoided Traps / Gold Standards Rejected
- Re-graduating via Ideation Sandbox — re-triggers the lost-graduation pattern that left #11237 and 4 other Discussions unbuilt. Direct ticket route is substrate-correct.
- Closing #11275 as superseded — PR #11278 implemented #11275's ACs faithfully; the gap is between operator's pre-graduation intent and the converged ACs. Scope-extension Cycle 2 is the substrate-correct framing.
- Uniform per-file budget — 21 of 25 skills are <20KB per file; uniform per-file cap should differentiate. Calibrate per-skill OR provide manifest-level default + per-skill override mechanism.
- Implementing #11237 (AI-reviewer CI gate) in same ticket — orthogonal substrate; conflating re-triggers the same pattern that produced the original mismatch. Lane 2 stays separate; GPT-authored per cross-family rotation.
- Substrate accretion bypass — per
pull-request-workflow.md §1.1, implementation PR substrate-mutation slot-rationale required. AC10 enforces.
Related
- Predecessor: #11275 (closed via PR #11278) — aggregate
payloadBudget shipped; this ticket extends to per-file granularity
- Empirical anchor: atlas-monolith sweep 2026-05-13 (pr-review-guide.md 61,079B / 45 sections; pull-request-workflow.md 33,833B; ideation-sandbox-workflow.md 23,025B; structural-pre-flight-workflow.md 18,989B; session-sunset-workflow.md 17,970B; epic-review-workflow.md 17,203B)
- Substrate-graduation-failure context: memory anchor
query_raw_memories("Discussion 11237 maps versus world atlas") — 5 Discussions reached [GRADUATION_PROPOSED] without operationalization (#11214, #11237, #11239, #11240, #11265)
- Sibling Lane 2: Discussion #11237 graduation — mechanical AI-reviewer CI gate (separate substrate, GPT-authored per cross-family rotation; not subsumed by this ticket)
- /create-skill substrate:
.agents/skills/create-skill/references/skill-authoring-guide.md §Map vs World Atlas (lines 106-111) — documented discipline this ticket mechanically enforces
Origin Session ID
c2d47e91-625f-4ebf-b066-49442f465830
Handoff Retrieval Hints
- Semantic:
query_raw_memories(query: "per-file skill payload cap atlas monolith bloat enforcement Map vs World Atlas")
- Empirical:
find .agents/skills -name "*.md" -exec wc -c {} \; | sort -rn | head -10 (live atlas-monolith ranking)
- Precedent:
git show $(git log --grep "11278" --format=%H | head -1) (substrate this ticket extends)
Friction Source
Operator-reanchored 2026-05-13 against the substrate-graduation-failure pattern:
V-B-A confirms the drift:
payloadBudgetaggregate per skill acrossreferences/**onlyEmpirical gap (same-session sweep 2026-05-13):
pr-review-guide.md61,079 B / 45 sectionspull-request-workflow.md33,833 B +review-response-protocol.md13,461 Bideation-sandbox-workflow.md23,025 B-workflow.md18,989 B21 of 25 skills are under 50% of the uniform 80K budget — generous slack invisible to the lint. 2 skills (pr-review + pull-request) hold 37% of all skill-payload bytes. Atlas monoliths inside
references/(single-file 60KB books with 45 sections) pass the aggregate check cleanly.Adjacent gaps:
<skill>/references/; ignoresassets/,audits/, scripts, anywhere else under skill folder--base origin/devpassed only onpull_requestevent;pushevent branch fires without it, disabling diff-aware downstream-doc checkWhy This Extends #11275 vs Closes-Then-Resupersedes
PR #11278 faithfully implemented #11275's ACs (the aggregate-only spec was inside the ticket scope). The substrate-evolution gap is between operator's pre-graduation intent and the converged ticket spec, not between the ticket and PR #11278. This is a scope-extension Cycle 2 (additive ACs on top of the now-merged #11275 baseline), not a corrective-supersede of #11275.
The Fix
Extend
ai/scripts/lint-skill-manifest.mjs+.agents/skills/skills.manifest.json+.agents/skills/skills.manifest.schema.json+.github/workflows/skill-manifest-lint.ymlwith:1. Per-file Size Cap Inside
references/Add
perFileByteBudgetfield to manifest schema. Default empirical floor (~25 KB / 250 lines per file?) calibrated against current floor + 10-15% headroom. Lint walks<skill>/references/and flags any individual file exceeding the per-file budget — surfaces atlas-monoliths that the aggregate check misses.2. AGENTS.md Byte Audit
Add
agentsMdByteBudgetto manifestdefaultsblock; lint comparesAGENTS.mdsize against the budget. Calibrate to current size + 10% headroom (so substrate-mutation PRs need explicit budget bump if they net-expand AGENTS.md beyond the headroom).3. Calibrated Per-skill
payloadBudgetReplace uniform 80,000 default with per-skill calibrated budgets sized to current-payload + 10-15% headroom. Force conscious budget-bump on PRs that net-grow substrate beyond the headroom (per
pull-request-workflow.md §1.1slot-rationale discipline).4. Lint Audit Scope Expansion
Walk the entire skill folder (
<skill>/**) for payload-byte aggregation, not just<skill>/references/. Currently lints ignore<skill>/assets/,<skill>/audits/, scripts. AggregatepayloadBudgetshould reflect actual loaded-surface, not just one subdirectory.5. CI Workflow
--baseParityWorkflow YAML currently passes
--base origin/${{ github.base_ref }}only onpull_requestevent. Add equivalent forpushevent (use--base HEAD~1OR the prior commit), OR explicitly document that downstream-docs-update check is PR-only by design.Acceptance Criteria
perFileByteBudgetfield added to per-skill manifest entry;agentsMdByteBudgetadded todefaultsblock. Both numeric, positive integer.<skill>/references/(and per AC4, all skill subdirs) and flags any individual file exceedingperFileByteBudget. Required Action template: "<skill>/<path>is<size>bytes, exceeds perFileByteBudget<budget>. Either split into sub-rule sibling files behind narrow triggers per Map-vs-World-Atlas discipline (skill-authoring-guide.md §Map vs World Atlas) OR justify the budget bump in PR body with §1.1 slot-rationale."AGENTS.mdbyte size, compares againstdefaults.agentsMdByteBudget, fails on overrun. Required Action: budget bump + slot-rationale.<skill>/**(excluding manifest itself) forpayloadBudgetaggregation, not just<skill>/references/. Schema docs reflect new scope.payloadBudget. Update all 25 skill entries to actual-floor + 10-15% headroom (vs uniform 80,000). Implementation PR documents the calibration table in PR body.--baseparity.pushevent either passes equivalent--baseflag OR workflow YAML documents the PR-only downstream-docs-update intent explicitly (with rationale).skill-authoring-guide.md §Map vs World Atlasfor atlas-monolith violations.[CALIBRATION]slot-rationale in PR body listing each skill's calibrated budget.AGENTS.md §13+pull-request-workflow.md §1.1. Added substrate is machine-readable (manifest fields + lint logic + workflow YAML); offset by NOT adding always-loaded prose discipline.Out of Scope
Avoided Traps / Gold Standards Rejected
pull-request-workflow.md §1.1, implementation PR substrate-mutation slot-rationale required. AC10 enforces.Related
payloadBudgetshipped; this ticket extends to per-file granularityquery_raw_memories("Discussion 11237 maps versus world atlas")— 5 Discussions reached[GRADUATION_PROPOSED]without operationalization (#11214, #11237, #11239, #11240, #11265).agents/skills/create-skill/references/skill-authoring-guide.md §Map vs World Atlas(lines 106-111) — documented discipline this ticket mechanically enforcesOrigin Session ID
c2d47e91-625f-4ebf-b066-49442f465830Handoff Retrieval Hints
query_raw_memories(query: "per-file skill payload cap atlas monolith bloat enforcement Map vs World Atlas")find .agents/skills -name "*.md" -exec wc -c {} \; | sort -rn | head -10(live atlas-monolith ranking)git show $(git log --grep "11278" --format=%H | head -1)(substrate this ticket extends)