Prime the session with architectural rules for the current task — universal + language + domain + project tiers — the deep pass on top of the rule-prime hook's floor. Auto-fires on the first substantive task, after /clear, and on topic shift; asks before re-priming on drift. Manual trigger /prep. Not for trivial questions.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add AcKeskin/contexture --skill prep --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Prep?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ackeskin-prep)More formats (shields.io, HTML) on the badges page.
---
name: prep
description: "Prime the session with architectural rules for the current task — universal + language + domain + project tiers — the deep pass on top of the rule-prime hook's floor. Auto-fires on the first substantive task, after /clear, and on topic shift; asks before re-priming on drift. Manual trigger /prep. Not for trivial questions."
---
# prep
The prep organ. Consumes [discover](../discover/SKILL.md), [deliver](../deliver/SKILL.md), the [architectural-rules tree](../../architectural-rules/README.md), and project `.claude/architecture.md` (when present, per [project-architecture.md](../../docs/project-architecture.md)).
Prep **prevents** drift by priming Claude with the rules *before* code is written. Review **detects** drift after the fact. Different jobs, complementary.
## When to run
**Auto-fire** (the description field above drives this — Claude reads it and fires the skill at the right moment):
1. **First substantive task of a session.** A substantive task is a code-writing, design, debugging, or review request. Trivial questions, lookups, and "what is X" style prompts do *not* trigger prep.
2. **First substantive task after `/clear`.** Context was wiped; re-prime.
3. **User signals a topic shift.** Phrases like "now let's work on X", "switching to Y", "different question about Z" where Z is a new domain / language / project.
**Manual fire:**
4. User types `/prep` (explicit trigger, e.g. when Claude failed to auto-fire, or the user knows they are about to shift).
5. User asks "prep for this" / "load architectural rules" / "prime for X".
**Do not auto-fire on:**
- Session start itself (nothing to prep against yet).
- Trivial questions / pure information requests ("what does git reflog do?").
- Every message — prep is *per-task*, not per-turn.
## Inputs
- **Task text.** The substantive request that triggered prep. If invoked manually via `/prep [scope-hint]`, use the hint to bias scope detection.
- **Working directory.** `$CLAUDE_PROJECT_DIR` if set, otherwise `cwd`. Determines project context and whether a `.claude/architecture.md` is available.
- **Recent session state.** Earlier turns in the same session (for topic-shift detection).
## Procedure
### 0. Read the floor watermark (rule-prime hook handoff)
The **rule-prime hook** primes the *floor* — always-tier + project-tier rules, plus the one language tier in a single-language repo — mechanically at `SessionStart`, and incremental tiers per prompt at `UserPromptSubmit`. It records what it primed in a per-session watermark (`~/.claude/session-state.json`, key `rulePrime`, keyed by session id): `{ scopes: [...], floorPrimed: true|false, droppedRules: [...], language, polyglot }`. When the floor exceeds its token budget the hook drops rules, sets `floorPrimed: false`, and lists the dropped rule keys in `droppedRules` — the watermark records what actually reached context, and the dropped rules are prep's to backfill.
Before priming, read that watermark:
- **Watermark present + `floorPrimed: true` (and `droppedRules` empty or absent)** → the full floor is already in context. Prep runs the **deep pass**, not a re-prime: announce *"floor primed by the hook (scopes: …) — running deep pass"*, then proceed to step 1 with the floor's scopes treated as already-loaded. In step 4, **do not re-emit** rules whose scope is entirely within the watermark's `scopes` (they are already in context); surface only what the deep pass *adds* — higher top-N, the task-specific domain tier, `.claude/architecture.md`, and any language tier the polyglot floor deferred.
- **Watermark present + `floorPrimed: false` (or `droppedRules` non-empty)** → the floor is **partial**: the rules named in `droppedRules` were resolved but never injected. Announce *"partial floor (dropped: …) — backfilling in deep pass"*, then run the deep pass as above **and re-emit every rule named in `droppedRules`** with its full body in step 4 — even when its scope appears in the watermark's `scopes`. Deferring a dropped rule leaves a silent gap; backfill takes priority over the step-4 dedupe.
- **No watermark (hook disabled, or non-hook environment)** → prep owns the floor as before. Run the full procedure from step 1 with nothing pre-primed. This is the unchanged legacy path — prep degrades gracefully when the hook is off.
The watermark is advisory and read-only here. Prep never writes it; it is the hook's artefact. If the watermark is malformed or unreadable, treat it as absent (full prime) — fail toward priming, never toward a silent gap.
### 1. Identify task scope
**First — resolve the active region (scope-resolution).** Before inferring scope from the task text, run the [scope-resolution resolver](../../docs/scope-resolution-resolver.md) for the task path: the downward longest-prefix walk over `<repo>/.claude/submodules.md` + `<path>/.claude/submodule.md` + `<dir>/.claude/scope.md`. It returns the effective `(corpus-source, scopes, kind, inherit-parent, active-submodule)`. Seed the detection below with this result — the resolved scopes are a prior on Language/Domain, and `corpus-source` selects which corpus the §2 discover call targets (`submodule` → the submodule's own corpus; `parent` → the enclosing corpus + the submodule's scopes; `none` → no rules, an out-of-discipline subtree). **No `submodules.md` (or no match) → single-tree, this step is a no-op and detection proceeds exactly as today** (the no-regression invariant). The walk is prose the resolver doc owns — do not re-derive the manifest formats.
Then, from the task text + project context (seeded by the resolved region), determine:
- **Task type** — one of: `code-writing`, `design`, `debugging`, `review`. Drives `relevance_phases` filter to discover.
- Code-writing: explicit "implement", "add", "write", "refactor", "fix".
- Design: "design", "plan", "how should we structure", architectural questions.
- Debugging: "debug", "not working", "fails with", error traces.
- Review: "review", "look over", "check this code".
- Default when ambiguous: `code-writing`.
- **Language(s).** From file extensions mentioned in the task, cwd-visible repo indicators (`package.json`, `*.csproj`, `CMakeLists.txt`, `.unity` packages), codemap, or explicit mention. Multiple allowed.
- **Domain(s).** From module names (`api`, `ui`, `rendering`, `auth`), task keywords, file paths. Multiple allowed.
- **Project.** The current working directory's project. If `<project-root>/.claude/architecture.md` exists, flag it for explicit read in step 3.
When scope detection is thin (no clear language / domain / obvious keywords), fall back to `[global, universal]` only and note the thin detection in the priming block.
### 2. Build the discover query
Invoke [`skills/discover/SKILL.md`](../discover/SKILL.md) programmatically:
```
{
task_keywords: [<derived from task text>],
scopes: ["universal", <detected language>, <detected domain>, "global", "project-<name>"],
kind: "architectural-rule",
relevance_phases: [<task-type mapping>, "always"],
top_n: 20,
render_bodies: true,
include_recaps: false
}
```
`relevance_phases` mapping:
| task type | phases |
| --- | --- |
| `code-writing` | `always`, `when-language-<lang>`, `when-domain-<domain>`, `when-touching-<X>` (every touching-target the task's files satisfy) |
| `design` | `always`, `during-planning` |
| `debugging` | `always`, `during-debug` |
| `review` | `always`, `during-review` |
`include_recaps: false` is deliberate — prep primes *what rules apply*, not *what I was doing last time*. Recaps are for the discover report, not the priming block.
Discover resolves the architectural-rule tier overlay as part of this call — the rules prep receives are already the *effective* corpus (user / company / project overrides + patches applied, disables dropped, anchors stripped). Prep does not re-resolve; it consumes the resolved set and carries any non-default annotations through to step 5.
### 3. Read `.claude/architecture.md` if present
If the project has `<project-root>/.claude/architecture.md`, Read it and treat its content as an additional fragment. Compose it with the discover output in step 4. Do not rely on discover to surface it — discover's codemap branch covers `codemap.md`, not `architecture.md`.
### 4. Merge, prioritise, cap
Combine discover's rendered fragments + the architecture file content.
**Sort** by specificity (highest → lowest):
1. Project-specific — `scope` includes `project-<name>` tag, or content is from `.claude/architecture.md`.
2. Domain — matched by `scope` containing a domain tag from step 1.
3. Language — matched by `scope` containing a language tag from step 1.
4. Universal — `scope` contains `universal` or `global`.
**Cap:**
- Hard cap at 20 rules. When more match, drop from the lowest-specificity tier first (universal → language → domain, never drop project-specific rules within the cap).
- Soft cap: the priming *summary block* targets < 500 tokens (rule names + one-line gists). Rendered rule bodies delivered on top of it are budgeted separately by deliver's per-body caps — the 500 figure never counts bodies. If the 20-rule set exceeds this, drop lower-specificity rules until the block fits. Do not paraphrase — delivery's source-of-truth rule forbids it.
**Compression:**
- The architectural-rules tree already enforces rule-level compression at storage time. Do not re-compress here.
- If the `.claude/architecture.md` content is long (>10 bullets), pull the most-relevant sections to the task; leave the rest for an explicit user request.
### 5. Surface the priming block
Output shape:
```
Prepped for: <language(s)> / <domain(s)> / project: <name>
Loaded N rules:
Universal: <terse rule list, comma-separated or bulleted>
Language: <terse rule list>
Domain: <terse rule list>
Project: <terse rule list>
Codemap age: X days. Architecture file: present | absent.
```
Rules lines use the rule's `name` field from frontmatter (short, memorable). When a rule's name alone is not self-explanatory, add its one-line description inline — keep each line terse.
**Overlay annotations — non-default only.** A rule overridden / patched / disabled / locked-diverged carries a short tag inline (`[user override]`, `[user patch −1~1+1]`, `[⚠ orphaned anchor]`, `[⚠ LOCKED divergence]`). Plain shipped rules carry no tag — the common case stays clean. This is the only addition to the priming block; it costs tokens only when something actually diverges from shipped.
**Empty-result shape** (no rules matched):
```
Prepped for: <detected scope>
No architectural rules matched.
Either this scope has no captured rules yet, or the task scope was misidentified.
Proceeding without priming. Run /prep manually if you want to provide context.
```
Show the priming block to the user before starting work. They see what was loaded and can correct if irrelevant ("you prepped for cpp but this is a TypeScript file — re-run with `/prep typescript`").
### 6. Record primed scope
Maintain a short in-context note — not a file, ephemeral per session:
```
Primed for: language=<lang>, domain=<domain>, project=<name>. N rules loaded.
```
Update this note every time prep re-runs. It is the comparand for the task-shift rule below.
### 7. Task-shift rule (continuous, not a one-time step)
Throughout subsequent work, observe:
- **Does the current request mention a different module / domain / language than the primed scope?**
- **Is Claude about to read or write files outside the paths implied by the primed scope?**
- **Has the user's intent clearly shifted topic** (even before files are touched)?
When any of those is true, stop and say:
> This looks like it may be moving outside the original scope (primed for **X**; now touching **Y**). Re-prep?
- User answers. On yes → re-run from step 1 with the new scope. On no → proceed with existing priming. Update the primed-scope note either way.
- **Budget:** at most one such prompt per 3 file operations in a row. Prevents thrashing when Claude is touching many files across modules.
- **False-positive cost is low** (user just says "keep going"), **false-negative cost is low** (user can `/prep` manually). Asymmetry favours asking — err on the side of surfacing.
No state tracking of file sets. No silent detection. Observe → surface → ask. Matches the collaborator principle.
**Boundary-cross specialization (scope-resolution).** When the repo has a `submodules.md`, the task-shift watch above gains a sharper trigger: the active region the [resolver](../../docs/scope-resolution-resolver.md) computes for the new task path. The cross-type — and the response — keys off the **filename**, never the contents:
- **Submodule cross** — the task path enters a *different* `submodule.md`-bearing registered path → treat as a re-prep event (the prompt above), noting the region change (`Submodule: services/api (go) → apps/web (ts)`); the new region may carry a new language/corpus.
- **Subfolder cross** — the task path crosses a `scope.md` boundary *within the same submodule* → **silent filter swap**: merge the new scopes, no prompt (it's a refinement, not a region change).
- **Vendored entry** — the task path enters a `kind: vendored` region → surface *"Entered vendored region — discipline disabled. Limit edits to upstream-compatible changes."* and do not propose refactors to that subtree.
This is the same observe→surface→ask mechanism, scoped to declared boundaries. **No `submodules.md` → none of this fires** (no-regression).
### 8. Push-back handling (continuous, not a one-time step)
When the user corrects Claude with reference to a rule ("you violated SoC", "this imports /api directly — go via services", "that's not how we do naming here"):
1. Note the correction.
2. Identify whether the correction maps to:
- **A rule already in the primed set.** Claude missed it — acknowledge, adjust the code, no capture needed (the rule exists).
- **A rule not in the primed set but already captured.** Prep's scope detection missed it — acknowledge, offer to re-run `/prep` with broader scope.
- **A rule that does not exist in the tree.** Propose a capture: *"This correction looks like a new rule. Capture it via `/capture`?"* — invokes [`skills/capture/SKILL.md`](../capture/SKILL.md) with the user's correction text as candidate content. Capture's own confirmation flow runs.
3. Never auto-capture. Collaborator principle.
## Failure modes
- **Scope detection returned `[global]` only.** The task was vague. Surface the thin detection explicitly in the priming block so the user can override. Do not guess a more specific scope.
- **Discover returned zero fragments.** Use the empty-result shape from step 5. Do not fabricate rules.
- **`.claude/architecture.md` is huge (>500 lines).** Read only the sections relevant to the task scope. If relevance is unclear, summarise: *"Project has a large architecture.md — loaded sections matching <scope>; the rest is available on request."*
- **Task-shift prompt fires too often.** Budget kicks in at 1-per-3 file operations. If budget is exhausted and drift still seems real, wait until the next file operation window rather than skipping acknowledgement entirely.
- **Push-back maps to no existing rule AND no clear captureable text.** Ask one clarifying question (*"Should this be a project-specific rule, a language rule, or a universal rule?"*) before proposing capture.
## What prep does NOT do
- **Does not monitor keystrokes or tool calls in real time.** Task-shift is observed at Claude's own judgement boundaries (about to read / write), not continuously.
- **Does not persist primed scope across sessions.** Ephemeral per session.
- **Does not review code for rule violations.** That's review. Prep primes; review audits.
- **Does not auto-capture new rules.** Push-back produces a capture *proposal*, never a silent write.
- **Does not substitute for the user's architectural judgement.** Surfaces rules, the user decides which apply in context.
- **Does not modify rule files.** Read-only over the architectural-rules tree.
- **Does not include session recaps.** `include_recaps: false` on the discover call. Recaps are episodic recall, orthogonal to rule-priming.
## Relationship to other organs
- **discover** — prep's retrieval engine. Prep never re-implements discovery logic.
- **deliver** — prep passes `render_bodies: true`; deliver handles tier ordering and caps within its own contract.
- **capture** — push-back → capture proposal. Prep never writes directly.
- **architectural-rules tree** — the corpus prep primes from. Prep's quality is bounded by the corpus's quality.
- **project-architecture.md** — the project's canonical architectural file. Prep reads it directly (step 3), not via discover.
- **review** — review consumes the same primed scope signal. For now, prep's primed-scope note is session-internal only.
- **recap** — prep does not load recaps into the priming block. Recaps belong in `/discover`-style recall, not rule priming.
- **rule-prime hook** — the mechanical half of priming. The hook owns the *floor* and records it in the `rulePrime` session watermark; prep reads that watermark (step 0) and runs the *deep* pass instead of re-priming. When the hook is off, prep owns the floor (the legacy path). Rationale + the drift flag: [`docs/prep-organ.md`](../../docs/prep-organ.md).
- **persist-before-discard rule + clear-context-decision-guard hook** — prep surfaces the rule like any other when the scope matches session-close; the hook is the mechanical backstop. Rule and hook must stay aligned. Rationale: [`docs/prep-organ.md`](../../docs/prep-organ.md).
See [`docs/prep-organ.md`](../../docs/prep-organ.md) for the scope map and the rationale behind each rule.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!