How should I split framework migrations into milestones for a Python backend?
Tares plans a framework migration as milestones that each carry acceptance checks, so every milestone ends at a point where you confirm the choices the crew made on its own. For a Python backend, write three kinds of milestone: tests and CI first, behavior preserved second, merged and live last. You set them in the spec session with tares factory spec, and the crew works through them as tickets.
How it works
A milestone is the unit you plan in. Each one holds tickets, and each one has acceptance checks that say when it is done. In A project, end to end, the spec session produced a spec, a plan, an AGENTS.md for the project and three milestones, each with checks:
- M1, tests and CI on the branch: a test runner, unit tests for the logic at risk, and a CI check on every pull request.
- M2, behavior stays as it was: changes leave past data and results as they were.
- M3, merged and live: the pull request documented, merged into main and running in production.
Use the same shape for a framework migration on a Python backend:
- Safety net first. Tests and CI on the current code, before you change the framework.
- Behavior preserved. Checks that existing results and stored data stay as they were after the move.
- Merged and live. The migration documented, merged and running in production.
If the backend is large, add milestones between the second and third, each covering one slice of the backend with its own checks.
Inside a milestone, the builder works through tickets one at a time. For each, it makes a branch, does the work and opens a pull request. The reviewer reviews every pull request, and once the verdict passes and CI is green, the builder merges. A blocked ticket names the tickets it waits for.
The milestone end is where assumptions get confirmed. When the crew meets something the plan did not cover, it picks the sensible answer, writes it down as an assumption and carries on. At the end of each milestone, the orchestrator brings you its assumptions in one question, and you keep them or not. In the example project, a working doc named a config file that failed to load on the repo’s Node version, so the builder used another file and recorded it as an assumption. A migration throws up many choices like that, such as a version pin or a changed config file name.
Set it up
- Check that Claude Code is signed in, gh is signed in with write access to the repos the crew works in, and git, jq and curl are installed.
- Install the CLI, start Tares locally and start the MCP endpoint that every crew session shares. On Tares Cloud, run
tares logininstead and skip the local start and the MCP endpoint. - Give Tares access to GitHub, in Settings > GitHub for a local Tares or Connect GitHub on Tares Cloud.
- Bring up the crew, then plan the project from your repo.
- In the spec session, answer Claude Code’s questions and ask for milestones that each end with checks you can observe, such as a CI check that passes on every pull request or a stated outcome for existing data. Say yes to hand the project to the crew when the plan reads right.
gh auth login
uv tool install tares # or: brew install glassflow/tap/tares
tares up
tares mcp --transport streamable-http
tares factory crew up
tares factory spec "what you want to build"In the spec session a second model challenges the plan before it goes into Tares. See Get started for the full setup.
When a milestone ends, answer the assumptions question in the orchestrator’s session. To make an answer stand from now on, say so, for this project or for every project.
What you get
- A plan you can read. The Tickets fold on the project page lists milestones with their acceptance checks, and each ticket with its builder, pull request and review rounds. A progress bar shows one segment per ticket.
- A record of your choices. The Decisions fold keeps every question the crew asked and your answer in your own words. The Assumptions fold lists every choice the crew made on its own and whether you kept it.
- A plan that adjusts. In the example project the reviewer found smaller issues outside the ticket it was reviewing. The orchestrator turned them into a new ticket and placed it in M2 before the integration tests.
- A standup report. It shows what is done, started, in review, blocked and waiting on you, with pull request links.
- A clear finish. After the last milestone the orchestrator asks whether the project is done. When you say it is, Tares marks it Done and moves it to the finished list.
When something else fits
- To change the plan while it builds, talk to the orchestrator. It answers the builders and brings you what needs you.
- When the crew is waiting on you, the Crew page shows it as Waiting for you, and you answer in that station’s session.
- The software factory for Claude Code needs Claude Code, so if you do not use it, plan the milestones yourself and work them by hand.