> For an index of all Botscent documentation, see https://botscent.nibnalin.me/llms.txt.

# Versions and stability

What each kind of release can change, how to pin a version, and how signer keys age.

Botscent uses semantic versioning. A release that changes any verdict is a minor version, never a patch. The npm package and the Python package have the same version and come from the same release.

## What each release can change

| Release | What it can change                                                                                             |
| ------- | -------------------------------------------------------------------------------------------------------------- |
| Patch   | A fix that changes no output.                                                                                  |
| Minor   | Any output: which visitors get which verdict, a new reason, a new agent name, a new token or a new signer key. |
| Major   | A renamed or removed reason id or agent name, or any change to an export's signature.                          |

A change to these things is also a major version:

* The wire format of the `Server-Timing` entry and of the page report, and the two carriers.
* The shared instance that copies of the library use on one page, except an addition.
* The stable parts of [`npx botscent check`](/docs/check): the flags, the `--json` field names, the check ids, the outcome values and the exit codes.

Every release publishes an output-change report in its release notes. The report says which outputs changed.

## What counts as an export

The exports are what `package.json` `exports` names on npm: `botscent`, `botscent/auto`, `botscent/server`, each adapter, `botscent/botscent.js` and `botscent/names.json`. In Python, the exports are the names without a leading underscore in `botscent`, `botscent.asgi`, `botscent.django` and `botscent.flask`.

Some parts are stable only in their shape:

* The top-level fields of [`diagnostics`](/docs/page-api#diagnostics) are stable. The keys of `probes` can change in any release.
* The text of each `check` line, and of the `--report` block, can change in any release.
* A page of an older 1.x version keeps reasons that a newer server sends, in the order received. The `Reason` and `AgentName` types accept any string, so a newer reason or name still type-checks.

## Pin an exact version

A minor release can change who is detected. No remote switch can undo the change, and a rollback means an install of the previous version. If you route or block on verdicts, pin an exact version:

```sh title="Terminal"
npm install --save-exact botscent
```

In Python, pin the version in your requirements, for example `botscent==1.0.0`. Read the output-change report before you upgrade.

## Signer keys

Each release bundles the Ed25519 keys of every known Web Bot Auth signer. The server half verifies signatures against these keys and makes no outbound request. The release notes and `fetched_at` in `registry/keys.json` give the time of the snapshot.

A bundled key is pinned as of the release. It is not checked against the signer's live directory:

* A key that a signer adds after the snapshot gives `signer.web-bot-auth.declared` until you upgrade.
* A key that a signer removes, because it rotated or leaked, stays `verified` until you upgrade. Nothing inside a deployed copy can revoke it.

A scheduled job opens a pull request when a signer's published keys change. A new key is a minor version.

> **Warning:** If you grant access on [`isVerified`](/docs/server-api#isverified), keep the package current. A leaked key stays valid in every installation that bundles it. The age of the snapshot is the limit on how stale your trust can be.

## One tag for npm and PyPI

The npm release and the PyPI release come from one tag with one version. CI publishes both: first npm, with provenance, then PyPI, then the GitHub release. The release notes give the sha256 of the test vectors that both packages passed. Both packages bundle the same signer key directories.

The TypeScript and Python halves must give byte-identical verdicts on the shared test vectors. The [contract](https://github.com/nalinbhardwaj/botscent/blob/main/spec/contract.md) pins the behaviour of both.

Release candidates go to npm under the `next` tag as `x.y.z-rc.N`, so `npm install botscent` keeps the last release. On PyPI they are `x.y.zrcN`, which pip installs only with `pip install --pre`.

## Supported versions

The latest minor release receives fixes. An upgrade to it also keeps the bundled signer keys current.

The packages declare these runtime and framework versions:

| Runtime or framework | Versions               |
| -------------------- | ---------------------- |
| Node.js              | 22.12 or later         |
| Python               | 3.11 or later          |
| Next.js              | 14 to 16               |
| React                | 18 and 19              |
| Vue                  | 3.3 or later, before 4 |
| Svelte               | 4 and 5                |
| Astro                | 4 to 7                 |
| Express              | 4 and 5                |
| Hono                 | 4                      |

## Related

* [The trust model](/docs/trust-model): what `isVerified` proves, and what it does not.
* [Server API (TypeScript)](/docs/server-api): the functions that each release keeps stable.
* [npx botscent check](/docs/check): the flags, ids and exit codes that are stable.
