---
title: Record releases and checks
description: Connect your project's landings, releases and checks to tzTrack, and read the evidence a fix still needs.
slug: /guides/record-releases-and-checks
order: 9
visibility: public
redirects_from: []
---

# Record releases and checks

Prompt:

> Connect this project's release pipeline and checks to tzTrack so we can see which fixes shipped and which still need verification.

Record a fix when its commit lands, record the build that carries it, and send each check's real result. These records let tzTrack distinguish a change that landed from one that was released and checked. They do not run your tests or deploy your application.

In every customer space, a green check supplies verification evidence only for the issue that check opened, rather than every issue in the components it covers. [Read the verification result](#5-read-the-verification-result) explains which fixes need a person's recheck.

## What your AI tool does

- Reads the space's configuration and connects the project's components to release lines.
- Adds calls to the existing landing, release and check jobs, using real commits, test evidence and build identities.
- Reads the resulting issue history and records any verification still needed.

## What you need

- A project with commits, a release pipeline and checks whose results the pipeline can read.
- The project's tzTrack space and a token with `owner` access. Your account has owner access in its own space; a shared space's owner assigns access.
- A secret store for the pipeline token. Never put its value in source, logs or an AI conversation.

## Before your AI starts

These steps are for your AI tool.

- Read the project's [setting file](/tztrack/reference/the-setting-file/), choose its space, and call the REST API's `read_space`. Preserve its existing configuration.
- Get a tzTrack token through [Mint a token](https://turnzero.ai/cloud/guides/mint-a-token/): from the signed-in session, request the `tztrack` grant and a label identifying the pipeline. Give the person the returned token-claim command to run in their own terminal into the secret store. Save the secret as `TZTRACK_TOKEN`; no token value passes through your tool.
- Read the [REST API](/tztrack/reference/rest-api/). This guide calls `land`, `deploy`, `ship` and `check` over that API. These release-recording acts are not tzTrack MCP tools. Set components and release lines with the REST API's `configure` as well: the `configure` MCP tool changes only the background-review setting.
- Check what the existing integration already records. The platform already records builds for hosted applications at deploy, promote and rollback; add no duplicate calls.

## Steps

### 1. Set the components and release lines

Call the REST API's `read_space` before its `configure`. For each configuration member you change, send its complete list: a named list replaces that member, and omitted members stay as they are.

Choose a release line for each independently released part of the project, and map each component's paths to it:

| Configuration | What to set |
| --- | --- |
| `release_lines` | Declare each line's `name` and `kind`: `product` or `client`. Omitted `kind` means `product`. [The REST reference](/tztrack/reference/rest-api/#supported-actions) links the complete field types and limits. |
| `components` | Give each component a `name`, its paths in `globs`, a declared `release_line`, and its `exposure` source. Keep existing `aliases` and `about` when replacing an entry. |

Choose `checks` for a component your pipeline's checks cover, and `none` otherwise. A green check supplies an exposure only on that check's own issue; expect the verification limit in step 5. Choosing an exposure source alone creates no evidence.

With no components declared, the starter components have no path patterns, use the `landing` line and have exposure `none`. A fix in such a component closes `done` at landing, so release records do not start a verification watch for it. Configure the component before relying on that watch.

### 2. Send records from the pipeline

Each call is an HTTPS `POST` to `https://tztrack.turnzero.ai/v1/<act>`, with a JSON body and the tzTrack token as its bearer credential. Set `TZTRACK_SPACE` to the chosen space's identifier so a job always names its space explicitly. This Node.js helper reads both settings without printing them:

```js
// record-tztrack.mjs
import { readFile } from 'node:fs/promises';

const [act, file] = process.argv.slice(2);
if (!['land', 'deploy', 'ship', 'check'].includes(act) || !file) {
  throw new Error('Use: node record-tztrack.mjs <land|deploy|ship|check> <body.json>');
}
if (!process.env.TZTRACK_TOKEN || !process.env.TZTRACK_SPACE) {
  throw new Error('Set TZTRACK_TOKEN and TZTRACK_SPACE in the pipeline settings');
}
const body = JSON.parse(await readFile(file, 'utf8'));
const response = await fetch(`https://tztrack.turnzero.ai/v1/${act}`, {
  method: 'POST',
  headers: {
    authorization: `Bearer ${process.env.TZTRACK_TOKEN}`,
    'content-type': 'application/json',
  },
  body: JSON.stringify({ ...body, space: process.env.TZTRACK_SPACE }),
});
if (!response.ok) {
  const refusal = await response.json().catch(() => ({}));
  throw new Error(`tzTrack refused ${act}: ${refusal.error ?? 'HTTP error'} (${response.status})`);
}
console.log(`tzTrack recorded ${act}`);
```

Create each body from the job's actual inputs, then run the helper with its file, for example `node record-tztrack.mjs land landing.json`. The following steps describe those bodies. [The REST reference](/tztrack/reference/rest-api/#supported-actions) gives their complete fields and answers.

For an act that accepts `key`, derive a stable key from that event, so retrying the same event records no duplicate. Keep the same key on a retry; do not generate a new one for each attempt.

### 3. Record the landed commit and its release

After a commit lands, call `land` once for each issue it fixes, narrows, resolves or reverts:

| Member | What the landing job supplies |
| --- | --- |
| `issue` | The issue's number or identifier. |
| `commit` | The landed commit carrying the code change. |
| `trailer` | `fixes`, `narrows`, `resolves` or `revert`. A docs issue, gap, question, task or idea uses `resolves`. |
| `test`, `proof` | For `fixes` or `narrows` on a bug or friction, the regression test and its actual proof: `base`, the test file's SHA-256 `hash`, and `result` (`proved`, `unverified` or `untestable`). Supply `accepted_by` and `reason` only for an accepted `untestable` result. Never invent proof to make the call pass. |
| `component`, `remainder`, `key` | The affected component, any remainder the narrowing leaves, and the event's stable key, as applicable. |

A bug or friction with a report from `test`, `beta`, `field` or `platform` moves to `fixed` when a fix is recorded. One with only workspace or person reports closes `done`, as does a fix whose component has exposure `none`. An AI's own reports through the MCP tools have origin `workspace`. `resolves` closes completed work `done`.

Where the platform or your existing integration does not already record the build, call `deploy`:

- Give `release_line`, `version`, `environment` and its `commit`.
- Give `order`, a whole number greater than every earlier build's order on that line and environment.
- Set `live: true` when that build is actually live. On withdrawal or rollback, record `withdrawn: true` for the withdrawn build; the fixed issues it carried and issues it verified reopen.
- Repeating an existing build updates `live` and `withdrawn` only. A new version needs its own build record.

Then call `ship` for the recorded build. Its `build` is `{ release_line, version, environment }`; `landings` lists the landed code-change commits carried in that build, selected from its actual range for the component on that release line. [The reference](/tztrack/reference/rest-api/#supported-actions) gives the full `ship` contract, including landings recorded on records-only commits. Make one call per build. Unknown commits are ignored, so `ship` cannot replace a missing `land` record. If your integration already sends `ship`, keep those calls rather than adding duplicates.

Read the issue's `landings` and history to confirm both `landed` and `shipped`. A landing starts its verification watch only when it ships on the component's line.

### 4. Record every check result

Call `check` after the check has finished, whether it passed or failed. Supply:

- `check`: a stable check name;
- `covers`: the `components` and `actions` it actually checks;
- `result`: `green` or `red`;
- `builds`: the actual `{ release_line, version, environment }` entries checked;
- `cause`: null, `harness` or `estate`, when known;
- the applicable `component`, `evidence` and event `key`.

A red on the check's first run, or its first red after a green, opens an episode. Further reds that reach the check thresholds open an issue of origin `test`, named by the check's key. Read those thresholds in `read_space`: they are fixed for customer spaces. Keep the check name stable across runs so later results update that episode.

A green check on a live build carrying the fix can record an exposure on that check's own issue. It does not supply exposures to every issue whose component appears in `covers`.

### 5. Read the verification result

Read the issue after the records arrive. Check its `landings`, each landing's `shipped` map, and the history's `landed`, `shipped` and `exposed` entries. An exposure counts only when its source matches the component's configured source and its build is live, not withdrawn, and at or beyond the shipping build's order.

The daily sweep closes the issue `verified` after three qualifying exposures, unless a report concerning the fix still waits to be read. `read_space` shows `exposures_to_verify: 3` and `watch_cap_days: 14`. These verification constants and the check thresholds are fixed for customer spaces; the REST API's `configure` refuses changes to them.

With too little evidence after 14 days, it stays `fixed` and gains `recheck`. A landing that never ships also gains `recheck` after 14 days. List those issues with `label: "recheck"` and `state: "fixed"`, then have the responsible person examine the remaining evidence.

In a customer space, a field- or beta-reported fix does not acquire exposures merely because a check covering its component is green. Hosting the application on Turn Zero Cloud does not add an exposure for that fix. With these REST records alone, it ships and is watched, then needs that recheck. An owner can close it `done` with a resolution explaining what was actually checked. The REST API serves no `expose` act for a pipeline to call.

## Expected result

Each fix has its landed commit, each release has a build and its shipped landings, and each check has its actual result. The issue history shows the evidence received. Eligible fixes close `verified` at the daily sweep; those still needing evidence remain `fixed` and may require a person's recheck.

## Refusals

Read the [REST API restrictions](/tztrack/reference/rest-api/#api-restrictions) and [Refusals](/tztrack/reference/refusals/) for the full list.

| Refusal | Status | Cause | Remedy |
| --- | --- | --- | --- |
| `credential_required` or `credential_refused` | 401 | The bearer token is missing or not accepted. | Check the pipeline's secret binding and obtain a valid tzTrack token without printing its value. |
| `grant_required` | 403 | The token lacks the access the act requires. | Use owner access for these recording acts; do not retry `expose` through this API. |
| `invalid_request` | 400 | A field, component, release line or proof is invalid. | Read the refusal and correct the body from the actual configuration and evidence. |
| `build_not_found` | 404 | `ship` named a build not yet recorded. | Record the build with `deploy` first. |
| `state_conflict` | 409 | `fixes` or `narrows` was used on a docs issue, gap, question, task or idea. | Use `resolves` for completed work of those kinds. |
| `default_space_needed` or `default_space_changed` | 409 | A request omitted the space and cannot safely choose it. | Name the intended space explicitly, as the helper does. |

## Related

- [REST API](/tztrack/reference/rest-api/) gives the request and response fields.
- [What the database stores](/tztrack/reference/what-the-database-stores/) explains the records.
- [Issues and kinds](/tztrack/concepts/issues-and-kinds/#why-fixed-is-not-closed) explains `fixed`, `done` and `verified`.
- [Track issues while you code](/tztrack/guides/track-issues-while-you-code/) covers the AI's work before landing.
