Skip to Content
Part 1: Software factory

Part 1: Software factory

A jet flying fast, trailing streaks of light

You set up a software factory: a crew of Claude Code sessions that plans with you, builds, reviews and merges, with Tares keeping the plan and your answers. Then you give it a small test job and watch it go from plan to pull requests merged on main.

Time: about 30 minutes. In our run: 2 minutes to start the crew, 7 minutes to plan, 12 minutes from hand-over to the last merge.

This is the local guide: Tares runs on your laptop. The cloud guide, for a Tares workspace we host, is added here before the workshop.

Before you start

  • Do the setup: Everyone, then Part 1.
  • Claude Code is signed in on a plan that allows background sessions. The crew runs on your own subscription: in our run on a Max plan it used about 5% of the 5-hour limit.
  • gh auth status shows you are signed in.
  • No Anthropic API key is needed: the crew runs on Claude Code, not on Tares agents.

What you build

The factory. A crew of Claude Code sessions running in the background on your own Claude Code plan:

  • the orchestrator, which picks up planned projects and starts builders;
  • a builder, which works the tickets in your repo, one pull request each;
  • the reviewer, which reviews every pull request before it is merged.

Tares holds what they share: the spec, the tickets, the reviews and your answers. The factory works on any repo; nothing in it is specific to tonight.

Its test job. To see the whole loop run once, you give it a deliberately small job. The starter is a link shortener with three endpoints:

  • POST /links takes a long URL and gives back a short code, for example aB3_x9.
  • GET /{code} redirects to the long URL.
  • GET /links lists every link.

It does not count anything: you cannot tell how often a short link was opened. The test job is a click counter. Every redirect counts as one click, and a new endpoint GET /links/{code}/stats shows the count for one link.

Steps

Make your own copy of the starter

Clone it too. Pick any name:

gh repo create my-link-shortener --private --template glassflow/factory-workshop-starter gh repo clone my-link-shortener cd my-link-shortener

You can also open github.com/glassflow/factory-workshop-starter  and click Use this template. GitHub runs CI on your copy by itself; it should pass.

See what the app does today

Start it in your repo folder:

uv sync uv run uvicorn app.main:app --reload

In another terminal, make a short link and keep its code in CODE:

CODE=$(curl -s -X POST localhost:8000/links -H 'content-type: application/json' -d '{"url":"https://glassflow.ai"}' | jq -r .code) echo $CODE

You should see a 6-character code. Open it:

curl -i localhost:8000/$CODE

You should see HTTP/1.1 307 Temporary Redirect and location: https://glassflow.ai/. Now try the stats endpoint the crew will build:

curl localhost:8000/links/$CODE/stats

You should see {"detail":"Not Found"}: it does not exist yet. Leave the app running; you use it again in step 13.

Start Tares

In a new terminal:

tares up

The console opens at http://127.0.0.1:8787 . Leave it running.

  • By default Tares listens on port 8787 and keeps its data in ~/.tares.
  • Already have a Tares on 8787, or want a clean one? Pick another port and folder: tares up --port 8797 --data-dir ~/tares-workshop. Then add --taresd http://127.0.0.1:8797 to the command in step 4, and run export TARESD_URL=http://127.0.0.1:8797 in every terminal you use for tares factory commands. Read 8797 wherever this guide says 8787.

Start the MCP endpoint the crew talks to

In another terminal:

tares mcp --transport streamable-http

It listens on port 8788. Leave it running.

Check everything

Back in your repo folder:

tares factory doctor

You should see ok on every line except two: “Claude Code has not trusted the crew home” (FIX) and “no crew yet” (warn). Starting the crew in step 7 clears both.

Give Tares access to GitHub

So it can follow your pull requests, CI and reviews by itself.

  • Copy the token gh already holds:

    gh auth token
  • In the console at http://127.0.0.1:8787 , open Settings, then GitHub, and click Add a personal token.

  • Name: github. Token: paste what gh auth token printed. Save.

Without this the crew still works, but it checks GitHub itself and Tares does not show the pull request state.

Start the crew

tares factory crew up
  • It asks to open Claude Code in the crew’s folder: pick 1. Yes, open it. In Claude Code pick Yes, I trust this folder, then type /exit.
  • Then it asks five questions, one per tab. Pick:
    • Merging: The crew, once its reviewer approves and tests pass
    • Releasing: No, it stops when work is merged to main
    • Codex check: No (pick Yes only if you have the Codex CLI signed in)
    • Builders: 1 (not the recommended 2: one builder is enough for this feature and saves your plan’s limits)
    • Grants: Nothing more
  • On Your answers, pick Save and start the crew.

You should see “started crew-orchestrator”, “started crew-reviewer” and “started the watch”. About 2 minutes. The crew now waits for work: the orchestrator hands projects to builders, and the reviewer reviews every pull request.

Plan the feature

In your repo folder:

tares factory spec "add a click counter: count each redirect and show it at GET /links/{code}/stats"

Claude Code opens in a new spec session; trust the folder if asked. It reads the repo, then asks one question at a time, each with a suggested answer. In our run it asked four:

  • The goal and the project name. Accept the suggestion.
  • What the stats endpoint returns, for example the code, the URL, the click count and the time of the last click. Accept the suggestion, and add: keep it small: two tickets at most, one milestone.
  • Who builds it. Pick the tares-factory crew.
  • Where the tickets live: Linear or Tares. Pick Tares.

It then writes the plan to Tares: a spec, one milestone with its checks, and two tickets. About 7 minutes. Short on time? Use the ready-made spec instead.

Hand the plan to the crew

The spec session ends with “Hand this to the orchestrator now?”. Say yes.

  • The spec session tells the orchestrator there is a new project, with your repo.
  • The orchestrator starts a builder: a new Claude Code session that works in your repo, one ticket at a time.
  • From here the crew owns the project. Type /exit to close the spec session; you do not need it again.

Watch it build

You can follow it in three places.

  • The Tares console. Open http://127.0.0.1:8787/crew .

    • The crew shows the orchestrator and the reviewer.
    • Under Projects is your project and its builder. Click it.
    • The project page has four columns, Spec, Build, Review and Done, with each ticket and its pull request.
  • GitHub. Your repo gets one pull request per ticket. The builder opens it, the reviewer reviews it, CI runs, and the builder merges it. In our run the first ticket merged 7 minutes after the hand-over and the second 5 minutes later.

  • The crew’s own sessions. Open the orchestrator in your terminal:

    tares factory crew attach orchestrator

    To see the builder at work, run tares factory crew status to find its name (it ends in -build-m1), then tares factory crew attach <that name>. Only watch the builder; it needs no input from you. To leave any session and keep the crew running, press ← (Claude Code shows its list of sessions), then Esc.

Say it is done

When both tickets are merged, the project page shows “1 question waiting for you”: “Is it done?”. Answer it in the orchestrator’s session (tares factory crew attach orchestrator): type A. Then press ← and Esc to leave it.

Look at what Tares kept

Open the project in http://127.0.0.1:8787/crew : the spec, the milestone and its checks, both tickets in Done with their pull requests, and the reviewer’s verdict on each.

Try the feature

In your repo folder, get the merged code and run the tests:

git pull uv run pytest

You should see every test pass, including the new click tests. The app from step 2 reloads by itself after git pull, and it starts with no links, so make a new one and open it twice:

CODE=$(curl -s -X POST localhost:8000/links -H 'content-type: application/json' -d '{"url":"https://glassflow.ai"}' | jq -r .code) curl -s -o /dev/null localhost:8000/$CODE curl -s -o /dev/null localhost:8000/$CODE curl -s localhost:8000/links/$CODE/stats

You should see your code, the URL and "clicks": 2. If the app is no longer running, start it again with uv run uvicorn app.main:app --reload.

Finished early? Plan the README’s next idea the same way, from step 8: expiry (expires_at on create, expired codes return 410) or tags (GET /links?tag=). The crew is still up and picks it up. When you are done, stop the crew as in Clean up.

Ready-made spec: skip the interview

Save the spec to a file in your home folder, then, in your repo folder, hand it to tares factory spec. The spec session asks nothing and hands it to the crew by itself, so steps 8 and 9 happen in one go. In our run it took 4 minutes instead of 7, and both tickets were merged 14 minutes after the command. Type /exit when it says it has handed the project over.

cat > ~/click-counter-spec.txt <<'EOF' Add a click counter. Goal: count every successful redirect of a short link and expose the count at GET /links/{code}/stats. Every GET /{code} that returns 307 counts as one click; a 404 for an unknown code never counts. Each link keeps clicks (int, starts at 0) and last_clicked_at (UTC datetime, null until the first click). GET /links/{code}/stats returns 200 {"code", "url", "clicks", "last_clicked_at"} for a known code and 404 {"detail": "unknown code"} for an unknown one; fetching stats is not a click. GET /links and POST /links keep their current response shapes. Counts stay in memory like the links; no persistence, no per-day breakdown, no new dependencies. The README documents the new endpoint. Plan: one milestone, exactly two tickets: T1 record a click on every successful redirect (store and redirect handler, with tests); T2 add GET /links/{code}/stats with tests and the README line, after T1 is merged. The tares-factory crew builds it, one PR per ticket into main, merged after the reviewer passes it and CI is green; nothing to deploy. Tickets live in Tares only. Everything above is decided: ask only what is still open, then hand it to the crew. EOF tares factory spec "$(cat ~/click-counter-spec.txt)"

You can also download the spec as a file.

What just happened

  • tares factory spec turned one line into a plan on Tares: a spec, one milestone with checks, and two tickets, each with a working doc. A second model attacked the plan before it was written.
  • The orchestrator picked the project up and started a builder in your repo. The builder worked the tickets in order, one pull request each.
  • The reviewer reviewed every pull request against a fixed bar. Once it passed and CI was green, the builder merged it.
  • Tares kept the plan, the checks, the reviews and your answers. After the hand-over you answered one question, at the end.

If something is off

  • Doctor says FIX on more than the two lines in step 5. Do what the line says. “no Tares answers”: tares up is not running. “no MCP server answers”: tares mcp --transport streamable-http is not running.
  • Stations say skills are missing. A tares plugin from a marketplace is taking over: claude plugin uninstall tares@tares, then tares factory crew down and tares factory crew up.
  • Nothing moves for a while. Run tares factory crew status: each station says what it is doing. If the orchestrator is waiting for you, tares factory crew attach orchestrator. To stop everything at once: tares factory crew halt "why", then tares factory crew resume.
  • You hit your plan’s limit. Use the ready-made spec, keep Builders at 1, and switch to the cloud version if it keeps happening.
  • The interview proposes more than two tickets. Say two tickets at most, one milestone.

Clean up

  1. Stop the crew:

    tares factory crew down

    This stops the orchestrator, the reviewer, any builder and the watch. Tares keeps the project, tickets and answers. tares factory crew up brings the crew back.

  2. Stop Tares, the MCP endpoint and the app with Ctrl+C in their terminals.

  3. Your repo keeps the merged feature. Delete it on GitHub if you do not want it.

Last updated on