Skip to Content

How should I split framework migrations into milestones for a Node/TypeScript app?

Tares lets you split a framework migration into a few milestones, each ending on acceptance checks, so each one closes with its assumptions confirmed. Make each milestone one outcome you can check, such as tests and CI in place, behavior preserved, then merged and live. At the end of each milestone, the orchestrator brings you the choices the crew made on its own, and you keep them or not.

How it works

The software factory for Claude Code plans a project as milestones, and each milestone carries acceptance checks. You get them from the spec session. You run tares factory spec in the repo and answer Claude Code’s questions, a second model challenges the plan, and the result goes into Tares: a spec, a plan, an AGENTS.md for the project, and the milestones with their checks.

The project page then shows the milestones with their acceptance checks in the Tickets fold, and each ticket with the builder that held it, its pull request and its review rounds. A ticket is to do, in progress, in review, merged or blocked, and a blocked ticket names the tickets it waits for.

The project walkthrough shows a split you can copy for a TypeScript codebase. It has three milestones:

  • M1, tests and CI on the branch: Vitest, unit tests for the logic, and a CI check on every pull request.
  • M2, behavior stays as it was: past data keeps its old values after the change, and a date rule is pinned down.
  • M3, merged and live: the pull request documented, merged into main and running in production.

Each milestone has one outcome that you can verify. M1 is a safety net, M2 is the behavior you must not break, and M3 is delivery.

When the crew meets something the plan did not cover, it picks the sensible answer, writes it down as an assumption and carries on. In that project the working doc named vitest.config.ts, which fails to load on the repo’s Node version, so the builder used vitest.config.mts and recorded it. The CI job for database tests ran on the same Node version as the unit tests rather than the one in the working doc, and that was recorded too. A migration meets choices like these often, such as a config file name or a Node version, so each milestone needs a place where you see them.

That place is the end of the milestone. The orchestrator brings its assumptions to you in one question, and the answer goes into the Decisions fold in your own words. To make an answer stand from now on, say so, for this project or for every project.

Set it up

  1. Check that Claude Code is signed in, that gh is signed in with write access to the repos the crew works in, and that git, jq and curl are installed.
gh auth login
  1. Install the CLI.
uv tool install tares # or: brew install glassflow/tap/tares
  1. Start Tares locally, then in a second terminal start the MCP endpoint every crew session shares. On Tares Cloud, run tares login instead and skip both.
tares up tares mcp --transport streamable-http
  1. Give Tares access to GitHub, in Settings > GitHub for a local Tares or Connect GitHub on Tares Cloud. Then bring up the crew.
tares factory crew up
  1. Plan the migration from the repo you are migrating.
tares factory spec "what you want to build"
  1. In the spec session, describe the migration and ask for milestones the way the example does. Put tests and CI first, then the behavior that must not change, then merge and deploy. Give each milestone acceptance checks you can run or read, for example that CI passes on every pull request or that past data is unchanged after the upgrade.

  2. When the plan looks right, say yes to handing the project to the crew. The orchestrator picks it up and starts a builder for the first milestone. New to the factory? Get started covers the full setup.

What you get

  • Milestones you can check. Each one has acceptance checks on the project page, so you can see where it ends.
  • One review point per milestone. The orchestrator brings its assumptions together at the end of the milestone, and you answer in one place.
  • A record of every choice. The Assumptions fold lists each choice the crew made on its own and whether you kept it. The Decisions fold keeps your answers as you typed them, up to 4,000 characters.
  • A plan that adjusts. The reviewer checks every pull request. If it finds smaller issues outside the ticket, the orchestrator can turn them into a new ticket inside the milestone. In the example, that ticket was placed before the integration tests.
  • Progress at a glance. The project page shows Spec, Build, Review and Done, with a progress bar of one segment per ticket.

When something else fits

  • If the migration is one small change, a single milestone with its acceptance checks is enough. You do not need to split it.
  • To steer a ticket that is in progress, talk to the orchestrator rather than rewriting the plan. Use a follow-up spec when you want to pick up a finished project again.

Still stuck? Get help

Last updated on