Chapter 1 of 12 · The workshop

Install, connect, verify

One hour to a repo with the crew in it. It talks to Linear, GitHub and Vercel. It refuses to write a secret. Nothing gets built in this chapter. Everything after it depends on it.

Agents none yetYou need a terminal, the accounts from the start pageTime about an hour
Before you start

The workshop comes before the work

Agents are only as safe as the room they work in. This chapter builds the room. Two command-line tools signed in. A repo with the crew's instruction files at the root. Connectors to the places the crew reads and writes. Environment variables that live in your shell and in Vercel and never in git. And one deliberate attempt to break a rule so you see the guard stop it. Do the steps in order. Each one ends with a command whose output tells you it worked.

Flags move

Where this chapter shows an exact install line or CLI flag, check it against the current docs before you rely on it: Claude Code, Codex CLI, Vercel CLI. The pattern is what matters. The flags change more often than this page does.

Twelve steps

Install

  1. Node 22 or newer, git, and the GitHub CLI

    Node runs the hooks and Bellows. Git holds the work. The GitHub CLI signs you in once so every agent can open pull requests. Pick your platform.

    winget install OpenJS.NodeJS.LTS Git.Git GitHub.cli
    # close and reopen the terminal so PATH picks the new tools up

    Codex CLI has had the smoothest run on Mac and Linux. On Windows, if the native install gives you trouble, run this whole chapter inside WSL. Claude Code runs natively on Windows and inside WSL.

    brew install node git gh
    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs git
    sudo apt-get install -y gh
    # or use nvm for Node and the gh install steps on github.com/cli/cli

    Then sign in to GitHub and check the versions.

    node -v && git --version && gh --version
    v22.12.0
    git version 2.47.1
    gh version 2.65.0
    gh auth login
    ? Where do you use GitHub? GitHub.com
    ? What is your preferred protocol for Git operations on this host? HTTPS
    ? How would you like to authenticate GitHub CLI? Login with a web browser
    ! First copy your one-time code: 4F2A-9C1B
    Press Enter to open https://github.com/login/device in your browser...
    ✓ Authentication complete.
    ✓ Logged in as priya-alderline
    Any Node 22 or newer works. The version numbers above are what Priya saw in August 2026.
  2. Install Claude Code and sign in

    Claude Code is the runtime for Anvil, Ember, Warden, Beacon, Ledger, Quill and Bellows. Install it globally, then run it once to sign in with the account that has your Claude subscription. A browser tab opens. When it closes you are in.

    npm install -g @anthropic-ai/claude-code
    added 1 package in 8s
    claude
    Welcome to Claude Code
    Select login method: Claude account with subscription
    Opening browser to sign in...
    Logged in as priya@alderline.coffee
    /exit
    Check the install line and sign-in flow at code.claude.com/docs. Some installs offer a native installer instead of npm; either works.
  3. Install Codex CLI and sign in

    Codex is the runtime for Flint and Gauge. Same shape: install globally, run once, sign in with the ChatGPT account that includes Codex.

    npm install -g @openai/codex
    added 1 package in 6s
    codex
    Sign in with ChatGPT
    Opening browser...
    Signed in. You can close the browser tab.
    /quit
    Check the package name and the sign-in options at developers.openai.com/codex. The exact welcome text differs by version.
  4. Create the repo and clone it

    One private repository named alderline-crm. The name shows up in branch names, PR titles and Vercel, so pick it once. Replace ALDERLINE with your GitHub user or organisation.

    gh repo create ALDERLINE/alderline-crm --private --clone
    ✓ Created repository ALDERLINE/alderline-crm on GitHub
    Cloning into 'alderline-crm'...
    cd alderline-crm && git status
    On branch main
    No commits yet
  5. Copy the kit into the repo

    Open the kit. Every file has a copy button. Instruction files and the .claude folder go at the repo root because that is where Claude Code and Codex look for them. Prompts, scripts and the rest stay under kit/ because Bellows reads them from there. When you are done the tree looks like this.

    tree -a -I node_modules --dirsfirst
    .
    ├── .claude
    │ ├── agents
    │ │ ├── anvil.md
    │ │ ├── beacon.md
    │ │ ├── ember.md
    │ │ ├── gauge.md
    │ │ ├── ledger.md
    │ │ ├── quill.md
    │ │ └── warden.md
    │ ├── hooks
    │ │ ├── after-edit.mjs
    │ │ ├── guard.mjs
    │ │ └── on-stop.mjs
    │ ├── gates.json
    │ └── settings.json
    ├── kit
    │ ├── linear
    │ │ └── workflow.md
    │ ├── prompts
    │ │ ├── build.md details.md journey.md qa.md release-note.md review.md
    │ │ └── scope.md security.md threat.md triage.md writeback.md
    │ ├── scripts
    │ │ ├── bellows.mjs
    │ │ ├── ledger.mjs
    │ │ └── telemetry.mjs
    │ ├── security
    │ │ └── checklist.md
    │ ├── tests
    │ │ └── ALD-42.spec.ts
    │ └── wiki
    │ └── notion-template.md
    ├── .mcp.json
    ├── AGENTS.md
    └── CLAUDE.md

    Commit it. This is the crew's first commit and it has no product code in it. That is the point.

    git add -A && git commit -m "Add the crew: instructions, agents, gates, hooks, connectors" && git push -u origin main
    [main (root-commit) 2a7f0c1] Add the crew: instructions, agents, gates, hooks, connectors
    29 files changed, 1184 insertions(+)
    branch 'main' set up to track 'origin/main'.
  6. Write .env.example with names only

    The crew needs six values. The repo holds their names and nothing else. Priya sets the real values in two places: the Vercel project for anything the app reads, and her own shell for anything Bellows reads. Create this file at the root.

    # Names only. Real values live in Vercel (the app) and in Priya's shell
    # (Bellows). Never commit a filled-in copy. The guard hook will stop you.
    LINEAR_API_KEY=
    LINEAR_TEAM=ALD
    NOTION_TOKEN=
    # If you use Outline instead of Notion, drop NOTION_TOKEN and set these two:
    # OUTLINE_URL=
    # OUTLINE_TOKEN=
    GITHUB_TOKEN=
    PREVIEW_URL=
    GATE_WEBHOOK=

    Where each one comes from. LINEAR_API_KEY: Linear, Settings → API → Personal API keys, created as a dedicated Alderline Crew user so agent comments look different from Priya's. LINEAR_TEAM: the team key. Create the team now with key ALD; chapter 8 and kit/linear/workflow.md set up its seven states. NOTION_TOKEN: a Notion integration token with access to the wiki pages. GITHUB_TOKEN: a fine-grained token scoped to this one repo. PREVIEW_URL: filled per branch by Vercel; leave it blank. GATE_WEBHOOK: a Slack incoming webhook or anything that accepts a JSON post. That is how Bellows pings Priya.

    Then set them in your shell. Do not paste values into the terminal from a password manager on a shared screen.

    export LINEAR_API_KEY=YOUR_LINEAR_KEY LINEAR_TEAM=ALD NOTION_TOKEN=YOUR_NOTION_TOKEN GITHUB_TOKEN=YOUR_GITHUB_TOKEN GATE_WEBHOOK=YOUR_WEBHOOK_URL
    # PowerShell: $env:LINEAR_API_KEY = "YOUR_LINEAR_KEY" and so on. Put them in your profile so Bellows sees them on every start.
  7. Link Vercel and turn on preview deployments

    Vercel builds every branch into a preview URL. Gauge runs its tests against that URL and Beacon walks the customer journey on it. Install the CLI, sign in, link the folder to a new project. Then connect the GitHub repo in the Vercel dashboard so every pushed branch gets a preview. That is the default when a Git repo is connected; check the project's Git settings.

    npm install -g vercel && vercel login
    Success! Email authentication complete for priya@alderline.coffee
    vercel link
    ? Set up "~/alderline-crm"? yes
    ? Which scope should contain your project? Alderline
    ? Link to existing project? no
    ? What's your project's name? alderline-crm
    ? In which directory is your code located? ./
    Linked to alderline/alderline-crm (created .vercel and added it to .gitignore)

    Add the app's environment variables in Vercel under Project → Settings → Environment Variables. Never through an agent. The secrets gate exists so that never happens by accident.

    The prompts vercel link asks change between versions. Check vercel.com/docs/cli.
  8. Add the MCP servers

    MCP servers are how the Claude agents reach Linear, Notion, GitHub and Vercel. The kit's .mcp.json already declares them at project scope, so copying it in step 5 did most of this. Here it is. Tokens come from the environment you set in step 6 and never from this file.

    {
      "$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." }
      }
    }

    If you would rather add servers by hand, or want them at user scope so every repo sees them, the commands look like this. Linear and Notion are hosted servers that sign you in through the browser the first time an agent uses them. GitHub runs locally through npx.

    claude mcp add --transport http linear https://mcp.linear.app/mcp
    Added HTTP MCP server linear with URL: https://mcp.linear.app/mcp to local config
    claude mcp add --transport http notion https://mcp.notion.com/mcp
    Added HTTP MCP server notion with URL: https://mcp.notion.com/mcp to local config
    claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=$GITHUB_TOKEN -- npx -y @modelcontextprotocol/server-github
    Added stdio MCP server github with command: npx -y @modelcontextprotocol/server-github to local config
    claude mcp list
    Checking MCP server health...
    linear: https://mcp.linear.app/mcp (HTTP) - ✓ Connected
    notion: https://mcp.notion.com/mcp (HTTP) - ✓ Connected
    github: npx -y @modelcontextprotocol/server-github - ✓ Connected
    vercel: https://mcp.vercel.com (HTTP) - ✓ Connected

    Sign in to Linear as the Alderline Crew user when the browser asks. Every comment the agents write will then carry that name and Priya's own comments stay hers.

    The claude mcp add syntax and the health-check wording are from the Claude Code docs at the time of writing. Verify at code.claude.com/docs. If you use Outline instead of Notion, remove the notion entry and keep the outline one.
  9. Check the agents are visible

    Claude Code reads .claude/agents/*.md at start. Open it in the repo and type /agents. You should see the seven Claude agents. Flint and Bellows are not in the list because Flint lives in AGENTS.md for Codex and Bellows is a script.

    claude
    > /agents
    Project agents · .claude/agents/
    anvil Anvil, the product manager. Use to turn a request, ticket or idea into a scoped Linear issue with acceptance criteria a machine can test…
    ember Ember, the builder. Use to implement one Detailed Linear issue end to end in this repository…
    gauge Gauge, QA and QC. Use to derive test cases from a Linear issue's acceptance criteria…
    warden Warden, security. Use to write a threat note for a Detailed issue that carries a risk flag…
    beacon Beacon, marketing and customer experience. Use to review a feature from the customer's chair before it ships…
    ledger Ledger, support and tickets. Use to triage new customer requests from the CRM ticket inbox…
    quill Quill, the scribe. Use at the end of any run to write back what was decided and learned…
    The screen layout of /agents changes between versions. The seven names are what matters.
  10. Smoke test Claude

    One headless call. Ask for Anvil by name and ask it something only CLAUDE.md can answer. If the reply lists the seven states in order, the agent file and the project file are both being read.

    claude -p "Use the anvil agent. Introduce yourself in two sentences and list the seven Linear states from CLAUDE.md."
    I am Anvil, the product manager for the Alderline CRM. I turn every request into a scoped issue with acceptance criteria before anyone writes code.
    The seven Linear states, from CLAUDE.md:
    Idea → Scoped → Detailed → In Progress → In Test → Ready to Deploy → Deployed
  11. Smoke test Codex

    Same idea. codex exec runs one prompt without the interactive screen. Ask about Flint. Only AGENTS.md knows who that is.

    codex exec "Read AGENTS.md and tell me who Flint is in two sentences."
    Flint is the builder and reviewer that runs on Codex in the Alderline CRM repository. Flint reviews the pull requests Ember writes and builds the issues Bellows assigns, and is the contrarian on the team by design: read the diff before the description and look for the case the author did not think of.
    Codex prints a few header lines about the model and working directory before the answer. They vary by version and are left out here.
  12. Verify the hooks fire

    This is the step that matters. Ask Claude Code to do something the gates forbid. The secrets rule in .claude/gates.json denies any write to a .env file. The guard hook runs before the tool and turns the rule into a refusal the agent has to explain.

    claude
    > Create a file called .env.local with the single line TEST=1.
    ● Write(.env.local)
    ⎿ PreToolUse hook denied: [gate:secrets] Secrets never go through an agent. Priya sets them in Vercel.
    ● I cannot create that file. The secrets gate blocks any write to a .env file. Add TEST=1 in Vercel under Project → Settings → Environment Variables, or in your own shell.
    > /exit
    tail -1 telemetry/events.jsonl
    {"ts":"2026-08-03T17:12:41.208Z","agent":"unknown","issue":null,"event":"gate","tool":"Write","gate":"secrets","decision":"deny","detail":".env.local"}

    Two things happened. The write was refused with the reason from the gates file. And the refusal was logged to telemetry/events.jsonl, which is where the dashboard counts gates from. The shell rules work the same way: ask it to run vercel --prod and the prod-deploy rule turns the command into a question for you instead of a deploy.

    The line that reports the block is drawn by Claude Code and its wording differs by version. The text in square brackets comes from your gates file and does not.
One more thing

Ask the crew to check its own room

Before you leave the workshop, have Claude Code audit the setup. This prompt is the one Priya keeps. She runs it after every change to the kit.

Read CLAUDE.md, .claude/settings.json, .claude/gates.json and .mcp.json. Then check this repository against them and report in a table:

1. Every agent file named in CLAUDE.md exists under .claude/agents/.
2. Every hook command in settings.json points at a file that exists.
3. Every environment variable named in .env.example is set in this shell (say SET or MISSING, never print a value).
4. Every MCP server in .mcp.json answers `claude mcp list` as Connected.
5. No file in the repo matches the secrets rule in gates.json.

Do not fix anything. Report only.
Done when
  • claude and codex both open signed in
  • gh auth status shows your account
  • The repo has CLAUDE.md, AGENTS.md, .claude/, .mcp.json and kit/ at the root and one commit on GitHub
  • claude mcp list shows Linear, Notion (or Outline) and GitHub as Connected
  • /agents lists seven names
  • Anvil answered with the seven states and Codex knew who Flint is
  • A write to .env.local was denied with [gate:secrets]

Founder Q&A

Windows or Mac?

Either. Claude Code runs natively on Windows and inside WSL. Codex CLI has been strongest on Mac and Linux; on Windows the safe route is WSL. The hooks and Bellows are plain Node scripts and run wherever Node runs. Priya uses a Mac. Tom's office machine is Windows and runs Bellows in WSL on a schedule. Check the current install notes for both tools before you decide.

What if I do not use Linear?

Keep Linear for this pack. The kit assumes it: the seven states by name, the issue templates, and the status lines Bellows reads and the states it moves. Jira or GitHub Issues would work in principle but Bellows would need rewriting where it talks to Linear, and the MCP entry would change. Get the loop running once as written. Then decide whether the swap is worth it.

Where do the tokens live?

Three places and none of them is the repo. Priya's shell profile, for everything Bellows and the hooks read. The Vercel project's environment variables, for everything the app reads. And the browser sign-ins for the hosted Linear and Notion servers, which Claude Code stores for you. .env.example carries names only. The guard denies any write to a .env file and the after-edit hook shouts if a key lands in an ordinary file. If a key ever does leak, rotate it first and ask questions second.

Do the agents run on my laptop or in the cloud?

Both. Interactive Claude Code and Codex sessions run where you type. Bellows runs on a schedule on any always-on machine: a spare laptop, a GitHub Action every ten minutes, or a small VPS. Wherever it runs it needs Node, claude and codex installed and signed in, and the environment variables set. The agents it starts run on that machine too. Chapter 11 covers the scheduling.

What does it cost to leave Bellows running?

The script itself costs nothing. A tick with nothing to do is one call to Linear. Cost comes from the agent runs it starts. The gates file caps those: runs per issue per day, minutes per run, review rounds and QA fails. A loop that gets stuck asks you instead of spending. On a quiet day Bellows runs every ten minutes and starts nothing. On a build day it might start twenty agent runs. Your subscriptions cover that up to their limits. The dashboard shows minutes per agent so you can see it.

What you have now

A repo with the crew in it and no product code. Two signed-in runtimes that each know who they are. Linear, Notion, GitHub and Vercel reachable from inside Claude Code. Six environment variables set where the agents can read them and nowhere they can write them. And proof, in one log line, that the guard stops a forbidden write before it happens.

Next: Chapter 2 · The loop. The six stages every request goes through, who owns each one, and why the loop closes back on itself.