---
title: Context entry reference
description: Shape and content rules for .claude/context/<domain>.md entries
---

# Context entry reference

Applies to per-domain narrative entries under `.claude/context/`. Skip for `index.md`, which is regenerated by `aitk indexes regen`.

## Scope

Governs per-domain narrative entries under `.claude/context/`: their structure, the decisions and gotchas they carry, and what they leave to the code.

Does not govern:

- Cross-domain decisions and system-wide risks: `architecture.md`
- Product scope, goals, and non-goals: `requirements.md`
- Path-scoped coding rules: `rule.md`
- Diagrams and wireframes, which answer structure and layout questions an entry hands off: `diagrams.md` and `wireframes.md`

## Organizing principle

Weight the entry toward what cannot be re-derived from the repo. That single rule sorts every section below.

- Folder structure is re-derivable with `ls`. Cheap to regenerate, expensive to maintain by hand. Cap it hard.
- Command surfaces are re-derivable with `--help` and already live in the CLI reference under `docs/`. Duplicating flag lists creates a second source of truth that drifts.
- Decisions and gotchas cannot be re-derived at any price. They are the reason the folder exists.

## What a working entry looks like

An entry works when a session can read it and answer three questions without opening source:

- Where do things live in this domain?
- Why are they that way?
- How do I add one more of what this domain holds?

An entry that fails these is non-conforming regardless of whether it satisfies every section and ordering rule below. Shape is the means. These three questions are the test.

## Frontmatter

- `title` (required): sentence case, names the domain (`Web`, `API`, `Agents`).
- `description` (required): one line describing what the domain covers.

Both fields feed `.claude/context/index.md` when regenerated.

## Required sections

- `## Overview`: two to four lines. What the domain owns and where its boundary sits.
- `## Layout`: one line per folder in owns-X form. Folders only, never files.
  - Form: ``- `scripts/lib/` owns shared bash functions sourced by domain scripts``. Do not list every file under that folder with a description each.
  - Implementation detail moves to `## Decisions`, `## Hidden contracts`, or `## Gotchas`.
  - Omit the section when the domain owns no paths in the repo, as with a domain covering external tools. Inventing a line to satisfy the heading is the padding banned below.

## Expected sections

Include whenever the domain has content for them. Never pad an entry with an empty heading.

- `## Decisions`: non-obvious choices and the reasoning behind them. The highest-value section in the folder and the one most often missing.
- `## Gotchas`: workarounds, things tried and rejected, scar tissue worth preserving.

## Optional sections

Pick by what the domain is. Add domain-specific headings as needed.

- `## CLI`: the command surface, only when the domain has one, and only as a list of what each verb does. Flags and JSON shapes stay in the CLI reference under `docs/`, linked rather than restated.
- `## Workflow` or `## Adding a <thing>`: the procedure for the domain's most common task. Most sessions arrive asking how to add one more of the thing the domain holds.
- `## Hidden contracts`: invariants the code does not self-document (shape constraints, skip rules, header semantics). Use `## Decisions` when the reader needs the reasoning rather than the invariant itself.

## Ordering

- Order sections `Overview`, `Layout`, `Decisions`, `Gotchas`, then everything else.
- Entries get read top-down and often partially, so irreducible content sits above recoverable content.

## The development entry

Only the `development` entry carries this section. It is not a general-purpose heading for other domains.

- `## Scripts`: a table of run commands (command plus purpose). The single discoverable surface for how to run the project. Keep run commands here, not scattered across `CLAUDE.md`.

## What goes in

- Per-domain narrative on how the code is structured and why
- Decisions specific to the domain. Broader cross-domain decisions belong in `.claude/ARCHITECTURE.md`.
- Constraints, gotchas, things tried and rejected
- Domain-specific conventions that do not fit a `paths:`-scoped rule
- A reference to another entry, spelled as the path that entry sits at rather than as its bare filename. A bare name resolves against whichever folder the reader is already in, so a domain that splits into subfolders strands every inbound reference and the break surfaces nowhere. A reference to a seed, a standard, or a file the project owns elsewhere keeps the form its own surface uses.

## What does not go in

- Exhaustive file trees with a description per file. Name folders and their responsibility under `## Layout` instead.
- Restated `--help` output, flag tables, or JSON shapes.
- A catalog a `list` command already returns. Link the command instead, so the entry cannot drift from it.
- Function-level documentation for implementation modules. Read the code. The exception is the public surface of a shared utility module, where the entry is how a session finds an existing helper instead of duplicating it.
- Rules. Those go in `.claude/rules/<scope>.md` with a `paths:` glob.
- Tutorials or human onboarding. Those go in `docs/` if a public audience exists.
- Generated content (API references). Generate, do not write by hand.
- Anything already in `.claude/REQUIREMENTS.md` or `.claude/ARCHITECTURE.md`.
- The history of how the domain reached its current shape. An entry describes the repository as it stands, so a change number, release label, or date attached to a change goes wherever the project tracks work.
- A rejected alternative's provenance, which is the same rule at the one place the section above admits history. Keep what was tried and why it lost. Cut who tried it and when.

## Length

- Aim for one entry per domain. There is no hard cap. Length is a symptom, not the defect.
- Past roughly 150 rendered lines, check three things before adding more: whether the entry still covers a single domain, whether it has filled with content `ls` or `--help` reproduces, and whether it has accumulated the history of its own changes. Fix whichever is true rather than trimming to hit a number. Rendered lines count as `markdown.md` defines them.
- Where a bullet sits past the weight checkpoint `markdown.md` states, the overflow to move is the incident that motivated the decision, which specializes that rule's instruction to send the overflow to prose. Keep the current design and the alternative that lost, and send the incident to the change that introduced it, the issue that tracked it, or the research record behind it.
- Never cut a `## Decisions` or `## Gotchas` entry to shorten a file. Cut a `## Layout` or `## CLI` section instead.
- Retire a decision or gotcha once its subject is gone, rewriting the bullet to state the current design rather than leaving the narration of what it replaced beside it. A rejected alternative is not a retired one, so what was tried and why it lost stays whatever its age. The rule above protects content whose subject is live, and this one releases content whose subject is not.
- Rewrite a decision a later one replaced rather than appending the replacement beside it. The subject is still live, so the rule above does not reach it, and two bullets on one subject leave a reader to work out which of them is current. State the design that stands and keep the superseded reasoning only where it is the alternative that lost.
- Split into a folder (`.claude/context/<domain>/<sub-area>.md`) when a domain has three or more sub-areas that do not fit cleanly in one file. That split is the natural ceiling.
- Keep a split domain's `index.md` generated. The catalog body is rewritten on every regen, so the domain's own overview and layout belong in a sibling file rather than in it, and the `subtitle` is what names the file to start with.
- Author a catalog that grows a row per shipped thing as a bullet list, never a markdown table. A table pads its columns to a shared width, so one row outgrowing its column reflows every row and turns a one-line edit into a whole-file rewrite that conflicts with any sibling branch. This is what forced the split above.

## Examples

### Template

```markdown
---
title: API
description: HTTP layer structure, route ownership, and request validation
---

# API

## Overview

Owns the HTTP surface end to end: routing, request validation, and response
serialization. Business logic lives in `src/services/` and is called from here,
never the reverse.

## Layout

- `src/routes/` owns the HTTP layer and request parsing
- `src/services/` owns business logic with no HTTP concerns
- `src/db/` owns persistence and schema migrations

## Decisions

- Validation happens at the route boundary using a schema library. Services trust their inputs.
- Pagination uses opaque cursor tokens, never offset+limit. Cursor format stays opaque to clients.

## Gotchas

- The `/health` endpoint skips auth middleware. Liveness probes from the orchestrator do not carry tokens.
- Database connection pool caps at 50. Concurrent requests over that block until a connection frees.

## Hidden contracts

- Route handlers return a plain object. The serializer wraps it in `{ data, meta }`. Handlers never wrap manually.
- Cursor tokens are base64-encoded JSON of `{ id, sort }`. Any handler that issues a cursor must use the shared encoder.
```
