Skip to content

Instantly share code, notes, and snippets.

@dhpwd
Last active August 10, 2026 20:10
Show Gist options
  • Select an option

  • Save dhpwd/bca9d471a4b34c515be7d23706e17bea to your computer and use it in GitHub Desktop.

Select an option

Save dhpwd/bca9d471a4b34c515be7d23706e17bea to your computer and use it in GitHub Desktop.
context-engineering for Cowork – single-file skill.md (no companion reference files). Write-up: https://danhopwood.com/posts/the-context-engineering-skill
name context-engineering
description Authoring standards for AI context – skills, agents, CLAUDE.md and rules. Use when creating, editing or trimming a skill, agent or CLAUDE.md/rules file, or deciding where an instruction belongs.

Context engineering

Every surface here loads into a context window, so every line is a recurring token cost.

Principles

  • Every line must change behaviour. If deleting a line wouldn't alter what Claude does, delete it. Narration, restated context, obvious implications and motivational framing all go
  • State what to do, not why. Include a reason only where its absence would cause misapplication at edge cases – a rule that looks wrong without it
  • Don't duplicate other context. Global preferences, CLAUDE.md and other skills already load. Copies drift and then conflict
  • Constrain only where being wrong is costly. Hard rules for irreversible or expensive mistakes – everywhere else, let judgement work from surrounding context. Over-constrained instructions misfire on situations the author didn't anticipate, and clash with the rest of the loaded context and with user instructions
  • Don't script trained behaviour. Current models verify, plan and self-correct unprompted, so "double-check your answer", "think step by step" and step choreography for judgement tasks compound with those defaults and degrade output. Delete them rather than tune them – each model upgrade is the cue to re-check
  • Don't ask for the chain of thought in the response. Instructions to show, transcribe or explain internal reasoning can trigger a refusal mid-run. Asking the model to justify its conclusions is fine
  • Positive, natural phrasing. State the do, not the bare don't – a lone prohibition leaves a gap that judgement fills wrong. Where a prohibition is needed, pair it with the replacement ("don't X – do Y"). Write as you'd brief a senior engineer. ALL-CAPS imperatives and "CRITICAL: You MUST" cause overtriggering
  • Write standing instructions, not one-time steps. Content is read at load and never re-read mid-task – phrase guidance to govern everything that follows
  • Design the interface, don't pile on examples. Examples narrow exploration to the cases shown. Prefer structure that implies use: named arguments, templates, enumerated options, a checklist. One example maximum, only where genuine ambiguity remains
  • Progressive disclosure. What always loads carries only what's always needed. Move reference tables, detailed procedures and long examples to the on-demand layer – supporting files for skills, path-scoped rules for CLAUDE.md, linked docs anywhere – each referenced with what it contains and when to load it
  • One skill, one job. If the description needs "and" to cover distinct jobs, split

Where an instruction belongs

Content Home
Facts needed every session – build commands, conventions, gotchas the repo can't tell Claude CLAUDE.md
Guidance for specific files or areas only Path-scoped rule (.claude/rules/ with paths)
Multi-step procedure, or knowledge that should load on a trigger Skill
Deep material for specific work – specs, strategy, domain knowledge Doc, linked or @-mentioned – pulled on demand, so detail is cheap
A worker repeatedly spawned with the same instructions Agent
Must run at a fixed point, or keeps being violated as documentation Hook – CLAUDE.md is context, not enforcement
Derivable from the repo (layout, dependencies, architecture) Nowhere – delete it
Learnings from corrections during work Auto memory – Claude writes it, audit via /memory

Skills: description and invocation

The description is the trigger – Claude matches it against requests to decide when to load the skill.

  • Key use case first, then the phrasings a user would actually type
  • Add "not when ..." only if the skill over-fires
  • Side-effectful workflows: disable-model-invocation: true. Background knowledge with no user-facing action: user-invocable: false

Agents

The same principles apply to agent definitions, with the cost pressure inverted: the body loads per spawn in an isolated window, not per turn in main context. What persists in main context is the agent's description in the roster.

  • The body is the agent's entire system prompt (and when run as the main session via --agent, it replaces Claude Code's default one). It can afford full workflow and output-format detail. Don't over-trim it by applying the per-turn cost test
  • The description is the delegation trigger and the recurring cost – tighten it hardest. It's also all the caller reads, so include what to provide – or delegation prompts under-specify
  • Grant the minimum tools, and check the background filter: background runs (the default) strip most built-in tools, so the same definition resolves to different tools foreground vs background
  • Agents see CLAUDE.md and git status but no conversation history or invoked skills – anything the task always needs goes in the body, preloaded skills or the delegation prompt
  • Route to a cheaper model or lower effort where the job allows

CLAUDE.md and rules

CLAUDE.md loads in full every session with no trigger – the strictest cost case, and adherence drops as it grows. Target under 200 lines per file.

  • Facts and rules only, specific enough to verify ("run npm test before committing", not "test your changes")
  • Path-scoped rules are CLAUDE.md's progressive disclosure – move area-specific guidance there
  • @path imports organise but don't save context – imported files load at launch
  • Contradictions across the loaded files make Claude pick arbitrarily – sweep for them when editing

Finishing checklist

Before calling a new or edited skill, agent, CLAUDE.md or rule done:

  1. Strip pass – delete every line whose removal wouldn't change behaviour
  2. Duplication – nothing restates other loaded context (global preferences, CLAUDE.md, other skills)
  3. Net-diff check (when editing) – diff against the prior version: each deleted or compressed line's behaviour survives elsewhere or is a deliberate drop
  4. Description – would it fire on the real phrasings, and not fire otherwise?
  5. Fresh session test – authoring-session context masks gaps. Verify trigger and output in a clean session
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment