Skip to content
stacks
Docs menu

The brief and the manifest

Understand the two files stacks new writes, what each section of the brief tells the agent, and which parts of .stacks/ you commit.

View as MarkdownOpen in ClaudeOpen in ChatGPT

stacks new and stacks add write two files for your agent. .stacks/BRIEF.md is the agent's task for building the project. .stacks/manifest.json is the project's definition of done, which you commit and keep for the life of the project.

How the brief and the manifest differ

The brief is prose for an agent: long, specific to this build, and no longer needed once the project is green. The manifest is data for stacks verify: short, exact, and still used a year later by someone who clones the repository. Keeping them in separate files lets the instructions run as long as they need to while the checks stay small and machine-readable.

What new writes

Here is a sandboxed go-cli project straight after new. The rest of this page uses the same project.

stacks new go-cli demo --sandbox --no-launch
Terminal
.gitignore
BRIEF.md
manifest.json
NOTES.md
state/
demo/.stacks/
Path What it holds Committed
.stacks/manifest.json The stack, fragments, preset, agents, commands, environment defaults and verify steps, plus a digest of the steps Yes
.stacks/BRIEF.md The agent's task No
.stacks/NOTES.md The agent's notes: questions it asked under ## Asked, problems with the brief under ## Findings No
.stacks/state/runs.jsonl One line per verify run No
.stacks/incoming/ Files add couldn't write because the project already had them No

.stacks/.gitignore ignores the brief, the notes, state/ and incoming/, so a normal git add . commits only the manifest.

One more record lives outside the project: a state record under ~/.local/state/stacks/projects/<projectId>.json (or $STACKS_STATE_DIR/projects/). It holds a second copy of the verify digest and the project's timings. Verify explains why it exists.

The brief

The brief is assembled from fixed CLI text and the composed entries, in this order:

Section What it says
Header Stack, fragments, preset, target agents, the project root and the files stacks wrote
## Your job Done means stacks verify exits 0 with outcome green. Work autonomously and stop only for decisions and missing tools
## Versions Nothing is pinned. Use current stable versions, prefer official generators, check current docs before writing config
## Ground rules Run generators non-interactively and away from the project root, keep AGENTS.md accurate, keep NOTES.md up to date
## Decisions Every entry's decisions, each with its default
## Dependencies and tools Packages by role, names only, and whether each required tool is on PATH
One section per entry The stack's guidance, then each fragment's
## Definition of done The verify steps and their exact commands, the rules against weakening them, manual QA and what to do after green
## Sandbox Only with --sandbox: skip deploy and release work, aim for the fastest path to green

The header of that go-cli brief:

# Build demo: Go CLI

- Stack: Go CLI (`go-cli`)
- Fragments: `agent-ops`, `ci-github`, `git-hooks`
- Preset: sandbox (local only, never deployed)
- Target agents: claude
- Project root: the directory containing `.stacks/`. Run every command from there.
- Files stacks wrote:
  - `.claude/` (10 files)
  - `.editorconfig`
  - `.gitignore`
  - `.stacks/` (4 files)
  - `AGENTS.md`
  - `CLAUDE.md`
  - `Makefile`
  - `README.md`
.stacks/BRIEF.md

Decisions

A decision is a choice the stack author couldn't make for you, with a sensible default. With the default preset the brief tells the agent to ask you about each one. With --yes or --sandbox it tells the agent to take every default and list them in its final summary:

## Decisions

Use each default below without asking, and list what you chose in your final summary.

- Module path: github.com/<owner>/<project-slug> (default), owner from `gh api user -q .login` or the git remote, never the author's display name. ...
- Binary name: the project slug (default; the Makefile's BIN).
- Coverage floor: 50% (default).
- ci-github: Runners: ubuntu-latest (default) or self-hosted labels.
...
.stacks/BRIEF.md

Brief length and word budget

The go-cli brief above is about 3,300 words, and a stack with several fragments often passes 4,000. The agent reads it once, at the start, so everything it needs goes in one file. stacks validate holds every composition to a budget of 6,000 words, or 9,000 with an app, so briefs stay readable. stacks show <id> prints a stack's brief size with its defaults.

Fixing a wrong brief

A wrong brief gets fixed in the stack or fragment that produced it. The brief is generated, and editing BRIEF.md changes nothing verify checks. The agent records the problem under ## Findings in NOTES.md so the entry's author can fix it.

The manifest

stacks verify reads only the manifest. Here is the same project's, trimmed to two steps and four commands:

{
  "schemaVersion": 1,
  "projectId": "fd22575b-8e97-4fce-868b-27856c7efd33",
  "cli": "0.5.0",
  "mode": "new",
  "name": "demo",
  "preset": "sandbox",
  "agents": ["claude"],
  "stack": { "id": "go-cli", "origin": "bundled", "trusted": true },
  "fragments": [
    { "id": "agent-ops", "origin": "bundled", "trusted": true },
    { "id": "ci-github", "origin": "bundled", "trusted": true },
    { "id": "git-hooks", "origin": "bundled", "trusted": true }
  ],
  "env": {},
  "commands": {
    "install": "Download modules and install dev tools that are missing",
    "build": "Build the binary into bin/ with version info",
    "lint": "Run golangci-lint",
    "test": "Unit tests"
  },
  "verify": [
    {
      "name": "install",
      "run": "make install",
      "phase": "setup",
      "tags": [],
      "layer": "install",
      "timeout": "10m",
      "owner": "go-cli",
      "skipByDefault": false
    },
    {
      "name": "lint",
      "run": "make lint",
      "phase": "check",
      "tags": [],
      "layer": "lint",
      "timeout": "10m",
      "owner": "go-cli",
      "skipByDefault": false
    }
  ],
  "verifyDigest": "sha256:38b641cbf6b495fb2b026e222c161ad5ca6ad48a26449d790611dbbc1d545748",
  "fingerprint": "sha256:c1c76ffed7d10d3815c1bfa762899875465cb766f353796fd671ab6561f9f3d3"
}
.stacks/manifest.json
Field What it's for
projectId A random id that names the project's state record. It never leaves your machine
preset, agents What the project was composed with
stack, fragments Each entry's id, its origin and whether it was trusted
env Default environment values for verify steps, such as ports. A variable you set in your shell wins
commands Every project command and what it does
verify The steps: name, command, phase, layer, tags, timeout, the entry that owns it, and whether it is skipped by default (prod steps in a sandbox)
verifyDigest The fingerprint of the steps, env and preset, checked before every verify run
fingerprint Identifies the exact composition, so a run can be compared with recorded runs of the same content

Commit the manifest with the project. Anyone who clones the repository can run stacks verify and get the same checks, with no brief and no stacks registry needed.

Adding to an existing project

stacks add writes into a project that already has code. It writes the same .stacks/ files, adds the new fragments' verify steps to an existing manifest (or creates one with mode: "add" and no stack), and parks any file that would conflict with one the project already has under .stacks/incoming/, so the agent can merge it by hand. Before it plans anything, add runs the same tamper check as verify. Add to an existing repository walks through it.