Skip to main content

Generated artifacts

ratchet init and ratchet init re-runs (update mode) produce two categories of output: the .ratchet/ directory tree that holds all planning and spec data, and per-tool skill and command files written under each selected AI tool's configuration directory.

.ratchet/ directory layout

init creates the following directories at the project root. batches/ and evals/ are created lazily by the commands that need them.

.ratchet/
├── features/ # permanent, living feature store
├── standards/ # project standards library (empty at init)
├── changes/
│ └── archive/ # completed changes, date-prefixed
├── batches/ # batch manifests (created lazily by ratchet new batch)
├── evals/
│ ├── specs/ # eval-spec YAML bindings (opt-in)
│ └── fixtures/ # checked-in fixture codebases (opt-in)
└── config.yaml # project config (schema + optional context/rules)

init also ensures the project-root .gitignore ignores the transient eval run-records directory (see the table below).

PathDescription
features/Permanent Gherkin feature store. ratchet archive copies a change's .feature files here by whole-file replacement. Organized by capability: features/<capability>/<name>.feature.
standards/Project-level guideline documents. Created empty by init; populated by /rct:propose-standard. Each file is a Markdown document with an optional tag: frontmatter field.
changes/Active change directories. Each subdirectory is one change (changes/<name>/).
changes/archive/Completed changes moved here by ratchet archive. Directory name is YYYY-MM-DD-<name>.
batches/Batch manifests. Each batch is batches/<name>/batch.yaml. Created when ratchet new batch first runs, not by init.
evals/specs/YAML eval-spec files. Each file maps case IDs to judge bindings (fixture, kind, check or success). Read by ratchet eval.
evals/fixtures/Checked-in fixture codebases. Each fixture is a directory (evals/fixtures/<name>/) that eval materializes into a throwaway working copy before judging.
config.yamlProject configuration. Contains at minimum schema: ratchet. May include batch.permissions for agent sandbox policy. Created by init when it does not already exist; never overwritten on re-runs.
.gitignore (project root)init idempotently ensures the project-root .gitignore contains .ratchet/evals/runs/, so transient eval run records never dirty the working tree or the mutation invariant gate. The file is created if absent and the entry appended only if missing; a re-run never duplicates it.

Per-tool skills and commands

For each AI tool selected during init, ratchet writes two kinds of generated files: skills (agent skill markdown files under the tool's skills/ directory) and commands (slash-command or prompt files in the tool's command directory). Both are fully regenerated on every init re-run.

Skill files

Each skill is a SKILL.md file inside a named subdirectory under <tool-dir>/skills/. The file contains a YAML frontmatter block followed by the skill instructions.

Frontmatter fields written by ratchet:

FieldValue
nameSkill name (e.g. ratchet-propose)
descriptionOne-sentence description of the skill
licenseMIT
compatibilityRequires ratchet CLI.
metadata.authorratchet
metadata.version1.0
metadata.generatedByInstalled ratchet version (e.g. 0.9.0)

Command files

Each command is a Markdown file with YAML frontmatter. The file path and frontmatter format vary by tool; the body content is the same workflow instruction.

Tool paths

ToolskillsDirSkill path patternCommand path pattern
Claude Code.claude.claude/skills/<dir>/SKILL.md.claude/commands/rct/<id>.md
Cursor.cursor.cursor/skills/<dir>/SKILL.md.cursor/commands/rct-<id>.md
Codex.codex.codex/skills/<dir>/SKILL.md~/.codex/prompts/rct-<id>.md (global; respects CODEX_HOME)
Gemini.gemini.gemini/skills/<dir>/SKILL.md.gemini/commands/rct-<id>.md
GitHub Copilot.github.github/skills/<dir>/SKILL.md.github/prompts/rct-<id>.prompt.md
OpenCode.opencode.opencode/skills/<dir>/SKILL.md.opencode/commands/rct-<id>.md

Workflows: core profile vs. eval opt-in

The core profile (the default) installs eleven workflows. The eval workflow is opt-in and only installed when a custom profile explicitly lists it.

Core profile workflows (installed by ratchet init by default):

Workflow IDSkill directory/rct: command
proposeratchet-proposepropose
applyratchet-apply-changeapply
verifyratchet-verify-changeverify
archiveratchet-archive-changearchive
propose-standardratchet-propose-standardpropose-standard
brainstormratchet-brainstormbrainstorm
apply-batchratchet-apply-batchapply-batch
archive-batchratchet-archive-batcharchive-batch
propose-batchratchet-propose-batchpropose-batch
decompose-phaseratchet-decompose-phasedecompose-phase
open-prratchet-open-propen-pr

The open-pr command is also the artifact the batch engine renders into the spawn locus for the whole-batch PR step: at batch completion the engine spawns a PR agent that delegates to /rct:open-pr to commit the accumulated work in the repo's git log commit style, push the work branch, and open exactly one forge-agnostic PR to its base branch. Like every command it is generated for every tool above at the tool's command path (e.g. claude .claude/commands/rct/open-pr.md, cursor .cursor/commands/rct-open-pr.md).

The decompose-phase command is also the artifact the batch engine renders into the spawn locus when batch apply drives a phase decomposition (it delegates to /rct:decompose-phase <phase> to author a reachable empty phase's change intents into batch.yaml). The decomposition spawn routes through the decompose agent stage — so agent.decompose (or a scalar agent) selects which agent runs it, exactly as the pr stage selects the PR agent. Like every command it is generated for every tool above at the tool's command path (e.g. claude .claude/commands/rct/decompose-phase.md, cursor .cursor/commands/rct-decompose-phase.md).

Opt-in workflow (custom profile only):

Workflow IDSkill directory/rct: command
evalratchet-evaleval

The active profile is read from the global ratchet config. Pass --profile core or --profile custom to ratchet init to override it for that run.

Scope reconciliation in the change-authoring workflows

The propose, propose-batch, and decompose-phase workflows carry a shared set of scope-reconciliation rules. The rules are authored once in src/core/templates/workflows/scope-reconciliation.ts and interpolated into each workflow body, so every generated skill and command for every tool in the table above renders the same text.

Overview

Originating-issue reconciliation

propose and propose-batch each run an originating-issue reconciliation step before any artifact is authored — in propose it is step 2, before the change directory is created; in propose-batch it is step 4, before ratchet new batch scaffolds the manifest. The step requires:

Sub-stepRequirement
IdentifyCollect every originating issue — referenced by the user, by a manifest phase or change intent, or by an injected done criterion.
FetchRead each issue through the project's issue tracker. gh issue view <n> is named as a GitHub example; no tracker or command is required. When no tracker client is available, the user is asked to paste the issue text.
EnumerateList the issue's material requirements from both its explicit fix items and the problems named in its narrative. Hedged wording (consider, maybe, optionally) does not lower the bar for a security-, permission-, or integrity-relevant requirement.
MapPoint every enumerated requirement at the feature scenario or plan task that covers it. In propose-batch the target is the phase goal, the phase success criterion, or the change-level done.
ListWrite out every requirement the authored scope does not cover.
SurfacePresent each uncovered requirement to the user as an enumerated "issue asks X, this proposal does not include X" decision point before artifacts are finalized. Writing an omission into plan prose as self-approval is prohibited.

Close-claim rules

A Fixes #N / Closes #N claim — in a batch manifest done, in a plan, or in a pull-request body — is permitted only when the issue's material requirements are actually implemented. A close-claim is an output of verification, never an input of planning. Work covering only part of an issue states "partially addresses #N" and does not state Fixes #N or Closes #N.

propose-batch applies this to the manifest specifically: Closes #N / Fixes #N must not be hard-coded into a phase goal, a phase success criterion, or a change-level done for work not yet scoped and verified. Phase contracts reference an issue as "targets #N" or "addresses #N"; the closing linkage is earned at pull-request-authoring time.

Stop-and-surface guardrail

All three workflows carry the guardrail in their Guardrails section. A de-scope of security-, permission-, or integrity-relevant work halts the workflow and asks the user rather than proceeding on momentum. An approved deferral requires a tracking issue that is explicitly filed, carries a named owner, and is linked from the change plan before the workflow proceeds; a prose bullet in plan.md is not a deferral mechanism.

Deferral carry-forward in decompose-phase

decompose-phase grounds a phase in the prior phases' shipped results. Its grounding step additionally requires:

  • Reading each prior phase's shipped change plan.md, not only the injected done criteria. The injected criteria are a paraphrase in which deferrals recorded as plan prose are invisible.
  • Extracting every ## Out of scope, deferred, revisit, later phase, follow-up, or equivalent item recorded in those plans.
  • Resolving each extracted item as exactly one of three outcomes: carried forward as a change intent in the phase being decomposed, tracked against an existing open tracking issue, or explicitly dropped by the user. Silently ignoring an extracted item is not an available outcome.
  • Verifying that a prior phase's Fixes #N / Closes #N claim was earned before the issue is treated as shipped. An unearned claim is surfaced and its remaining scope carried forward, never inherited as fact.

Change directory artifacts

ratchet new change <name> scaffolds a change directory at .ratchet/changes/<name>/. The propose workflow writes the two required artifacts into it.

.ratchet/changes/<name>/
├── features/
│ └── <capability>/
│ └── <name>.feature # Gherkin: Feature / Scenario / Given-When-Then
├── plan.md # ## Why / ## What Changes / ## Design / ## Tasks
├── .ratchet.yaml # change metadata
└── .run/
├── journal.jsonl # append-only engine run log
└── state.json # current change state snapshot

features/<capability>/<name>.feature

Gherkin feature file. One or more files may exist under features/ grouped by capability. Each scenario must contain at least one Given, one When, and one Then step. The features/ directory may also contain a .deleted tombstone file listing store-relative paths to remove from the permanent feature store on archive (one path per line; blank lines and #-prefixed lines are ignored).

plan.md

Plan document with four required top-level sections:

SectionPurpose
## WhyMotivation and problem statement
## What ChangesScope description
## DesignTechnical design; active standards are embedded here by propose
## TasksMarkdown checklist (- [ ]) tracked by the apply phase

.ratchet.yaml

Change metadata file. Fields:

FieldTypeDescription
schemastring (required)Workflow schema name (e.g. ratchet)
createdstring (YYYY-MM-DD)Date the change was created
standardsstring arrayTags of standards this change follows (e.g. [security, testing])

.run/ (change-local run state)

journal.jsonl and state.json hold the engine run state for the change when it is driven by a headless verb (ratchet propose, ratchet apply, ratchet verify). When a change is driven inside a batch, run state is written at .ratchet/batches/<batch>/run/ instead. See Run-state locus.

Standards model

Each standard is a Markdown file at .ratchet/standards/<name>.md with an optional YAML frontmatter block.

Frontmatter field:

FieldDescription
tagStable identifier for the standard. Falls back to the file-name stem when absent. Changes and features reference standards by tag, not by file name.

Example:

---
tag: security
---

# Security standard

...

When ratchet archive runs and the change declares one or more standard tags in its .ratchet.yaml, two link structures are written into the permanent store:

Forward links — per-capability sidecar

.ratchet/features/<capability>/.ratchet.yaml maps each feature file within that capability to the standard tags the contributing change declared. The sidecar YAML structure:

features:
<feature-file-relative-to-capability>:
- <tag>
- <tag>

Tombstoned features (listed in features/.deleted) have their entries removed from the sidecar on the same archive run.

Reverse links — ## Implemented by block

Each .ratchet/standards/<tag>.md that has at least one implementing feature receives a generated ## Implemented by section appended by ratchet. The block lists the store-relative paths of all feature files that implement the standard. It is regenerated from the forward sidecars on every archive run — ratchet never appends to it incrementally. Standards with no implementing features have the block removed or never gain one.

The block is delimited by an HTML comment marker so ratchet can locate and replace it idempotently:

## Implemented by

<!-- ratchet:implemented-by — generated from .ratchet/features/<capability>/.ratchet.yaml; do not edit by hand -->

- <capability>/<name>.feature