CodeHerderSearch⌘KRequest access →

A repository's project folder

Commit a .codeherder folder to a repo to keep a team's own workflow, stage, and rubric documents in the codebase.

A .codeherder folder at the root of a repository is a place for a team to keep its own workflow, stage, and rubric documents alongside its code. Commit it, and everyone who clones the repo gets those documents too.

It’s not the same thing as .codeherder.env — see It’s not .codeherder.env below if that’s what you’re after.

Creating or adopting it

Run this from anywhere inside your checkout:

ch project init

It’s offline: no sign-in and no server request. It looks at .codeherder in your repository root and does exactly one of these things:

  • Nothing there yet — it creates the folder and tells you to git add it.
  • A real folder already there — it leaves it untouched and reports what it found.
  • A leftover link from a torn-down session — CodeHerder sometimes leaves a symlink at this path after a sandbox is cleaned up. ch project init recognizes its own link, removes it, and creates a real folder in its place.
  • Anything else — a file, or a symlink to something CodeHerder didn’t create — it refuses and changes nothing, so you can sort out what’s there yourself.

ch project init never runs git. Stage and commit the folder yourself once it’s created:

git add .codeherder
git commit -m "Add project folder"

What goes in it

Your team’s documents live in three subdirectories of .codeherder:

  • workflows/ — workflow documents, one per task type.
  • stages/ — stage documents your workflows can reference.
  • rubrics/ — rubric documents for stages that judge their own output.

ch project init creates the folder empty. Make whichever of these subdirectories you need yourself.

Document format

Each file is one JSON document. The preview rejects a file that does not match this format.

{
  "schema_version": 1,
  "kind": "stage",
  "key": "code",
  "label": "Code",
  "content_hash": "<64 hex characters>",
  "body": { "StageKey": "code", "Label": "Code", "Spec": { "prompt": "..." }, "Fields": [] }
}

Envelope fields

Field Required Meaning
schema_version yes Must be 1.
kind yes stage, workflow, rubric or wiki.
key yes Lowercase letters, digits and _. It starts with a letter and has at most 64 characters.
label yes The display name. It must match the label inside the body.
archived_at no A timestamp that marks the document archived. Leave it out.
requires no The documents this one needs. Each entry is {"kind": ..., "key": ...}.
content_hash yes The hash of the document. See below.
body yes The content. Its shape depends on kind. Unknown keys fail.

Body shape per kind

  • stage — StageKey, Label, Spec and Fields. These keys use Go case. StageKey and Label must match the envelope. Keys inside Spec use snake case, such as prompt and writable. This is not the {label, spec, fields} document that ch stage create --stage-file takes.
  • workflow — a composition: key, label, instances, fields and the other keys that ch workspace workflow composition prints. key and label must match the envelope.
  • rubric — key, stageKey, artifact, levels and criteria.
  • wiki — {"file": "<OKF file text>"}.

The requires list

A workflow lists each stage that its instances use. A stage lists each rubric that its verifications name. A workflow that uses a stage from your workspace library needs that stage document in the folder too.

How content_hash is computed

  1. Copy the document and set content_hash to an empty string.
  2. Rewrite body with its object keys sorted. Keep array order and number text.
  3. Convert archived_at, if present, to UTC.
  4. Write the envelope as compact JSON. Keep the field order of the table above.
  5. Escape strings as Go json.Marshal does:
    • Write <, > and & as \u003c, \u003e and \u0026.
    • Write U+2028 and U+2029 as \u2028 and \u2029.
    • Keep all other non-ASCII characters as UTF-8.
    • Use no other escapes than the ones JSON requires.
  6. Take the SHA-256 of those bytes and write it as lowercase hex.

Get a valid file

Do not write the hash by hand. Export a document from the server:

ch stage show code --as-project-doc > .codeherder/stages/code.json
ch workspace workflow composition story --as-project-doc > .codeherder/workflows/story.json

Both commands print the document with no {data} wrapper. A local edit to the body changes the hash. After a local edit, recompute the hash with the steps above. Or edit the stage or workflow on the server, then export again. The --as-project-doc flag cannot combine with --json. A disabled stage still exports, with no archived_at.

Where these documents take effect

This is the part worth being precise about: today, a project document only affects what you see when you run

ch workflow show --offline --type story

Name whichever task type you want to look at, such as story, bug, or auto. If you name one that doesn’t exist, the error lists the ones you can choose from.

That command composes a workflow entirely on your machine, no sign-in required. It starts from CodeHerder’s built-in workflow for the type you name, then layers your project’s workflows/, stages/, and rubrics/ documents on top, with your project’s version winning wherever the two overlap.

The preview reads your working tree, so a document you’ve just saved is already picked up. You don’t need to commit it first. Committing is how you share it with your teammates.

To preview documents kept somewhere else, name the directory that holds them with --project-dir:

ch workflow show --offline --type story --project-dir ~/workflow-drafts

CodeHerder then reads only that directory, and ignores your checkout’s .codeherder folder. It picks up every .json file underneath, at any depth, and each one has to be a workflow, stage, or rubric document. One stray .json file stops the command.

So name a directory that holds only those documents. A whole .codeherder folder qualifies, as long as nothing else under it is a .json file. Point the flag at one subdirectory, such as .codeherder/workflows, and it reads only that one. Your stage and rubric documents stay out of the preview.

Committing a project document does not, by itself, change the pipeline a task runs on the server. ch workflow show --offline is a local preview. To change what a task actually runs, use Customising a task’s workflow or Customising workflows instead.

It’s not .codeherder.env

.codeherder (this folder) and .codeherder.env (a single file) share a name and both live at your repository root, but they do unrelated things. .codeherder.env sets your default server and workspace for the ch CLI — see Project defaults for the CLI.

Last updated

CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close