agentleFS
AcKeskinAcKeskin/contexture/skills/prep/SKILL.md

prep

Skill2 starsChanged 6 days agoMITView on GitHub

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.

7 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

11 rules. 0 are common, 5 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 7 edited versions we read keep these.

  • 5

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every message — prep is *per-task*, not per-turn.

    line 29
  2. Distinctive:

    Before priming, read that watermark:

    line 43
  3. Very specific:

    Default when ambiguous: code-writing.

    line 62
  4. Very specific:

    When scope detection is thin (no clear language / domain / obvious keywords), fall back to [global, universal] only and note the thin …

    line 67
  5. Very specific:

    If the project has <project-root>/.claude/architecture.md, Read it and treat its content as an additional fragment.

    line 100
  6. Very specific:

    If the .claude/architecture.md content is long (>10 bullets), pull the most-relevant sections to the task.

    line 121
  7. Distinctive:

    Update this note every time prep re-runs.

    line 162
  8. Distinctive:

    When any of those is true, stop and say:

    line 172
  9. Distinctive:

    No state tracking of file sets.

    line 180
  10. Very specific:

    Boundary-cross specialization (scope-resolution): When the repo has a submodules.md, the task-shift watch above gains a sharper trigger: …

    line 182
  11. Very specific:

    When the user corrects you by a rule: if the rule was primed, fix the code.

    line 192

“Common” is measured: kept by at least 6 in 10 of the 7 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

prep

The prep organ. Consumes discover, deliver, the architectural-rules tree, and project .claude/architecture.md (when present, per 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:

  1. User types /prep (explicit trigger, e.g. when Claude failed to auto-fire, or the user knows they are about to shift).
  2. 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 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 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 typephases
code-writingalways, when-language-<lang>, when-domain-<domain>, when-touching-<X> (every touching-target the task's files satisfy)
designalways, during-planning
debuggingalways, during-debug
reviewalways, 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 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)

When the user corrects you by a rule: if the rule was primed, fix the code; if it exists but wasn't primed, offer to re-run /prep wider; if it doesn't exist, offer /capture. Never auto-capture. Detail: reference.md, Push-back handling.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.