From frame
Context preservation methodology applied when writing, editing, refactoring, debugging, reviewing code or designing modules/architecture. Pins per-directory responsibilities, entry points, and domain terms through INLAY.md, and preserves non-obvious decisions through WHY comments.
How this skill is triggered — by the user, by Claude, or both
Slash command
/frame:inlayThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<inlay>
Discipline and guardrails for an agent's code work. Pin codebase context next to the code so the agent does not pay the cost of rediscovering truth on every task.
Apply on writing, editing, refactoring, debugging, reviewing code, and designing modules. Effect is largest on mid-sized or larger codebases and on long-running work.
Before writing code:
Test: "If this interpretation is wrong, will the user have to ask for the work again?" → ✓ → confirm before starting.
When to apply: introducing a new module, a change that crosses inlay boundaries, or when the scope of the work is unclear. For self-evident in-file edits, the auto-injected context is enough.
When starting code exploration after receiving a request:
search to see the tier-1 inlay list and their purpose. Narrow down which tier-1 inlay this work touches (or whether it touches none).Test: "Do you know the entry contracts and internal responsibilities of every inlay this work touches before starting?" → ✓ → proceed.
Place an INLAY.md at the codebase root. Any directory containing an INLAY.md is an Inlay. When exploring an inlay, read the INLAY.md and its entry point first; descend into inner files only when needed — do not re-read the entire inlay on every task. Inlays can nest (child inlay inside a parent).
Fixed INLAY.md shape:
---
name: <inlay name>
purpose: <one-line responsibility>
entry: <entry-point path> # single file
entry: [<path>, <path>, ...] # multiple files
when:
- <invocation context>
---
## Domain Terms
- **<domain term>** — <definition>
name, purpose, entry, when).when — high-level scenarios in which the agent invokes this inlay. 1–3 bullets recommended. Needing more is a signal that the inlay's responsibility has grown too wide; consider splitting.## Domain Terms — only when present. A domain term is a name whose meaning is fixed inside the inlay. Exclude generic words and identifiers whose meaning is closed by language convention. A child inlay's domain terms live in the child INLAY.md only.Split test: "Can internal changes or failures affect code outside the inlay without going through entry?" → ✓ → the boundary is drawn wrong.
Splitting: when a split is reported, propose it to the user. Split an inlay only when the user approves or explicitly asks. Do not mix changes and splits in one go.
Synchronization: when an inlay's entry points or domain terms change, update INLAY.md alongside the code. Breaking changes go through INLAY.md and the code in the same PR.
entry is the single source of truth for the inlay's outward contract. Pin the following so an agent can call and review by reading entry alone:
entry's exports. Symbols not in entry do not exist outside the inlay.Result<T, E>).Non-obvious preconditions, postconditions, invariants, external dependencies, and concurrency models also belong in the docstring when they apply.
The entry point is a source file inside the inlay directory. When the outward contract fits in one file, write a single path (e.g. entry: index.ts). When it spans several files, list them as an array (e.g. entry: [routes.ts, schema.ts]). Do not maintain a separate markdown interface document.
Multi-file entry test: "Is each entry file a different facet of the same outward contract?" → ✗ → signal that the inlay's responsibility has grown too wide; consider splitting.
Across all INLAY.md files in the repo (parent / child / sibling, all the same), the following are violations:
Inside one inlay, use one name per concept. When the external API and internal representation differ (e.g. snake_case vs camelCase), map explicitly at the entry boundary; past that, use a single name internally.
Form: // WHY: reason. Use the language's comment marker (#, /* */, etc.). For multi-line, tag only the first line and indent continuation lines.
// WHY: This updates shared state, so parallelizing it would cause a race condition.
// Sequential execution must be preserved.
Before writing a WHY comment, first complete this sentence:
"From the code alone, the reader would not know ___."
If you can fill the blank with one concrete fact → that fact is the WHY body. If you cannot fill it, or only abstract phrases come up ("for safety", "to prevent X", etc.) → do not write the comment.
Common shapes the blank takes:
Even if none of these shapes fit, a concrete blank is still a WHY. Even if one of them seems to fit, an abstract blank is WHAT.
Signs the blank is not filled:
When editing or removing a WHY: line, first verify the comment's condition still holds. If it no longer holds, update both the comment and the code. Never change the code while leaving the comment.
Even on lines without a WHY: comment, do not touch what is outside the request:
Test: "Does every changed line trace directly to the user's request?"
The plugin's hooks intercept Read / Edit / Write / MultiEdit / NotebookEdit calls and automatically inject the ancestor INLAY.md chain of the targeted file as a system-reminder.
<inlay-context path="...">...</inlay-context> blocks listed root → leaf.Edit/Write/MultiEdit/NotebookEdit with target file INLAY.md) suppress chain injection — this prevents the inlay's own body from being re-injected into the prompt as a self-loop.Because automatic injection is independent of explicit tool calls, the agent normally does not need to call the tools by hand. For cases that do require an explicit call, see the tool section below.
Use the following tools instead of reading INLAY.md directly:
search — At a given location, find the INLAY.md there and in immediate children one level deep (deeper nesting is ignored). Returns a JSON array of name, purpose, path. Tool name: mcp__inlay__search. Args: { path?: string } (defaults to cwd). When to call: the tier-1 inlay scan in step 1 of Task entry procedure. For deeper trees, descend one level at a time during step 3 recursion.read_context — Read the ancestor INLAY.md chain from a given path up to the nearest .inlay ancestor directory (stops at, and includes, that .inlay directory; never above it). If no .inlay ancestor exists, the path is outside any inlay scope and the result is empty. Output is a string of <inlay-context path="...">...</inlay-context> blocks, top-down. INLAY.md already served in this session with the same hash appears with (already read) as the body (lifetime: MCP server process). Tool name: mcp__inlay__read_context. Args: { path?: string } (defaults to cwd). When to call: when you want to peek at another inlay's context before editing (the prospective lookup in step 2 of Task entry procedure). The normal in-file flow is handled by automatic injection.doctor — Checks for broken frontmatter (4 fields: name/purpose/entry/when), empty when list, and body over 300 lines. On violation, prints a <inlay-instruction> block with the prescription. Run: node $CLAUDE_PLUGIN_ROOT/guardrails/inlay/context-doctor.mjs [<root>]. Defaults to cwd. exit 0. When to call: right after creating or editing an INLAY.md, to verify it.INLAY.md. The unit of exploration where the entry point and INLAY.md are read first.entry field.WHY: comment — A comment recording "why this was done."npx claudepluginhub hve4638/cc-toolkit --plugin frameGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Resolves in-progress git merge or rebase conflicts by analyzing history, understanding intent, and preserving both changes where possible. Runs automated checks after resolution.