# 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.

`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.

```sh title="Terminal"
stacks new go-cli demo --sandbox --no-launch
```

```text title="demo/.stacks/"
.gitignore
BRIEF.md
manifest.json
NOTES.md
state/
```

| 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](https://stacks.steamfield.io/docs/concepts/verify.md#tamper-evidence) 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:

```md title=".stacks/BRIEF.md"
# 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`
```

### 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:

```md title=".stacks/BRIEF.md"
## 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.
...
```

### 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`](https://stacks.steamfield.io/docs/reference/validation.md) 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:

```json title=".stacks/manifest.json"
{
  "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"
}
```

| 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](https://stacks.steamfield.io/docs/concepts/registries-and-trust.md) 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](https://stacks.steamfield.io/docs/guides/existing-repo.md) walks through it.

## Related

- [Verify: the definition of done](https://stacks.steamfield.io/docs/concepts/verify.md): how the manifest's steps run.
- [How stacks works](https://stacks.steamfield.io/docs/concepts.md): where the brief's sections come from.
- [`stacks new`](https://stacks.steamfield.io/docs/reference/commands.md#stacks-new) and [`stacks add`](https://stacks.steamfield.io/docs/reference/commands.md#stacks-add): every flag.
