# Design Pattern

# Progressive Disclosure Design Pattern

**Source:** `~/system/specs/agentic-os-pillar4-skills-audit-2026-05-04.md` (§5)  
**MC:** [\#99131](https://boards.alai.no/tasks/99131) | [\#99176](https://boards.alai.no/tasks/99176)  
**Date:** 2026-05-05

*Derived from `~/.claude/skills/skill-creator/SKILL.md` ("context window is a public good"). This section codifies what is implicit in the canonical reference — it does not invent a new framework.*

---

## Definition

Progressive disclosure for skills means that skill content is loaded in tiers based on actual need:

- **Tier 1 (frontmatter — always-loaded):** Every time a Claude session starts, all SKILL.md frontmatter `description` fields are loaded to determine which skills to activate. Frontmatter is the highest-cost content per byte because it loads regardless of usage.
- **Tier 2 (SKILL.md body — loaded on trigger):** After a skill matches its trigger condition, the full SKILL.md body loads. This is the decision-making and branching layer.
- **Tier 3 (references/ — loaded on demand):** Content in `references/` is loaded explicitly via `Read <path>` only when the agent reaches a branch that needs it. Scripts in `scripts/` are invoked without being loaded into context.

**The principle:** never load content that is not needed for the current branch of execution.

---

## L0–L3 Rubric

This rubric is used for the `progressive_disclosure_score` column in the inventory CSV.

<table id="bkmrk-level-definition-bod"><thead><tr><th>Level</th><th>Definition</th><th>Body size</th><th>References</th><th>Frontmatter</th><th>Hardcoded paths</th></tr></thead><tbody><tr><td>L0</td><td>Monolithic — entire skill in one file, no references/ dir</td><td>any (often &gt; 200 LOC)</td><td>absent</td><td>any size</td><td>allowed</td></tr><tr><td>L1</td><td>SKILL.md exists + references/ dir may exist, but body &gt; 200 lines OR references are read proactively (not conditionally)</td><td>&gt; 200 LOC</td><td>optional</td><td>any size</td><td>allowed</td></tr><tr><td>L2</td><td>SKILL.md body ≤ 200 lines; references/ loaded conditionally on branch; no hardcoded paths</td><td>≤ 200 LOC</td><td>conditional</td><td>any size</td><td>not allowed</td></tr><tr><td>L3</td><td>SKILL.md ≤ 60-line trigger skeleton; references/ strictly on-demand per branch; frontmatter ≤ 500 bytes; no hardcoded /Users/makinja paths</td><td>≤ 60 LOC</td><td>on-demand only</td><td>≤ 500 bytes</td><td>not allowed</td></tr></tbody></table>

**Distribution in current corpus:**

- L0: 32 skills (40.5%) — monolithic, no references
- L1: 38 skills (48.1%) — body &gt; 200 LOC or proactive refs
- L2: 2 skills (2.5%) — sentry-skill-scanner, task-splitter
- L3: 0 skills (0%) — no skill fully meets all L3 criteria

*Note: skill-creator comes closest to L3 intent but is 362 LOC (exceeds the 60-line body target).*

---

## Reference Exemplar

The canonical reference for the L3 pattern is `~/.claude/skills/skill-creator/`.

This skill demonstrates:

- `references/output-patterns.md` — loaded only when generating skill output
- `references/workflows.md` — loaded only for the workflow design step
- Clear "when to Read" callouts in the body
- Frontmatter description that covers all trigger cases without bloat

The canonical pattern from skill-creator states:

> "Keep SKILL.md body to the essentials and under 500 lines to minimize context bloat. Split content into separate files when approaching this limit. When splitting out content into other files, it is very important to reference them from SKILL.md and describe clearly when to read them, to ensure the reader of the skill knows they exist and when to use them."

A true L3 implementation would reduce this further to ≤60-line skeleton with all procedural content in references/.

---

## Anti-Pattern Catalog

All 9 anti-patterns documented (minimum 8 required per spec):

<table id="bkmrk-%23-pattern-detector-h"><thead><tr><th>\#</th><th>Pattern</th><th>Detector heuristic</th><th>Example skill</th><th>Fix</th></tr></thead><tbody><tr><td>1</td><td>`BLOAT_LOC_GT_300`</td><td>`wc -l SKILL.md > 300`</td><td>task-postflight (541L), product-lifecycle (491L), doc-coauthoring (375L)</td><td>Move decision trees and reference tables to references/</td></tr><tr><td>2</td><td>`FRONTMATTER_GT_500B`</td><td>description field bytes &gt; 500</td><td>docx (785B), xlsx (945B), pptx (690B), task-splitter (469B)</td><td>Condense to single-line trigger sentence; move examples to body</td></tr><tr><td>3</td><td>`INLINED_SCRIPT`</td><td>bash/python block embedded in markdown body</td><td>plan-build-test (Playwright CLI commands inline)</td><td>Move to scripts/run-tests.sh; invoke without loading into context</td></tr><tr><td>4</td><td>`DUPLICATE_PROCEDURE`</td><td>Same workflow steps appear in 2+ skills</td><td>product-lifecycle delegates to plan-with-team (6,266 tokens combined on product-lifecycle invocation)</td><td>Extract shared procedure to references/ in one skill; the other references it</td></tr><tr><td>5</td><td>`NO_TRIGGER`</td><td>No `description:` field in frontmatter, or field is empty</td><td>code-review (0B), qa-doc-review (0B), financial-overview (0B), invoice (0B), onboard-client (0B), onboard-partner (0B), send-for-signing (0B), form-filler (0B)</td><td>Add description: field with "Use when..." trigger condition</td></tr><tr><td>6</td><td>`NO_REFS_DIR`</td><td>No references/ subdirectory; entire skill in one file</td><td>70 of 79 skills</td><td>Create references/ dir; move branch-specific content</td></tr><tr><td>7</td><td>`DEAD_30D`</td><td>use\_count=0 AND no log hits in 19-day measurement window</td><td>doc-coauthoring, product-lifecycle, design-system, debugging (all 0 invocations)</td><td>Audit whether skill is still needed; consider retire or merge</td></tr><tr><td>8</td><td>`HARDCODED_PATH`</td><td>`/Users/makinja` embedded in skill body</td><td>learning-opportunity, vault-unlock, form-filler, plan-build-test</td><td>Replace with `$HOME` or relative path; required for Pillar #9 VM portability</td></tr><tr><td>9</td><td>`UNREGISTERED`</td><td>Disk directory exists but missing from skill-registry.db</td><td>17 skills (ask-board, deploy-verify, fiken-agent, hop-build, incident-response, library, lightrag-\*, prompt-forge, sync, task-postflight, task-splitter, template-meta-prompt, vault-unlock, web-search)</td><td>Run `INSERT INTO skills (name) VALUES ('<name>');` or skill-creator registration step</td></tr></tbody></table>

---

## Three-Tier Load Model

The canonical Anthropic pattern (derived from skill-creator/SKILL.md):

### Tier 1 — Always-Loaded (frontmatter only)

- **Content:** trigger condition + one-paragraph overview + when-to-use
- **Location:** YAML `description:` field
- **Target:** ≤ 60 lines total frontmatter / ≤ 1.5K tokens
- **Cost:** paid on every session, regardless of whether skill fires
- **Rule:** Never put procedural steps, code examples, or reference tables here

### Tier 2 — Loaded on Trigger (SKILL.md body)

- **Content:** process steps, branching logic, tool whitelist, output contract
- **Location:** SKILL.md body (everything after frontmatter `---`)
- **Target:** 60-200 lines / token budget ≤ 5K
- **Cost:** paid when skill trigger matches
- **Rule:** Include branch decision table; link to Tier 3 files explicitly

### Tier 3 — On-Demand (references/ and scripts/)

- **Content:** detailed procedures, examples, anti-pattern tables, worked code samples, branch-specific rules
- **Location:** `references/<branch>.md`, `scripts/<action>.sh`
- **Target:** unbounded; each file should be independently useful
- **Cost:** paid only when the agent reads the file on a specific branch
- **Rule:** Agent must see the file reference in Tier 2 SKILL.md body with explicit "when to read" instruction

---

## Canonical Skill Skeleton Template

```
---
name: <kebab-case-name>
description: Use when <concrete trigger>. Does <one-line outcome>.
argument-hint: <stdin-arg>
---

# <name>

## 1. Preconditions (<= 30 lines)
- Hard checks. Abort fast. Cite the hook that enforces if any.

## 2. Branch decision (<= 30 lines)
Pick the procedure, then load it:

| Condition | Procedure |
|---|---|
| <condition-A> | Read `./references/<branch-a>.md` |
| <condition-B> | Read `./references/<branch-b>.md` |

## 3. Sub-agent dispatch contract (<= 40 lines)
- Model tier (Haiku/Sonnet/Opus + rationale)
- Tool whitelist
- Brief path: `./references/<role>-brief.md`
- Output contract (path + format)

## 4. Closure (<= 30 lines)
- mc.js submission shape
- Memory write rule (cite owning skill; do NOT reimplement)

# Body MUST stay under 200 lines.
# Anything longer goes into references/<branch>.md.

```

*This template will be promoted to `~/system/specs/skill-skeleton-canonical.md` as a separate Skillforge step.*

---

[← Top-20 Priority](https://docs.alai.no/books/pillar-4-skills/page/top-20-priority) | [PoC Analysis →](https://docs.alai.no/books/pillar-4-skills/page/poc-task-postflight)