/capture-ready
Author stateful code capture-ready BY CONSTRUCTION, in ANY language — so verification never needs an instrumentation retrofit. Apply whenever writing or substantially reshaping a state machine, workflow, reducer, store, or protocol handler in any session and any language
$ npx -y skills add cognitive-fab/polygraph --skill capture-ready --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/capture-ready
Context preview
The summary Claude sees to decide when to auto-load this skill.
Author stateful code capture-ready BY CONSTRUCTION, in ANY language — so verification never needs an instrumentation retrofit. Apply whenever writing or substantially reshaping a state machine, workflow, reducer, store, or protocol handler in any session and any language
SKILL.md
capture-ready.SKILL.mdname: capture-ready
description: Author stateful code capture-ready BY CONSTRUCTION, in ANY language — so verification never needs an instrumentation retrofit. Apply whenever writing or substantially reshaping a state machine, workflow, reducer, store, or protocol handler in any session and any language (Python, Go, Rust, Java, TS outside polygen, …): shape the module to the eight CR requirements (one named step boundary, declared observable projection, observable rejections, a step-listener seam from the first commit, injected non-determinism, effects declared not awaited, exported scenarios, one in-flight step) so a Polygraph trace corpus falls out of a listener registration instead of an after-the-fact patch. polygen enforces most of this structurally for JS/TS; this skill is how the same discipline reaches everything polygen cannot author. Trigger phrases: "capture-ready", "instrumented from the start", "make it traceable", "write it so we can verify it later", or any request to write stateful/transition logic where polygen is not being used.
capture-ready — write it instrumented, so nobody retrofits traces
The Polygraph toolchain starts working at code-generation time, not at verification time. Every other capture path in this repo answers "the code exists; how do I get traces out of it?" — instrument a copy, keep a patch, hope it doesn't rot. That retrofit is only ever necessary because the code was **shaped** without capture in mind. This skill states the rule for code an agent writes: get the shape right at authoring time and the corpus falls out of a listener registration — no patch, no seam hunt, nothing to re-derive when the code moves.
Source of truth (ships with the plugin — read it when detail is needed): `${CLAUDE_PLUGIN_ROOT}/docs/capture-ready.md`. The retrofit path for code we did NOT write is unchanged (`polygraph` skill Step 2 + `docs/capture-spec.md`) — never reshape someone else's target to make it easier to capture.
> Scope disclosure: capture-ready is not verified and not evidence — a module > can satisfy all eight requirements and be wrong. It is the precondition > that makes verification cheap and repeatable.
When this fires
Any session where you are authoring or substantially reshaping stateful code — a state machine, workflow, reducer, store, saga, protocol handler — in ANY language, with or without polygen. Apply BEFORE the first commit: adding the listener seam to a well-shaped module later is a one-line change; adding a single step boundary to a module that grew three mutation paths is a rewrite. If polygen is in play (JS/TS), it enforces CR-1..CR-4 and CR-8 structurally; your job narrows to CR-5, CR-6, CR-7 as review points.
The eight requirements
- **CR-1 — One named step boundary.** All state change flows through a single
entry taking a named action and its data (`dispatch(action, data)`, `handle(msg)`, `next(state, action, data)`). No second mutation path, no transition logic in a route handler, view, or `useEffect`. A trace window is *defined* by this boundary.
- **CR-2 — Observable state is a declared projection.** One function returns
exactly the contract's state keys — a **snapshot**, never references into a live model (aliasing makes `pre === post` and every window silently reads as a no-op).
- **CR-3 — Rejections are observable.** An action that does not apply
produces an explicit `reject(reason)` and a window with `pre == post` — never a `throw` (the window is lost) and never a silent `return state` (deliberate no-op and unhandled become indistinguishable).
- **CR-4 — A step-listener seam exists from the first commit.** The module
accepts an optional observer firing once per step, after the transition settles, with `{action, data, classification}`. Defaults to a no-op; costs nothing unused. This single requirement is what replaces the instrumentation patch forever.
- **CR-5 — Non-determinism is injected.** Clock, RNG, ID generation, env
reads, locale formatting are constructor/config ports so a scenario can pin them at a seed. Ambient reads make deterministic re-capture impossible without redacting the very fields the transition depends on.
- **CR-6 — Effects are declared, then executed at the edge.** The transition
returns/records effect intent; a caller performs the I/O. No `await fetch(...)` mid-transition. (Also the precondition for running under polyrun, whose journal is the strongest corpus in the system.)
- **CR-7 — Scenarios are exported functions**, callable from plain Node/CLI —
not bodies buried in a test runner. The same drivers serve the test suite, the demo corpus, and any later capture run.
- **CR-8 — One in-flight step per instance.** The step boundary serializes:
a transition settles before the next action presents. This is an observable serialization point, not a thread-safety claim — transactional handlers, queue consumers, actor mailboxes, and per-node apply loops all satisfy it.
The language-neutral contract
Only the emitter changes per language. From the CR-4 listener, write one NDJSON line per step:
{"pre":{…},"action":"NAME","data":{…},"post":{…}}`pre`/`post` are the CR-2 projection. Everything downstream — `validate_corpus.mjs`, `replay.mjs`, `check.mjs`, polyvers' stimuli gate — consumes that shape unchanged, whatever language produced it. For JS the emitters already exist (`scripts/instrument/sam-emitter.mjs` for SAM v2, `tapReducer` in `scripts/instrument/trace-emitter.mjs` for reducer shapes); for anything else, write the few lines by hand at the listener.
Reference shapes for a reducer and a service/class (and the SAM v2 one-liner) are in `docs/capture-ready.md` §"What it looks like" — a store whose `dispatch` computes `pre`, applies the pure reducer, emits, and exposes `getState()` as the projection is the whole pattern in ~10 lines, in any language.
Anti-patterns (each forces a retrofit)
| you are about to write | instea
Read more
name: capture-ready description: Author stateful code capture-ready BY CONSTRUCTION, in ANY language — so verification never needs an instrumentation retrofit. Apply whenever writing or substantially reshaping a state machine, workflow, reducer, store, or protocol handler in any session and any language (Python, Go, Rust, Java, TS outside polygen, …): shape the module to the eight CR requirements (one named step boundary, declared observable projection, observable rejections, a step-listener seam from the first commit, injected non-determinism, effects declared not awaited, exported scenarios, one in-flight step) so a Polygraph trace corpus falls out of a listener registration instead of an after-the-fact patch. polygen enforces most of this structurally for JS/TS; this skill is how the same discipline reaches everything polygen cannot author. Trigger phrases: "capture-ready", "instrumented from the start", "make it traceable", "write it so we can verify it later", or any request to write stateful/transition logic where polygen is not being used.
capture-ready — write it instrumented, so nobody retrofits traces
The Polygraph toolchain starts working at code-generation time, not at verification time. Every other capture path in this repo answers "the code exists; how do I get traces out of it?" — instrument a copy, keep a patch, hope it doesn't rot. That retrofit is only ever necessary because the code was **shaped** without capture in mind. This skill states the rule for code an agent writes: get the shape right at authoring time and the corpus falls out of a listener registration — no patch, no seam hunt, nothing to re-derive when the code moves.
Source of truth (ships with the plugin — read it when detail is needed): `${CLAUDE_PLUGIN_ROOT}/docs/capture-ready.md`. The retrofit path for code we did NOT write is unchanged (`polygraph` skill Step 2 + `docs/capture-spec.md`) — never reshape someone else's target to make it easier to capture.
> Scope disclosure: capture-ready is not verified and not evidence — a module > can satisfy all eight requirements and be wrong. It is the precondition > that makes verification cheap and repeatable.
When this fires
Any session where you are authoring or substantially reshaping stateful code — a state machine, workflow, reducer, store, saga, protocol handler — in ANY language, with or without polygen. Apply BEFORE the first commit: adding the listener seam to a well-shaped module later is a one-line change; adding a single step boundary to a module that grew three mutation paths is a rewrite. If polygen is in play (JS/TS), it enforces CR-1..CR-4 and CR-8 structurally; your job narrows to CR-5, CR-6, CR-7 as review points.
The eight requirements
- **CR-1 — One named step boundary.** All state change flows through a single
entry taking a named action and its data (`dispatch(action, data)`, `handle(msg)`, `next(state, action, data)`). No second mutation path, no transition logic in a route handler, view, or `useEffect`. A trace window is *defined* by this boundary.
- **CR-2 — Observable state is a declared projection.** One function returns
exactly the contract's state keys — a **snapshot**, never references into a live model (aliasing makes `pre === post` and every window silently reads as a no-op).
- **CR-3 — Rejections are observable.** An action that does not apply
produces an explicit `reject(reason)` and a window with `pre == post` — never a `throw` (the window is lost) and never a silent `return state` (deliberate no-op and unhandled become indistinguishable).
- **CR-4 — A step-listener seam exists from the first commit.** The module
accepts an optional observer firing once per step, after the transition settles, with `{action, data, classification}`. Defaults to a no-op; costs nothing unused. This single requirement is what replaces the instrumentation patch forever.
- **CR-5 — Non-determinism is injected.** Clock, RNG, ID generation, env
reads, locale formatting are constructor/config ports so a scenario can pin them at a seed. Ambient reads make deterministic re-capture impossible without redacting the very fields the transition depends on.
- **CR-6 — Effects are declared, then executed at the edge.** The transition
returns/records effect intent; a caller performs the I/O. No `await fetch(...)` mid-transition. (Also the precondition for running under polyrun, whose journal is the strongest corpus in the system.)
- **CR-7 — Scenarios are exported functions**, callable from plain Node/CLI —
not bodies buried in a test runner. The same drivers serve the test suite, the demo corpus, and any later capture run.
- **CR-8 — One in-flight step per instance.** The step boundary serializes:
a transition settles before the next action presents. This is an observable serialization point, not a thread-safety claim — transactional handlers, queue consumers, actor mailboxes, and per-node apply loops all satisfy it.
The language-neutral contract
Only the emitter changes per language. From the CR-4 listener, write one NDJSON line per step:
{"pre":{…},"action":"NAME","data":{…},"post":{…}}`pre`/`post` are the CR-2 projection. Everything downstream — `validate_corpus.mjs`, `replay.mjs`, `check.mjs`, polyvers' stimuli gate — consumes that shape unchanged, whatever language produced it. For JS the emitters already exist (`scripts/instrument/sam-emitter.mjs` for SAM v2, `tapReducer` in `scripts/instrument/trace-emitter.mjs` for reducer shapes); for anything else, write the few lines by hand at the listener.
Reference shapes for a reducer and a service/class (and the SAM v2 one-liner) are in `docs/capture-ready.md` §"What it looks like" — a store whose `dispatch` computes `pre`, applies the pure reducer, emits, and exposes `getState()` as the projection is the whole pattern in ~10 lines, in any language.
Anti-patterns (each forces a retrofit)
| you are about to write | instea
Your tests check the paths you thought of. Polygraph checks the ones you didn't.
Repo: cognitive-fab/polygraph
Other skills on polygraph.
- /polyviz
Turn Polygraph verification artifacts into clean, brand-consistent diagrams (SVG, optional PNG). polyviz is a DETERMINISTIC, artifact-derived renderer — same inputs produce byte-identical output and it makes no model call at render time. Use when the user wants to "visualize /
Open skill - /polygen
Write NEW stateful code that is verifiable from the moment it's written, instead of auditing code that already exists (that's the "polygraph" skill). Draft a contract from a feature description, author a SAM v2 strict-profile module against it (named intents/schemas/domains,
Open skill - /polygraph
A polygraph for your state machine. Audit a stateful piece of code end-to-end: YOU (the agent) instrument a copy, build any test doubles needed to run it, and capture real execution traces, then derive a transition-function spec from its source with an LLM (default artifact: a
Open skill - /polynv
Elicit the invariants for a state machine — the plugin takes the lead. Harvest candidate invariants from the contract's own vocabulary (terminal states, typed fields, reject rules, effect kinds), contribute the frontier model's domain knowledge as candidates, pre-check every
Open skill - /polyvers
Check whether a state-machine version change is safe to ship against the live fleet, and produce the migration when the shape changed. Classifies the change into compatibility lanes (shape, vocabulary, intent, semantic, migration, composition), runs the mechanical gates those
Open skill - /workflow
Build an LLM-era feature as a WORKFLOW, not an agentic loop — the composition skill that drives the whole toolset end-to-end. Design the stages along the data flow with the user (each failure either bends back to ONE named stage carrying its exact signal under a bounded budget,
Open skill

