# Findings and fixes

> A finding is a problem that Sequential counts across sessions. Hand it off, link the fix and mark the release. Then Sequential measures the rate again.

> **In short**
>
> - A **finding** is a problem that Sequential counts across sessions: an exception, a failed request, a dead click, a rage click or a dead end.
> - Hand a finding to a developer or an agent with its **fix brief**. Then link the pull request, commit or issue for the fix.
> - Record a **release marker** for each release. Name the findings that it is for, for example `"finding_ids": ["F-12"]`.
> - About once an hour, Sequential measures again. It compares the sessions before the release with the sessions after it.
> - The result says what the rate did after the release. It never says why.

## What it is for

Use **Findings** to follow a problem from the first time Sequential counts it to the release that is meant to fix it. After the release, the **Verification** card on the finding shows what the rate did.

## Where findings come from

Sequential looks for five kinds of problems in your events: **Exception**, **Failed request**, **Dead click**, **Rage click** and **Dead end**.

Sequential opens a finding in one of two ways:

- **From the first session.** A JavaScript error (**Exception**), or a request that fails with a server error (5xx) or a network failure, such as a timeout, opens a finding from the first session it happens in. One session of one person is enough, an anonymous visitor too. Until it repeats in 3 sessions from 2 people, its fix brief says "Opened from its first session", and the agents' `first_session` is `true`.
- **When it repeats.** A rage click, a dead click, a dead end, or a request that fails with another status, such as 404, opens a finding when the same problem happened in at least 3 sessions, of at least 2 different people, in the last 7 days.
- **A dead end and how people came back.** From 14 October 2026, Sequential also records how each visitor came back from the page that the click opened:
  - **with Back**: the visitor's own Back button or swipe, also a Back that reloads the page;
  - **sent by the app**: a redirect, or a navigation that the page made;
  - **not known**: Sequential cannot tell. This is so with a Sequential SDK from before 9 October 2026, with another tool's SDK, and in a browser without the Navigation API, such as Firefox.

  The sessions sent back by the app and the sessions not known open a dead end at 3 sessions of 2 people, as above. The sessions with Back count only toward a higher bar: at least 6 sessions, of at least 4 people, and at least 20 % of the sessions that visited the page. A dead end that opens by that bar is a pattern of people going back, not a fault. Its title reads "People often go straight back from <page> after "<text>" on <page>".

  On the finding, **Evidence** has a **Came back** row: the sessions by how people came back, for example "2 sessions with Back · 1 not known" or "1 session with Back · 3 sent by the app · 2 not known". A kind with no sessions is left out. A dead end found before 14 October 2026 has no counts, so it has no row. Under **Sessions**, each sample of a dead end ends with "· came back with Back", "· sent back by the app" or "· return not known". A sample without a kind ends as before.

Some problems never open a finding, under either rule:

- an error from a browser extension: its stack, frame or message names a `chrome-extension://`, `moz-extension://` or Safari extension address
- an error or a request on an ad, analytics or tag host, such as Google Analytics, Google Tag Manager, Hotjar or Segment. Payment and sign-in services are not on that list, and neither is the API of your own app: their failed requests count as usual.
- a request that the page cancelled, or that the browser cancelled because the user left the page
- a prefetch request

- The same problem is the same finding as it grows. It keeps its id.
- The count of people is the "N users" on the row. With the Sequential SDK, PostHog or Mixpanel, one person counts once, even if they signed in between. Amplitude, Pendo and Smartlook send no link, so there each id counts as one person.
- A finding that Sequential already shows never disappears because its count fell below 2. It stays, and the row shows its true count.
- The counts are exact. Sequential counts sessions. It does not estimate.
- Sequential looks for new findings every 15 minutes, by default. When the Findings page is empty, it says the interval of your server: "Sequential checks for new findings every N minutes."
- Judgments never create a finding. When sessions with the problem are judged, the row adds a hedged line, for example "about 4 of 9 judged probably gave up (±2)".
- Sequential switches findings on per project. The app has no setting for it. On a project where findings are off, the page says "Findings aren't switched on for this project yet." From 15 October 2026, an agent's `list_findings` then answers `enabled: false` and still lists the stored findings: no new finding opens, and the stored findings are not updated. `get_overview` counts them too.

## When the Findings page is empty

The **Open** tab says why it is empty, and when a finding appears:

- "Findings start once sessions arrive", when no session has reached the project yet. Install a source on **Setup**.
- "No problem found in the last 7 days", with how many sessions Sequential checked. When session replay does not record, it adds that failed requests and the browser's own JavaScript errors are not seen. Errors that your SDK sends, clicks and dead ends still count.
- On a project where findings are off, "Findings aren't switched on for this project yet".

Under **When a finding appears**, the page gives the two rules and the noise rule above. Then it gives **Open Watch**, **Ask your agent to look for problems** and **About findings**. **Ask your agent** gives your coding agent a prompt to look through the last 7 days for problems that are not findings yet.

The other tabs say less. An empty **Dismissed** tab says "Nothing is dismissed." An empty **All** tab says "No findings yet."

## The Findings page

1. In the left rail, click **Findings**. Its number is the count of open findings at the stage **New**.
2. Choose a tab: **Open**, **Dismissed** or **All**.
3. Read a row: the kind, the title, the counts and the stage badge on the right. The counts read like "12 of 300 sessions on /checkout · 5 users · last 7 days": the sessions with the problem, of all the sessions on that page. When Sequential did not count the page's sessions, they read like "12 sessions · 5 users · last 7 days".
4. Click a row to open the finding.

- The page shows at most 50 findings. It then says "Showing the top 50 findings."
- A finding that did not occur in the last 7 days shows "not seen in the last 7 days".

If your app routes by `#/…`, a finding's **Evidence** also has **Routes**: up to 5 hash routes on the finding's page, each with the number of affected sessions that were on it. The card says: "Where the affected sessions were on this page. A session can count on more than one route." It shows where the sessions were, not where each occurrence happened. Agents do not get this list.

On a finding, **Evidence** lists up to 5 sample sessions under **Sessions**. A sample shows **Watch from m:ss** when you can play its recording. Otherwise it shows **Open events**, with a chip for a recording that exists: **Processing · ready by** and a time, or **Expired**. A muted **Couldn't check recording** chip means that Sequential could not read the state, also on a second try. The recording can exist. A **Processing** sample checks again after that time. When the recording is ready, it changes to **Watch from m:ss** without a reload. A sample without a state gets it when it comes into view.

## A finding's page

From 11 October 2026, a finding shows, from the top:

1. The kind, the title, the counts and the impact.
2. The status timeline. See below.
3. **Verdict**: who gave the last verdict, and when. Owners, admins and members also get two choices: **Confirm problem** and **Dismiss…**. **Dismiss…** opens **Not a problem** and **Won't fix**, with a box for an optional reason. A dismissed finding has **Reopen**.
4. Tabs to the cards: **Evidence**, **Verification** and **Hand off**. **Sessions** and **Releases** are parts of **Evidence**. The tab of the card in view is marked. On a wide screen, the tabs stay at the top while you scroll.
5. **Evidence**: the page, when Sequential first saw it, the environment, the routes, then **Sessions** and **Releases**.
6. **Verification**. See [Read the result](#read-the-result).
7. **Hand off**: **Fix brief**, **Draft a fix** (owners and admins only) and **Fix links**, in one card.

## The status timeline

At the top of a finding, the timeline shows how far the finding got: **New** › **Handed off** › **Fix linked** › **Fix released** › **Measuring**, then the result. A step that is done has a ✓. The current step is a badge.

| Stage | What it means |
|---|---|
| **New** | Nothing has happened to the finding yet. |
| **Handed off** | Someone copied the fix brief or opened a GitHub issue from it. Or a token read the finding or its brief: GET `/api/findings/:n` counts too. The timeline shows the date. See [What counts as a handoff](#what-counts-as-a-handoff). |
| **Fix linked** | A pull request, commit or issue link is on the finding. |
| **Fix released** | A release marker names the finding. The first measurement has not run yet. |
| **Measuring** | Sequential is counting the sessions after the release. There are not enough yet to tell. |
| **Confirmed fixed**, **Improved**, **No change**, **Worse**, **Regressed**, **Not measured** | The result. See [Read the result](#read-the-result). |
| **Dismissed** | Someone set **Not a problem** or **Won't fix**. This can happen at any stage. **Reopen** makes the finding open again. |

- When more than one stage applies, the finding shows the first of these: **Dismissed**, the measurement, **Fix linked**, **Handed off**, **New**.
- **Handed off** has a ✓ only when someone really handed the finding off. **Fix linked** has a ✓ only when a link exists. A release alone can move a finding to **Measuring** with these two steps not ticked.
- Only **Worse** and **Regressed** are amber, on the list and on the **Verification** card. They are the results that ask you to act. The timeline shows them without colour.
- The list never shows **Fix released**. Until Sequential measures a new release, the list shows the last result that it stored for the finding. This result can be for an older release. With no stored result, the list shows **Fix linked**, **Handed off** or **New**. Open the finding to see the stage for the newest release.

## Hand off a finding

1. Open the finding, and go to **Hand off**.
2. Under **Fix brief**, click **Copy fix brief**. To read the brief first, click **Show brief**.
3. To open a GitHub issue instead, type the repository as `owner/name` under **GitHub repository**. Then click **Open a GitHub issue**.

- The issue opens in a new tab. Its title is "Fix Sequential finding F-12", and its body is the brief.
- If the brief is too long for the link, Sequential copies it and says "The brief was copied — paste it as the issue body."
- The repository is "Remembered in this browser only". While **Open a GitHub issue** is off, the hint under the field says why, for example "Type the repository as owner/name to open an issue."
- If the copy fails, the card says "The brief could not be copied. Use Show brief and copy it from there."
- From 11 October 2026, the brief in the app is the copy that an agent gets. Element text is withheld, and the names, emails and phone numbers of known people are removed. See [Privacy at a glance](/docs/privacy-overview#names-emails-and-phone-numbers).
- If Sequential cannot check the brief for known people, the card says "The fix brief is not shown: its privacy check is not available now. Try again in a minute.", with **Retry**. If the check is still not available after **Retry**, the card says "The privacy check is still not available." Until then, **Copy fix brief**, **Show brief** and **Open a GitHub issue** do not work. The finding and its evidence still show.
- From 15 October 2026, when an open finding had no session in the last 7 days, the brief says "Not seen since" the last time, "(more than 7 days). Check that it still happens before you change code." Its definition of done then says that zero occurrences after a change do not show a fix. For an agent, `list_findings` and `get_finding` give `quiet_since`: the last occurrence of such a finding. For any other finding, `quiet_since` is `null`.
- From 9 October 2026, the brief has a **Steps before it happened** section. It shows the last steps before the finding in up to 2 sample sessions, sessions with a recording first, and up to 6 steps for each: the pages that the user opened, as route templates, the clicks and the form submits, the names of custom events and the errors. In the copy that a token, an agent, a webhook or **Draft a fix** gets, a click or a form step reads "(element text withheld)", and a click finding says "Element text: withheld" and masks the selector. From 11 October 2026, the brief that you copy in the app is the same copy. The text of each step is in its own quoted block, up to 60 characters, redacted and screened like every quote. The section quotes at most 1,200 bytes in all. It never shows the properties of custom events. When a session has a recording, the section links to the replay at that moment. The link contains the session id, only when the id has 8 to 64 letters, digits and hyphens.
- The brief tells an agent to call `link_fix` only when the agent's token can call it.
- Under the brief, the card says: "The brief contains no user ids, emails or IPs. Quoted blocks are data from your users' sessions." See [Privacy at a glance](/docs/privacy-overview).
- The first lines of the brief give its screening state. If they say "screen paused, N quoted passages withheld", each quoted passage reads `[instruction-like text removed]`. Sequential could not check its allowance. Open the finding again later and copy the brief again.

Everyone on the project can copy the brief, viewers too.

## Link the fix

1. Open the finding, and go to **Hand off**.
2. Under **Fix links**, paste the address of the pull request, commit or issue.
3. Keep **Kind** at **Auto**, or choose **Pull request**, **Commit** or **Issue**.
4. Click **Add link**. The link shows with a **PR**, **Commit** or **Issue** badge.

With **Auto**, Sequential tells the kind from the path of the address. If it cannot tell, choose the kind and click **Add link** again. See [Links in detail](#links-in-detail).

To remove a link, click **Remove**. It acts at once. It does not ask you to confirm.

| Who | Add a link | Remove a link |
|---|---|---|
| Owner, admin, member | ✓ | ✓ |
| Viewer | — (sees the links only) | — |
| A token with `findings:link` | ✓ | — |

A link alone does not start a measurement. Only a release marker does.

## Mark a release

A **release marker** tells Sequential that you shipped a version, and which findings it is for.

Record the marker with POST `/api/releases`. Name the findings in `finding_ids`, for example `["F-12"]`. The token needs the `releases:write` scope. An agent can use the `record_release` tool.

- Sequential measures only markers for the project's own environment. When a marker names no environment, it gets the project's environment.
- Sequential does not measure a marker for another environment. The **Verification** card only lists it. See [Read the result](#read-the-result).

The `sequential release` command and a GitHub Action will read the findings from trailer lines in your commit messages. They are not published yet. See [The sequential release command](#the-sequential-release-command). A trailer looks like this:

One commit can name several findings: Sequential-Finding: F-12, F-14 F-19

```text
fix: debounce the retry loop

Sequential-Finding: F-12
```

## Read the result

The **Verification** card on the finding shows the measurement for the newest release that names the finding.

Before the first measurement, the card says one of these:

- "Not measured yet: no release has named F-12. Put `Sequential-Finding: F-12` in the fix's commit or PR, and mark the release."
- "Fix released on …: waiting for the first measurement."
- "A release in staging (v1.4.0, …) named F-12; this project measures production." No marker for the project's environment names the finding, but markers for other environments do. The card shows one line for each of them, up to 5, newest first. Sequential does not measure them.
- "Couldn't check for a release just now; reload the page to try again." Sequential could not read the release markers. So the card does not say that no release named the finding.

If Sequential cannot read the markers but has a stored result, the card shows that result. It adds the same "Couldn't check for a release just now" line as a note.

After it, the card shows a badge, one sentence, the **After** and **Before** rates, and "Measured" with the time. Each rate reads like "4 of 200 sessions (1–5%)". The range is a 95 % interval.

| Result | What it needs |
|---|---|
| **Measuring** | Not enough sessions after the release yet. The sentence gives the count so far and the count needed, for example "(needs 120 to tell)". |
| **Confirmed fixed** | No session after the release had it, and enough sessions came: at least 3, and at least 6 divided by the rate before. For example, with 12 of 300 before (4%), 150 sessions. |
| **Improved** | Enough sessions came. The rate after is lower than before, and the 95 % interval of the change is wholly below "no change". |
| **No change** | Enough sessions came. The 95 % interval of the change includes "no change". |
| **Worse** | Enough sessions came. The rate after is higher, and the 95 % interval is wholly above "no change". |
| **Regressed** | After **Confirmed fixed**, a session had it again within 30 days. |
| **Not measured** | Sequential could not compare the two windows. The sentence says why. |

The sentences say what the rate did, for example "After fe@2, none of 150 sessions on the page had it; before, 12 of 300 did." They never say that the release fixed or caused anything.

## Troubleshooting

| You see | What it means | What to do |
|---|---|---|
| "Not measured yet: no release has named F-12" | No marker names the finding, for this environment or any other. | Name the finding in `finding_ids` of the marker. A trailer alone does not name it. |
| **Not measured** | Sequential could not compare. It never shows this as 0. | Read the sentence. See [Why a result is Not measured](#why-a-result-is-not-measured). |
| "Time-based: this project doesn't report its release on …" | Your sessions do not carry the release name. So the after window mixes old and new clients. | Report the release on your events, with the same name as the marker's `version`. |
| A note under the rates, such as "Another release, fe@3, went out during the after window." | Something else changed at the same time. The result stays, but read it with care. | See [Notes under the rates](#notes-under-the-rates). |
| **Measuring** for a long time | Not enough sessions reached the page. | Wait. After 28 days, the result becomes **Not measured**. |
| An agent gets `{"withheld": "needs findings:verify"}` | Its token does not have `findings:verify`. | Create a token with **Read a finding's measurement after a release**. |
| "The latest measurement failed; it is retried every hour." | The last run failed. The card keeps the last good result. | Wait for the next run. |
| "A release in staging (…) named F-12; this project measures production." | The marker is for another environment. Sequential measures only the project's environment. | Record a marker for the project's environment that names the finding. Check the `environment` that your CI job sends. |
| "Couldn't check for a release just now; reload the page to try again." | Sequential could not read the release markers. It does not mean that no release named the finding. | Reload the page. |
| **Add link** says "kind: required (could not be inferred from the url)" | With **Auto**, Sequential could not tell the kind from the path of the address. | Under **Kind**, choose **Pull request**, **Commit** or **Issue**. Then click **Add link** again. With the API or the `link_fix` tool, send `kind`. |

> **A result is not a cause**
>
> The card compares two groups of sessions. Other changes can move the rate too, for example another release or a change in traffic. The card lists the ones that Sequential can see. It cannot see all of them.

### The before and after windows

Each window counts the sessions that had an event on the finding's page. A session is **affected** if the finding occurred in it during the window. For a failed request, the page is the page where the failure happens most.

| Window | Which sessions | When |
|---|---|---|
| Before | All sessions on the page | From 14 days before the release to the release. If the finding was first seen later, the window starts then. |
| After, release basis | Sessions that carry the fix release and no other release | From 1 day before the release to 28 days after it |
| After, time basis | Sessions that started 2 hours or more after the release | From 2 hours after the release to 28 days after it |

- Sequential counts the before window once, at the first measurement. After that, the count does not change, unless Sequential changes how it finds that kind of problem. Then it counts the before window again with the new rules, so that the two windows use the same rules. If the before window then starts earlier than the project keeps the data, the result is **Not measured**.
- A session that carries two releases, for example a tab left open across a deploy, counts on neither release.
- The release basis starts 1 day before the marker. A session can carry the new release before the marker arrives.
- No window reads the last 2 minutes. Events take up to about a minute to become visible.

### Release basis and time basis

- Sequential uses the **release basis** when any event carried the release name, from 1 day before the release. The name must match the marker's version exactly.
- With the Sequential SDK, add `data-release` to the tag, for example `data-release="2.14.1"`, or call `sequential.register({ $release: '2.14.1' })` on each page load, so that every event carries the release name. See [Sequential SDK](/docs/sequential).
- Otherwise it uses the **time basis**. The card then says: "Time-based: this project doesn't report its release on sessions, so the after window mixes old and new clients."
- The release basis has no note on the card.
- Once a measurement is on the release basis, it stays on it.
- Until the result is final, a measurement on the time basis moves to the release basis once your events carry the release name.

### How many sessions are needed

The **needed** count is the number of after-window sessions that Sequential needs to tell. The card shows it as "(needs N to tell)" while the result is **Measuring**.

- While no session after the release had it: at least 3 sessions, and at least 6 divided by the rate before (the rule of three). For a rate before of 4%, this is 150.
- Once a session after the release had it: the number that a two-proportion test needs to show the rate halved, at 95 % and with 80 % power.
- **Improved**, **No change** and **Worse** use a 95 % interval of the rate after divided by the rate before (Katz). **No change** means that the interval includes 1.
- The **After** and **Before** rates show a 95 % Wilson interval.
- A window with no sessions reads "no sessions yet", never a 0% rate.

### Why a result is Not measured

| The card says | Why |
|---|---|
| "Not measured: it wasn't seen in the window before fe@2, so there is nothing to compare." | No session in the before window had it, or no session reached the page. The before window is the 14 days before the release. If the finding was first seen later, the window starts then. |
| "Not measured: the sessions before fe@2 are no longer kept." | Some of the data that the before window needs is no longer kept. |
| "Not measured: the sessions after fe@2 aged out before there were enough to tell." | Some of the data that the after window needs is no longer kept. |
| "Not measured: in the 28 days after fe@2, 40 sessions reached the page — not enough to tell." | 28 days passed and the after window still had too few sessions. |

- **Not measured** is final for that release. A newer marker that names the finding starts a new measurement.
- The card shows no rates for **Not measured**. When Sequential did not read a window, it never shows the window as 0.
- Sequential measures a window only while the data that it reads is still stored. It checks the data that is really stored, not the current retention setting. For exceptions and failed requests, it reads the events and the replay data, so the shorter of the two periods decides. For the other kinds, it reads only the events.
- In a project made before 29 September 2026, Sequential does not measure a window that starts before 30 September 2026. It has no record of which data those days hold. If the server sets a [retention limit](/docs/retention-and-deletion#a-server-wide-limit), Sequential deletes a finding that was last seen before about the limit plus 8 days, with its verdicts, links, verification results and hand-off records. See [Retention and deletion](/docs/retention-and-deletion).

### Notes under the rates

| Note | When it shows |
|---|---|
| "Another release, fe@3, went out during the after window." | Another marker for the same environment came after the fix release, inside the after window. The card lists up to 50. |
| "The share of traffic reaching this page changed a lot between the two windows (20% → 45%)." | The share of all sessions that reached the page changed by more than half, up or down. |
| "At current traffic this may never reach a verdict (about 30 sessions a week; 120 needed)." | In the before window, fewer sessions a week reached the page than the needed count. |

A note never changes the result. Sequential does not say what moved the rate.

### When results become final

- **Improved**, **No change** and **Worse** are decided once, at the first run with enough sessions. They are then final for that release.
- **Confirmed fixed** starts a **regression watch** of 30 days. Every run, Sequential looks at the sessions on the page since the confirmation.
  - On the release basis, every session counts, except a session that carries an older release. An older release is one with a marker, for the same environment, from before the fix release. Examples are a stale tab or an old app. A release with no marker counts.
  - On the time basis, every session counts.
  - If one of these sessions had it, the result becomes **Regressed**: "Seen again after it was confirmed fixed." The card does not name a release.
  - After 30 days with none, **Confirmed fixed** is final.
- **Regressed** and **Not measured** are final for that release.
- A newer marker that names the same finding starts a new measurement. The card always shows the newest one.

### When Sequential measures

- The job runs about once an hour.
- It measures only open findings. A dismissed finding is not measured.
- It measures only projects where findings are switched on.
- It measures only the newest marker, for the project's environment, that names the finding.
- One run measures at most 200 findings over all projects. Findings not measured yet go first, then the findings measured longest ago.
- A marker less than 2 minutes old waits for the next run.
- If a run fails, the card keeps the last result and says "The latest measurement failed; it is retried every hour."

### Archived projects

- While a project is archived, Sequential does not look for findings in it and does not measure its findings.
- Its tokens stop working.
- The app shows only live projects, so you cannot open the findings of an archived project.
- Sequential keeps the stored results. A final result does not change. After **Restore project**, measuring starts again for the other findings. If a window has aged out of retention in the meantime, the result is **Not measured**.
- The 30-day regression watch of a **Confirmed fixed** result keeps counting while the project is archived. Sequential does not look at the sessions of that time.

### Links in detail

- The address must start with `https://`. It can have at most 500 characters and no control characters.
- With **Auto**, Sequential tells the kind from the path of the address. It ignores the query (after `?`) and the fragment (after `#`).
- A pull request is `/pull/<n>`, `/merge_requests/<n>` or `/pull-requests/<n>`. More parts can follow, for example `/pull/42/files`.
- A commit is `/commit/<sha>` or `/commits/<sha>`, with 7 to 40 lowercase hex characters. More parts can follow.
- An issue is a path that ends with `/issues/<n>` or `/-/issues/<n>`. Only a `/` can follow.
- For any other address, choose the kind under **Kind**. Through the API, send `kind` (`pr`, `commit` or `issue`) to POST `/api/findings/:n/links` or the `link_fix` tool.
- Sequential always uses a kind that you choose. It does not compare it with the address.
- Adding the same address again changes nothing. The first link stays, with its first author.
- Sequential stores and shows a link. The server never opens the address. In the app, you can click the link to open it in a new tab.
- If the links cannot be loaded, the card says "Links couldn't be loaded." and shows no **Add link** form.

### What counts as a handoff

- **Copy fix brief** and **Open a GitHub issue** in the app.
- **Draft a fix**, once Sequential has recorded the hand-off. A webhook send that fails does not count. The audit log records it as `finding.dispatched`, not `finding.handed_off`.
- A token that reads the finding or its brief. GET `/api/findings/:n` carries the fix brief, so it counts as a handoff. So do GET `/api/findings/:n/brief`, the `get_fix_brief` tool and POST `/api/agent/get_fix_brief`.

These do not count: opening the finding in the app, the findings list, and the `get_finding` tool. A token request that Sequential refuses, because it could not screen the brief, does not count either.

After the next update of the hosted preview, the `get_fix_brief` tool also tells MCP clients that it changes data. Its `readOnlyHint` is false, its `destructiveHint` is false and its `idempotentHint` is true. Its description says that the first call moves the finding to `handed_off`, and that a later call does not change it. A client can then ask you before it calls the tool. A token with `findings:read` can still call it.

Sequential keeps the time of the first handoff. The audit log records only that first handoff, as `finding.handed_off`. A `via` chip shows how: `copy`, `issue`, `rest` or `mcp`. See [Audit log](/docs/audit-log).

### Draft a fix

Owners and admins see **Draft a fix** in the **Hand off** card of a finding. It hands the finding's fix brief to your own coding agent. The agent opens the pull request, and you review it.

- **Get a prompt for your agent** records the hand-off, then shows a prompt to copy: "Fix Sequential finding F-12. Read its brief with the Sequential MCP tool get_fix_brief (number 12), follow it, and put "Sequential-Finding: F-12" in the pull request so Sequential can measure the fix after release."
- Your agent needs Sequential connected, with a token that has `findings:read`. See [Agent tools](/docs/agent-tools).
- **Send to your webhook** appears only when the project has a webhook that is turned on, and the server can sign webhooks. Sequential's hosted service does not sign webhooks yet, so there the card offers only the prompt.
- Sequential records the hand-off before it shows the prompt. If it cannot check all the quoted text in the brief, it sends nothing and says so. Try again in a minute.
- After a hand-off, the card shows when and how the finding was handed over, and when you can do it again: "You can hand it over again after" a date. The server refuses another hand-off of the same finding for 7 days after the last one that succeeded.
- From that date, the card shows **Hand it over again** with the same choices. A page that is open turns over at that moment, without a reload.
- If a later webhook send failed but an earlier hand-off succeeded, the card says "This finding was handed to your agent recently." and gives the same date.
- A dismissed finding, or one with a fix link, cannot be handed over.
- An agent can also ask for a draft, with the tool `request_fix_draft` and a token that has `findings:draft`. The card then shows "Your agent asked for a draft" with the time, and "Nothing is sent until you approve it." Choose **Approve: get a prompt**, **Approve: send to your webhook** (only when the webhook is ready), or **Decline**. The agent never receives the brief from this request.
- `request_fix_draft` writes, so it is not on `/mcp/readonly`. claude.ai never gets `findings:draft`: it cannot be granted through OAuth.
- If the card cannot load the finding's hand-off status, it says "This finding's hand-off status couldn't be loaded." with **Try again**, and offers no hand-off until the status loads.
- Members and viewers do not see **Draft a fix**.

### Set up the webhook for Draft a fix

Owners and admins set up the webhook under **Settings** → **Projects** → your project → **Draft a fix**. **Send to your webhook** on a finding posts the fix brief there. Point it at whatever starts your coding agent.

- Enter a **Webhook URL** that starts with `https://`, tick **Send briefs to this webhook**, and click **Save**.
- **Send a test** posts a test body with no finding in it, and tells you whether your webhook answered.
- **New signing secret** makes a new secret and shows it once. The old secret stops working at once. Sequential cannot show a secret again.
- Each delivery is a POST with a JSON body of five fields: `finding`, `revision`, `template_version`, `finding_url` and `brief_markdown`, the screened fix brief. It holds no user ids, emails or recordings. Its **Steps before it happened** section can hold a replay link with a session id.
- Each delivery is signed. The header `X-Sequential-Signature` is `t=<unix seconds>,v1=<hex>`, where `v1` is the HMAC-SHA256 of `<t>.<raw body>` with your secret. The page shows how to check it in Node.
- Sequential sends once per click and waits up to 5 seconds. It does not follow redirects, and it refuses an address in a private network. A test counts too: a project can send up to 20 a day.
- If a send fails, the finding says why, for example "it didn't answer in time".
- Sequential's hosted service cannot sign webhooks yet. There the page says "Webhook dispatch isn't available on this server yet. You can save a webhook now; nothing is sent until it is." Until then, findings offer only the prompt.

### The sequential release command

The command and the GitHub Action are not published yet. The command is not on npm, and the Action is not in a public repository. Until they are, record markers with POST `/api/releases`.

`sequential release --version <v> [--environment <e>] [--sha <sha>] [--range <prev..HEAD>]`

- `SEQUENTIAL_TOKEN` is required. It is a project access token with the `releases:write` scope. Always pass it from a secret store.
- `SEQUENTIAL_API_URL` is required. It has no default, because Sequential's hosted API is not deployed yet.
- The address must use `https://`. Only `localhost` and `127.0.0.1` can use `http://`.
- `--version` is required. The other options are optional. Without `--environment`, the marker gets the project's environment.
- `--range` is a git range, for example `v1.2.0..HEAD`. A base of all zeros, as on a first push, reads only the head commit.
- The trailer name can be in any case, but it must start the line. An id is `F-` and a number from 1, with no leading zero. The command reads up to 50 ids for each release.
- On success, it prints "Recorded release v1.3.0 (2 findings: F-12, F-14)" or "Recorded release v1.3.0 (no findings named)".
- On a refusal or a network error, it prints the error and exits with 1. It never follows a redirect, and it never prints the token.

The GitHub Action takes the inputs `version`, `sha`, `range`, `environment`, `token` and `api-url`. `version`, `token` and `api-url` are required. `api-url` has no default.

### Tokens and agents

- `findings:verify` is not on every token. On the **Access tokens** tab, a new token starts with `findings:read` only. On **Agents**, a new token starts with the scopes of **Agent: read everything, plus Ask**, and these include `findings:verify`. An existing token does not get the new scope. In the app it reads "Read a finding's measurement after a release".
- GET `/api/findings/:n/verification` and the `get_verification` tool need `findings:verify`. Without it, the route answers 403 `insufficient_scope`. A signed-in person does not need a scope.
- The findings list and one finding also carry the stage. For a token without `findings:verify`, the stage is one of `new`, `handed_off`, `fix_linked` or `dismissed`. `measuring` and every result come back as `{"withheld": "needs findings:verify"}`. (`fix_released` is also allowed, but the list and one finding never show it.) The `handed_off_at` time always shows.
- The findings list and one finding also carry `latest_verdict`, the newest verdict on the finding. For a token, its `reason` is screened like visitor text. It comes as `{"observed": …}`, `{"withheld": "removed by screen"}` or `{"withheld": "not screened"}`. A verdict with no reason has `"reason": null`. The name of the person who gave the verdict, `user_name`, always comes as `{"withheld": "person name"}`.
- This applies to GET `/api/findings` and `/api/findings/:n`, to POST `/api/agent/list_findings` and `/api/agent/get_finding`, and to the MCP tools `list_findings` and `get_finding`. The app, with a signed-in person, gets the reason and the name as stored.
- For a token, each title in the findings list is only the kind, for example `Exception`. `scope` and `page_route` are screened like visitor text. They come as `{"observed": …}`, a `withheld` form, or `""` if the finding has no page.
- For a token, each `session_id` in one finding's evidence and in a finding's sessions list comes as `{"id": "…", "source": "observed"}`. In the sessions list, a release name comes as `{"withheld": "not screened"}`. `get_session` gives the screened release.
- A token does not get a fix brief or a finding that Sequential could not fully screen. GET `/api/findings/:n` and `/api/findings/:n/brief` answer 503 `screen_unavailable`. The `get_fix_brief` and `get_finding` tools answer an error. The operator setting `FINDINGS_SCREEN_REQUIRED=false` turns this off. See [Privacy at a glance](/docs/privacy-overview).
- When the screen is paused, a token gets the brief and the finding with every quoted passage withheld. The brief says "screen paused". A finding with more quoted passages than the screen reads is still refused.
- `link_fix` needs `findings:link`. `/mcp/readonly` never lists it. No token can remove a link.
- With a token, GET `/api/findings/:n/verification` runs the `get_verification` tool. So REST, POST `/api/agent/get_verification` and MCP give the same answer. The request counts once toward the project read limit for tokens. If a limit refuses it, the answer keeps the status and the Retry-After of that limit. See [Limits](/docs/limits).
- In the answers of `link_fix` and `get_verification`, link addresses, release names, environments and commit SHAs are screened like visitor text. They come as `{"observed": …}` or a `withheld` form. See [Privacy at a glance](/docs/privacy-overview).
- The app, with a signed-in person, gets these values as stored.
- `released_elsewhere` lists up to 5 markers for other environments that name the finding, newest first. It shows only when no marker for the project's environment names the finding. Sequential does not measure these markers.
- `release_check: "unavailable"` means that Sequential could not read the release markers. Then a missing `released` or `released_elsewhere` means "not checked", not "no release".
- In a verification answer, a `null` count means that Sequential never read that window. It is not a zero. A failed run shows only `measurement_failed`, never the error text.

## Related

- [Audit log](/docs/audit-log)
- [Roles and permissions](/docs/roles-and-permissions)
- [Limits](/docs/limits)
- [Privacy at a glance](/docs/privacy-overview)
- [Retention and deletion](/docs/retention-and-deletion)
- [Watch: sessions worth your time](/docs/watch)
