Branches
Branches are isolated review workspaces for spec, test, and component
changes. They let your team review AI-generated or human changes before those
changes become product truth on main.
Branch lifecycle
- Create a branch from
main. - Edit specs, tests, or components on the branch.
- Open the Branches page.
- Review additions, modifications, deletions, duplicates, link proposals, and conflicts.
- Merge into
main, close the branch, or delete it.
Branches can be created explicitly or automatically by workflows such as intent capture and agents. Tiden merges an intent branch by itself once the work it describes has shipped. See Automatic merge of intent branches.
A branch is open, merged, or closed. Only an open branch accepts changes.
Closed branches
A person closes a branch to end it without merging and without losing its
specs, links, review, and run history: from the row menu on the Branches page,
from the header of the branch page, with tiden branch close, or with
POST /v1/branches/{id}:close. A branch that Tiden abandons also reads
closed, but it follows the rules under Abandoned intents,
not the ones below.
After a person closes a branch:
- Its status is
closed, and the API returnsclosedAtandclosedByName. The branch page readsClosed by <name> · <when>, and the branch shows under the Closed filter on the Branches page. - Its specs, code links (git branch and pull requests), test runs, and history
stay. Its review stays readable with
tiden branch merge-previeworGET /v1/branches/{id}/merge-preview; the branch page does not show the diff of a closed branch. - It accepts no new changes. Writes, code links, and holds are refused with
BRANCH_NOT_OPEN. Its description can still be changed. - Its open intent sessions are closed with the reason
branch-closed, and its automatic merge is off. - It stays closed. There is no reopen; to continue the work, start a new
intent.
tiden intent continueandtiden intent holdrefuse it.
Closing a branch that is already closed changes nothing. You cannot close
main, a merged branch, or an automatic branch that Tiden created from a pull
request: the API answers BRANCH_CLOSE_DENIED for main and for an automatic
branch, and BRANCH_NOT_OPEN for a merged one.
Delete is different: it discards the branch's changes, and its links and history go with them. See Close a branch.
Change stats
Branch rows show counts for:
- Spec additions, modifications, and deletions.
- Test additions, modifications, and deletions. A test that already exists on
maincounts as an addition here; the merge preview lists it as a duplicate. - Component additions, modifications, and deletions.
- Conflicts.
Merge preview
Merge preview shows the changes that would be applied to main. Use it before
merging from the CLI:
tiden branch merge-preview --product-id <product-id> --name <branch-name>
Every field of the REST response, GET /v1/branches/{id}/merge-preview, is
listed in the Merge preview response
reference. --format json prints a CLI re-encoding of it that can leave out
some fields and empty values; the reference lists them.
A suite or case that the branch created but that already exists on main
shows as a duplicate. A suite is a duplicate when main has a suite at the
same title path from the root, ignoring case and surrounding spaces. A case is
a duplicate when a case on main carries the same
signature. A case written by hand or by
an agent has no signature, so it only matches through its suite. In the CLI a
duplicate row starts with = and ends with (already on main).
The merge still adds every duplicate as a second copy, and the addition counts
on the branch row, the diff page, and the CLI summary keep including it. To
keep one copy on main, delete the duplicate case on the branch before you
merge. For a duplicate suite, first move any cases the branch added under it
to the suite on main, then delete the branch suite. Deleting a suite deletes
the cases under it.
Conflict resolution
A conflict occurs when the branch changed an item and main also changed that
same source item after the branch copy was created. Resolve conflicts by
choosing either:
- Keep branch.
- Keep main.
The CLI can auto-resolve all conflicts in one direction:
tiden branch merge \
--product-id <product-id> \
--name <branch-name> \
--auto-resolve branch
Link proposals
On non-main branches, spec-test link changes are proposals. Review them before merge:
tiden branch link-proposals list \
--product-id <product-id> \
--name <branch-name>
tiden branch link-proposals review \
--product-id <product-id> \
--name <branch-name> \
--decision accepted \
--all-proposed
Merges block unreviewed link proposals unless you pass:
--allow-unreviewed-link-proposals
Automatic merge of intent branches
An intent branch (intent/<date>-<slug>) holds the specs that a coding agent
wrote down for one piece of work. Tiden merges it into main by itself, about
24 hours after the last pull request of that work merges. Nobody has to open
the branch and select Merge. Branches that agent runs or imports create
keep waiting for your review.
Before it merges anything, Tiden describes what the merged code does and checks that the work the agent promised is in it. You can hold the merge, merge by hand sooner, or turn the automatic merge off for the product.
When Tiden merges
Tiden merges an intent branch when all of these are true:
- Every pull request linked to the intent has merged or is idle. A pull request is idle when neither it nor the intent has had activity for 7 days: no commit, comment, or review on the pull request, and no activity from a person or an agent on the intent. Tiden then merges the intent without that pull request and removes the link. If the pull request merges later, Tiden describes it on its own, like any merge that no intent covers. When the intent still has open promises, the idle pull request moves to the successor intent with them (see Partly delivered intents).
- A pull request in a repository that is not connected to the product is ignored. A pull request whose state Tiden cannot read counts as open until Tiden has not read it for 7 days and the intent has had 7 days without activity. After that it counts as idle.
- No agent session is working on the intent. A session left open counts as finished once its pull requests have merged and it has been idle for 24 hours.
- 24 hours have passed without activity from a person or an agent on the intent. A pull request merging counts as activity. Tiden's own writes do not.
- No hold is set.
New activity, such as a new agent session on the same intent, restarts the 24 hours. The merge box on the branch page shows the time Tiden merges after and, while the branch waits, the reason, such as a pull request that is still open or an agent session that is still active. For an open pull request it also shows the date Tiden stops waiting for it if nothing happens.
Tiden links a merged pull request to an intent when an agent linked it with
tiden intent link-pr, or when the pull request's branch is the git branch
recorded on exactly one open intent in that repository.
The closing pass
When the 24 hours are over, Tiden runs a closing pass. It lists the product files that the merged pull requests changed and the promises of the intent. A promise is one checkable item of work that the agent declared when the intent started, such as "export works offline".
If every changed file already has a spec on the branch and every promise is already shown as delivered, the pass has nothing to do. Otherwise an agent reads the merged code, writes or updates specs on the intent branch, and decides for each promise whether the code delivers it. The specs it writes name the pull request they come from in their sources.
The closing pass writes only to the intent branch. It never writes to main
and never merges.
The merge
Tiden merges the branch on behalf of its owner, the person who created it. If the owner no longer has access, Tiden uses another member who does. The history shows Tiden auto-merge as the actor. Afterwards the branch page says Merged automatically by Tiden, any session still open on the intent is closed, and the owner gets an in-app and an email notification.
The merge never waits for the branch's Quality Gate, and it settles conflicts without asking. The merged branch carries a note for each case:
- With a red Quality Gate. The gate verdict for the branch was Blocked, or
Tiden could not compute it. The merge went ahead and the owner was notified.
The specs are now on
main, where the Quality Gate reports their gaps like any other gap onmain. Open Quality gates and add the missing tests. - Conflicts resolved: N.
mainchanged N items after the branch copied them. For a spec, the closing pass describes it again from the current code of the repository's primary branch, and the merge keeps the branch version. For every other kind of item, such as a test or a component, the merge keeps themainversion. When the closing pass did not run, conflicting specs keep themainversion as well. The branch history lists each choice. - Closing pass skipped. The closing pass failed 3 times, or it could not run
because the repository has no enabled codebase agent or the workspace has no
active billing plan. Tiden merged what the agent had already recorded and
notified the owner. The pull requests of that intent then follow the usual
path for merges outside an intent branch: Tiden describes them from
main, and they appear under Untracked merges. Review them there. The specs arrive later, and they do not sit on the intent branch.
Tiden has no undo for an automatic merge. To correct what merged, start a new
intent with tiden intent reopen.
Partly delivered intents
When the merged code leaves a promise open, the intent is partly delivered. The branch page lists the open promises and the date the shipped part merges, and the owner is notified. Nothing merges yet.
New activity on the intent clears that date and the intent is in progress
again. This is the usual way to finish the work: continue the intent with
tiden intent continue.
After 7 days without activity, Tiden makes a checkpoint merge:
- Tiden creates a successor intent branch named like the original with
-contadded (-cont-2when that name is taken). It carries the open promises with the same IDs. - Tiden merges the original branch. The shipped part reaches
main. - Tiden marks the open promises on the original as moved to the successor.
- The owner is notified, with a link to the successor.
When a linked pull request is idle, Tiden does not wait the 7 days: it makes the checkpoint merge at the next check, and the idle pull request moves to the successor with the open promises.
The original branch page says Checkpoint merge and links to the successor.
Continue the work there with tiden intent continue --intent <successor>.
Abandoned intents
An intent with no merged pull request and 7 days without activity is abandoned.
That covers an intent with no linked pull request, an intent whose pull
requests all closed unmerged, and an intent whose open pull requests are idle. Tiden closes the branch and notifies the owner.
Nothing reaches main, and the branch is not deleted.
Any activity on the intent reopens the branch: a new agent session, a settled item, a linked pull request, a hold, or a linked pull request that merges later. Tiden's own writes do not reopen it. A branch that Tiden did not abandon stays closed. When a person closes an abandoned branch, it stays closed too. See Closed branches.
Hold and release the merge
A hold pauses the automatic merge of one intent branch. It stops every timer described above, including the 24 hours, the 7 days for partial work, and the 7 days for abandonment. When the hold ends or you release it, Tiden checks the intent again and each timer counts from that moment.
A hold has a reason and an end date. A hold an agent sets lasts at most 7 days.
A person can hold an intent for up to 30 days. A person sets it from the branch
page or with tiden intent hold. An agent sets it with the same command or with
the MCP tool hold_intent. The branch page shows who set it, until when, and
why. See
Hold an automatic merge.
Generated branches
Generated branches are commonly named with prefixes such as intent/ or
agents/. Branches with the agents/ prefix are proposals. Review the diff,
inspect sources and agent artifacts, then merge only the changes you trust.
An intent/ branch merges by itself after its work has shipped. To review it
first, open the branch page before the merge time and either merge it yourself
or set a hold.