Linear state changes trigger agents. The wiki is read at the start of a run and written at the end. Hold that boundary and the two systems never drift.
Two systems, three jobs. Linear documents the work and triggers the next step. The wiki guides: it is what the crew knows when a run starts. Neither does the other's job.
An issue in Linear has a state. States are a machine an agent can trust: Idea, Scoped, Detailed, In Progress, In Test, Ready to Deploy, Deployed. Bellows watches the state and starts the agent the state calls for. The agent moves the state when it is done. That is the whole trigger mechanism. No webhooks are required to start, and no agent ever asks "what should I do next".
The wiki has no states and triggers nothing. It holds the charter, the decisions, the runbooks and the learning log. Anvil reads the last three decisions before it scopes. Ember reads the runbooks before it touches a deploy step. Quill writes at the end of every run. Skip the wiki and the crew re-learns the company every session, and you will watch it make a decision on Tuesday that contradicts one from Monday.
If it has a state and an owner, it is an issue. If it is true for longer than one issue, it is a page. When you are not sure, ask whether an agent should be woken up by it. If yes, Linear.
This is the setup file from the kit. Do it once, in the order written. The state names matter because Bellows moves issues by name.
# Linear setup for the Alderline crew
Linear is the system of record for work. Every agent reads and writes it, and
Bellows watches it. Twenty minutes of setup, once.
## 1. Team and key
Create a team **Alderline CRM** with key `ALD`. Issue ids become `ALD-1`,
`ALD-2` and so on; branches and PRs carry the same id.
## 2. Workflow states (Settings → Teams → ALD → Workflow)
Replace the defaults with these seven, in this order. The names matter:
Bellows moves issues by name.
| State | Type | Who moves it here | Meaning |
|---|---|---|---|
| Idea | Backlog | Ledger, Beacon, Priya | A request or an idea. Nothing decided. |
| Scoped | Unstarted | Anvil | Problem, out-of-scope and acceptance criteria written. |
| Detailed | Unstarted | Anvil | Size, flags, gate question and Warden's threat note attached. Ready for a builder. |
| In Progress | Started | Ember or Flint | Branch open, PR open or coming. |
| In Test | Started | Bellows (after APPROVE) | Gauge, Warden and Beacon are on it. |
| Ready to Deploy | Started | Bellows | QA green, Warden clear, Beacon reviewed. Waiting for Priya. |
| Deployed | Completed | Bellows only | Live. Quill and Beacon write it up. |
Keep `Canceled` and `Duplicate` as the two canceled states.
## 3. Labels
`bug`, `feature`, `how-do-i`, `frontend`, `backend`, `api`, `customer-data`,
`auth`, `billing`, `delete`, `external`, `defect`, `flaky`, `learning`.
Anvil sets the risk flags; Gauge sets `defect` and `flaky`; Ledger sets the
category on intake.
## 4. Estimates
Turn on estimates with the Fibonacci scale (1, 2, 3, 5, 8). Anvil sizes. A
slice above 5 trips the `scope-size` gate.
## 5. Templates (Settings → Templates)
**Request (from Ledger)**
```
## From the customer
<ticket text, verbatim>
## Account
<account> · <contact> · ticket <TKT-id>
## Category
<bug | feature>
```
**Scoped issue (Anvil fills this)**
```
## Problem
## Out of scope
## Acceptance criteria
AC-1
AC-2
## Size
## Risk flags
## The gate question
builder: ember | flint
```
## 6. Connect the agents
- **Claude Code:** the hosted Linear MCP server is in `.mcp.json`. The first
time an agent uses a Linear tool it will ask you to sign in; do it once
as a dedicated **Alderline Crew** Linear user so agent comments are
distinguishable from Priya's.
- **Codex:** Flint and Gauge post through Bellows, which uses the GraphQL API
with `LINEAR_API_KEY` (Settings → API → Personal API keys, created as the
Alderline Crew user).
- **Bellows:** polls the API every ten minutes by default. If you want it
instant, add a webhook (Settings → API → Webhooks) for `Issue` updates
pointing at wherever you run `bellows.mjs --once`.
## 7. Views to make
- **The loop** — board grouped by state. This is the lifecycle visualiser
with real data.
- **Waiting on Priya** — issues with a comment starting `GATE ·` and no
comment starting `approve` or `reject`. Priya's inbox.
- **Defects open** — label `defect`, state In Progress.
- **Learning** — label `learning`, all time. Grows as the crew improves.
A board grouped by state. This is the lifecycle visualiser with real data. When Priya wants to know where everything is, this is the one tab.
Issues with a GATE · comment and no approve or reject after it. Her inbox. If this view is empty, nothing is blocked on her. If it has six things in it, she is the bottleneck and knows it.
Label defect, state In Progress. What Gauge found and Ember has not fixed yet. A count that grows for two days in a row is a slice that was scoped wrong.
Label learning, all time. Every time the crew changed how it works. It should grow slowly and never stop. Read it monthly with the wiki's Learning log open next to it.
The wiki template from the kit. Notion or Outline, same structure. Each page names who writes it and who reads it, which is how you keep nine agents from all editing the charter.
# The wiki — Notion or Outline
The wiki is the crew's memory. Linear holds the work; the wiki holds what the
company knows. Quill writes to it at the end of every run. Anvil reads it at
the start of every scope. If you skip this layer the agents re-learn the
company every session.
Pick one. Notion if you already live there; Outline if you want a fast,
markdown-native wiki you can self-host. The structure is the same.
## Pages (top level)
| Page | What goes there | Who writes | Who reads |
|---|---|---|---|
| **Charter** | Who Alderline is, who the customers are, what the CRM is for, what it is not. One page. | Priya, once; Quill edits on decision | Anvil, Beacon, every kickoff |
| **Decisions** | One sub-page per decision: date, issue, options in one line each, the choice, the reason, who approved. | Quill | Anvil (the last three, every scope) |
| **Specs** | A link per Linear issue. Linear is the record; this is the index. | Quill | Anyone |
| **Runbooks** | How to deploy, how to roll back, how to rotate a key, how to seed a preview, how to run Bellows. Dated change line at the top of each. | Quill, Ember | Ember, Flint, Bellows |
| **Learning log** | One entry each time the crew changed how it works: the lesson as the title, the issue, what file changed. This is what the dashboard counts as learning. | Quill | Priya, monthly |
| **Customer journey** | Stages, what the customer feels, where tickets cluster. | Beacon, monthly | Anvil, Priya |
| **Ticket pulse** | Weekly: tickets by category, median first reply, top three requests, one line for Anvil. | Ledger | Priya, Anvil |
| **Release notes (customers)** | Two lines per deployed issue, in the customer's words. Marked Ready for Priya until sent. | Beacon | Priya |
| **Threat model** | The standing threats for a CRM with customer data, and the controls in place. Warden adds to it. | Warden | Warden, Ember, Flint |
## Notion
1. Create a page **Alderline CRM — Wiki** and the nine pages above under it.
Make **Decisions**, **Learning log** and **Release notes (customers)**
databases with properties `Date`, `Issue` (text, the ALD id), `Status`.
2. Create an internal integration **Alderline Crew** at notion.so/my-integrations
and share the wiki page with it. The hosted Notion MCP server in
`.mcp.json` signs in as you; Quill's headless runs use the integration
token as `NOTION_TOKEN`.
3. Tell the crew where it is: add the page URL to `CLAUDE.md` under a heading
`## Wiki`.
## Outline
1. Create a collection **Alderline CRM** with the nine documents above.
2. Settings → API → create a token for a user **Alderline Crew**. Set
`OUTLINE_URL` and `OUTLINE_TOKEN` in the environment.
3. Outline's REST API is `POST /api/documents.create`, `documents.update`,
`documents.search` with a bearer token. `kit/scripts/outline-mcp.mjs` is
a thin MCP bridge over those three calls so Quill can use the same tool
names as it would for Notion. Remove the `notion` entry from `.mcp.json`.
## What "trigger" means here
The wiki does not trigger anything. Linear state changes trigger agents
(Bellows watches them). The wiki is read at the start of runs and written at
the end. Keeping that boundary is what stops the two systems drifting: work
in Linear, knowledge in the wiki.
## The one rule
An agent that made a decision writes it down before it finishes. If it
forgot, the Stop hook reminds it. If it still forgot, Bellows calls Quill.
| Notion | Outline | |
|---|---|---|
| Where it runs | Hosted. Already there if the company lives in it. | Self-hosted, or their cloud. Markdown-native. |
| How the crew connects | Hosted Notion MCP server in .mcp.json, OAuth on first use. Headless runs use an integration token. | A small local MCP bridge over three REST calls, with an API token for the Alderline Crew user. |
| Databases | Decisions, Learning log and Release notes as databases with Date, Issue and Status properties. | Documents in a collection; the same properties in a front-matter table at the top of each. |
| Pick it when | Priya and Tom already work in Notion and will read the wiki there. | You want the wiki in plain files you own, or you want to grep it from a script. |
| Verdict | Works | Works |
Both work. Pick one and do not run two. Alderline chose Notion because Priya already ran the company from it. The rest of this chapter shows Notion; the Outline path is the same pages with a different connector.
MCP servers are how a Claude Code agent reads an issue or writes a page. The kit's .mcp.json lists them. Copy it to the repo root and Claude Code asks once whether to trust the servers in it. Or add them one at a time with claude mcp add, which writes the same entries.
{
"$comment": "MCP servers the crew can reach from Claude Code in this repo. Tokens come from the environment, never from this file. Linear and Notion are hosted servers (OAuth on first use); Outline is a small local bridge if you prefer it to Notion; GitHub and Vercel run locally with npx. Check each server's current install line in its own docs; these were correct when written.",
"mcpServers": {
"linear": { "type": "http", "url": "https://mcp.linear.app/mcp" },
"notion": { "type": "http", "url": "https://mcp.notion.com/mcp" },
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" } },
"vercel": { "type": "http", "url": "https://mcp.vercel.com" },
"outline": { "command": "node", "args": ["kit/scripts/outline-mcp.mjs"], "env": { "OUTLINE_URL": "${OUTLINE_URL}", "OUTLINE_TOKEN": "${OUTLINE_TOKEN}" }, "$comment": "Only if you use Outline instead of Notion. Remove the notion entry then." }
}
}
The first time an agent uses a Linear or Notion tool, Claude Code opens a browser and asks you to sign in. Sign in as the dedicated Alderline Crew user you created in Linear and the integration you created in Notion, not as Priya. Every comment the crew writes then carries the crew's name, and you can tell Anvil's words from Priya's at a glance.
.mcp.json holds no secrets. The GitHub token is read from GITHUB_TOKEN in your shell; the Outline token from OUTLINE_TOKEN. Bellows's headless runs use LINEAR_API_KEY and NOTION_TOKEN set in the scheduler. The secrets gate in chapter 7 means no agent can write them into the repo.
--transport, --scope and -e are the current shape of claude mcp add. Check code.claude.com before you paste; the pattern is stable, the flags move. The hosted server URLs are in each vendor's own docs at linear.app and notion.so.
The write-back step is the one every team skips, because by the time it matters the run is over and the agent is gone. Quill exists so that it is never skipped. Bellows calls Quill after every Deployed, after any escalation, and after any run where a kit file changed.
---
name: quill
description: >-
Quill, the scribe. Use at the end of any run to write back what was decided
and learned: a decision record when a choice was made, a changelog entry
when an issue is Deployed, a runbook change when a process changed, and a
learning-log entry when an agent found a better way. Writes to the wiki
(Notion or Outline). The write-back step nobody else remembers.
tools: Read, Grep, Glob, mcp__notion__*, mcp__linear__*, mcp__github__*
model: sonnet
---
You are Quill. You write short, dated entries and you link every one to the
issue it came from. You record what was decided and why, never what was
discussed.
## Where things go (wiki structure in kit/wiki/notion-template.md)
- **Decisions**: one page per decision. Title, date, the issue, the options
considered in one line each, the choice, the reason, who approved.
- **Changelog**: one entry per Deployed issue. Date, issue, one line of what
changed in the team's words. Beacon writes the customer version.
- **Runbooks**: edit in place when a procedure changed. Add a dated line at
the top: "Changed <date>: <what>". Never delete the old step; strike it.
- **Learning log**: one entry when an agent's kickoff prompt, agent file or
test approach changed because of something that went wrong. Title it with
the lesson, not the incident. This is what the dashboard counts as
"learning".
- **Specs**: link the Linear issue; do not copy it. Linear is the record.
## When you are called
Bellows calls you after every `Deployed`, after any `ESCALATE`, and after any
run where a kit file changed. You may also be called by any agent that made a
decision it wants remembered.
## Output
The list of pages you created or edited, each as `wiki:<title> · <url>`.
Then `QUILL DONE`.
Use the quill agent.
Linear issue {{ISSUE_ID}} ("{{ISSUE_TITLE}}") is Deployed. Write back to the
wiki: a Changelog entry (date, issue, one line in the team's words); a
Decision record if any comment on the issue or its PR records a choice
between options; a Runbook edit if a procedure changed; a Learning-log entry
if any file under .claude/, AGENTS.md or CLAUDE.md changed during this issue.
Link every entry to the issue. List what you wrote as `wiki:<title> · <url>`
and finish with `QUILL DONE`.
{{EXTRA}}Here is what Quill wrote the evening ALD-42 went live. A decision record first. Notice the shape: options in one line each, then the choice, then the reason, then who approved. Not the discussion.
Option 2. Notes appear on the driver route sheet for that account.
The request came from a driver problem: TKT-118, the back door at Riverbend Café. A note the driver cannot see solves nothing. A driver app is a product, not a slice. The route sheet already exists and the drivers already read it. The 280-character limit follows from this: one row on the sheet.
Priya Raman, comment on ALD-42, Mon 14 Sep 2026, 9:42 am, with the customer-data gate: "Yes, and the drivers need to see it."
Then the learning log. The title is the lesson, not the incident, so a year from now someone can read the titles alone and know what the crew learned. Each entry names the issue and the file that changed. This database is what the dashboard counts as learning.
| Lesson | Date | Issue | What changed |
|---|---|---|---|
| Validate length on the server, not just the form — ALD-42 | 2026-09-14 | ALD-42 | Gauge's AC-3 defect, Flint's nit and Warden's Medium were one bug. security/checklist.md check 3 now names a length limit at the edge. |
| Disable Save on empty input — ALD-42 | 2026-09-14 | ALD-42 | Flint's cold review found the unguarded empty state. kit/prompts/review.md item 2 lists "empty state" first. |
| Gauge needs seeded fixtures for tenant tests — ALD-11 | 2026-08-20 | ALD-11 | Sign-in and roles could not be tested without a second tenant's session. The seed script now creates other-tenant-fixture; gauge.md step 3 says seed through the app or the seed script only. |
Bellows polls Linear every ten minutes by default. Each tick it reads the active issues, looks at the state of each, and starts the agent that state calls for. Polling is enough for a company this size: the slowest step in the loop is an agent run of twenty minutes, and a ten-minute wait on top changes nothing. If you want it instant, add a Linear webhook for Issue updates that runs bellows.mjs --once. Same script, different trigger.
Here is one tick, run by hand at 1:30 pm on Monday 14 September, fifteen minutes after Anvil moved ALD-42 to Detailed. Priya had answered the customer-data gate with approve customer-data at 9:42 that morning, so Bellows found the approval and started Ember. The script prints nothing on a clean tick; it writes telemetry and Linear comments. The tick blocks while the agent runs, which is why Bellows lives on a timer and not in your terminal.
That is the trigger, end to end. The state changed, Bellows noticed, an agent ran, the agent changed the state, and the next tick noticed that. The Bellows script itself is quoted and walked through in chapter 11.
Notion has no state machine an agent can trust. A status property can be anything anyone types, it has no required order, and there is no reliable "changed since" an agent can poll without reading every page. Linear's workflow states are fixed, ordered and queryable, and every change is stamped. That is what a dispatcher needs. Notion is very good at being read by people and written by Quill. Let it do that.
Yes, with labels standing in for states and the same seven names. Bellows would query the GitHub API instead of Linear's, which is a change to one file. You lose two things: a clean board grouped by state, and estimates as a first-class field. If the company already lives in GitHub and nobody but the crew will look at the board, it is a fine trade. Alderline chose Linear because Priya looks at the board.
One writer. Quill is the only agent that edits wiki pages. Every other agent that wants something remembered says so in a Linear comment, and Quill writes it at the end of the run. Beacon and Ledger own their own pages (Customer journey, Release notes, Ticket pulse) and nobody else touches those. Warden adds to the Threat model. There is no case where two agents edit the same page in the same run, so there is nothing to merge.
Linear: anything with a state and an owner. Requests, slices, defects, gate questions and their answers, review findings. The record of what happened to one piece of work. The wiki: anything true for longer than one issue. Who the company is, what was decided and why, how to deploy and roll back, what the crew learned. The Specs page is the one deliberate overlap: a link per issue, so a reader of the wiki can find the record without copying it.
A Linear team with seven states Bellows moves by name, four views that tell Priya where everything is and what waits on her, and templates the agents fill. A wiki with nine pages, each with one writer, in Notion or Outline. MCP connections signed in once as the crew. Quill writing decisions and lessons at the end of every run, in a shape someone can read a year later. And a trigger that is nothing more than a state change and a ten-minute tick.
Next: Beacon. The customer in the room, the journey review, and the two-line release note a café owner will read.