Reference

# Releases

Source releases are annotated, immutable \`vMAJOR.MINOR.PATCH\` tags, with \`-rc.N\` pre-releases before a stable one (Tags): patch for compatible fixes, docs and…

## Versioning and publication

Source releases are annotated, immutable `vMAJOR.MINOR.PATCH` tags, with `-rc.N` pre-releases before a stable one ([Tags](#tags)): patch for compatible fixes, docs and dependency updates; minor for compatible features; major for breaking API or operational contracts. Every delivered change belongs to a release. The two skills carry their own `version` in their `SKILL.md`; bump one only when its command contract changes. The `agentfeedback` skill's `SKILL.md` is generated: its version is in `internal/skillgen/source/skill.json`, and `just skills` renders it.

Maintainers decide when to cut a release, by hand, when they judge `main` ready; landed changes never trigger one. An agent pushes a `v*` tag, creates a GitHub release or pushes an image (the steps below, recovery included) only when a maintainer asks for that version.

Maintainers need Git, the tools `just ci-full` needs ([develop.md](https://github.com/AgentFeedback/agentfeedback/blob/c7573e1b301aa1495f290c417ce2fb390caee544/docs/develop.md)), GoReleaser 2.19.0 exactly (the `v2.19.0` archive from github.com/goreleaser/goreleaser/releases, or `brew install goreleaser` while 2.19.0 is Homebrew's version; `just release` refuses any other version, because the archives are only reproducible with the same one; an earlier release is reproducible with the version `scripts/release.sh` pins at its tag), Docker with buildx logged in to `ghcr.io` (push access to the `agentfeedback/agentfeedback` package), able to build and run `linux/amd64` and `linux/arm64` images (on a machine of the other architecture, QEMU emulation: `docker run --privileged --rm tonistiigi/binfmt --install all`; `docker buildx ls` lists the platforms) and allowed to run a privileged container (the playbook gate runs systemd in one), `curl`, and an authenticated GitHub CLI (`gh`) with write access to the repository and its tags. There is no hosted CI: every check runs on the releasing machine.

### Tags

- `vX.Y.Z`: a stable release, marked `latest` on GitHub, image tags `X.Y.Z`, the full commit SHA and `latest`.
- `vX.Y.Z-rc.N`: a pre-release, published as a public GitHub release flagged pre-release and never `latest`, image tags `X.Y.Z-rc.N` and the full commit SHA. It exists to verify the release assets, the installer and the install playbooks before the stable tag: `just playbooks vX.Y.Z-rc.N` runs both playbooks against the published pre-release, downloaded as an agent downloads it. No other suffix is accepted.

In both forms the tag's major version must match the module path's major-version suffix in `go.mod` (`/v4` today): the Go tool never resolves a tag of another major for the module path, so `just release` refuses it. A new major changes the module path and every import path first, then tags.

### Assets

Every release carries exactly these assets, and `install.sh` and the install playbooks rely on the names:

| Asset | Content |
| --- | --- |
| `agentfeedback_<version>_<os>_<arch>.tar.gz` | `os` `linux` or `darwin`, `arch` `amd64` or `arm64`: the binary `agentfeedback`, `LICENSE`, `README.md` |
| `agentfeedback_<version>_windows_<arch>.zip` | the same with `agentfeedback.exe` |
| `SHA256SUMS` | SHA-256 of the six archives and `install.sh`, in `sha256sum` format; the client playbook checks `install.sh` against it before running it. It proves the assets belong together, not who published them: the release is not signed |
| `install.sh` | `skills/agentfeedback/scripts/install.sh` from the tagged commit |

`<version>` is the tag without the `v`. The binaries are static (`CGO_ENABLED=0`), built with `-trimpath` and the toolchain named on the `toolchain` line of `go.mod`, and stamped with the version and commit that `agentfeedback version` prints. The exact build line is in [operate.md](https://agentfeedback.dev/docs/reference/operate#build-from-source); `.goreleaser.yaml` holds the same flags.

### Cutting a release

1. Update the stable version link in `README.md` (stable releases only) and add notes to this file. Set `version` in `flake.nix` to the tag without its `v` prefix; the release preflight rejects a mismatch. Nix source archives do not contain Git tags, so they need this explicit version. Promoting an RC to stable requires a new commit updating this value; the RC and stable tags cannot share a commit and report distinct versions.
2. Run `just ci`, commit, push `main`.
3. Write the release notes to a file outside the checkout or under the gitignored `.private/`. Start with a short summary, then describe the user-visible changes, compatibility and upgrade steps. Do not repeat the release title in the body. Use absolute links to documents at the release tag so older notes keep pointing to the matching documentation.
4. Run the preflight, then publish:

   ```
   just release-check vX.Y.Z 'Release name' /path/to/notes.md
   just release vX.Y.Z 'Release name' /path/to/notes.md
   ```

     
   Pass only the descriptive title, without `vX.Y.Z`: the command adds the tag once, producing `vX.Y.Z — Release name`. A version-prefixed title is rejected. GoReleaser's changelog processing must stay enabled: setting `changelog.disable: true` discards even the supplied `--release-notes`.  
   Both check the tag form, the GoReleaser version, that `install.sh` exists, that `origin` is this repository, a clean `main` equal to `origin/main`, that the tag exists neither locally nor on `origin`, that `gh` can push, `goreleaser check`, and `just ci-full` (the release gate: e2e, fuzz, contract and the live harness on top of the merge gate). The preflight then builds a snapshot of all six targets into `dist/release/`, checks that its `SHA256SUMS` lists exactly the six archives and `install.sh` and that every line matches (the `install.sh` line against the committed file), builds the two snapshot images and smoke-tests them (each platform's binary prints the snapshot version, and the image started with no arguments answers `/ready`), and stops. `just release` instead builds the release against a local tag ( `goreleaser release --skip=publish`), checks it and runs both install playbooks against it in a clean container ( `just playbooks <tag> dist/release`, [develop.md](https://github.com/AgentFeedback/agentfeedback/blob/c7573e1b301aa1495f290c417ce2fb390caee544/docs/develop.md#verification-before-you-are-done), with every `AF_PLAYBOOK_*` answer unset: no exposure, the default harness; run `AF_PLAYBOOK_ADDRESS=0.0.0.0 just playbooks <tag> tree` beforehand to cover the exposure branch), then builds and smoke-tests the snapshot images as the preflight does, because GoReleaser builds the published images only while publishing; only then does it push the annotated tag with an absence lease, so a build or playbook defect leaves nothing public and the local tag is removed. GoReleaser then rebuilds, pushes the image (one multi-platform index under every tag above) and uploads the release, which stays a draft until every asset is up. The script verifies it as a downloader sees it: not a draft, flagged pre-release exactly when the tag is one, `latest` exactly when it is stable, the title and notes matching the supplied prose, exactly the assets above, `SHA256SUMS` byte-identical to the local build's, `install.sh` identical to the committed one, and every downloaded archive and `install.sh` matching its `SHA256SUMS` line; then the image as a puller sees it: every tag names the same index, which holds `linux/amd64` and `linux/arm64`, and each platform's binary prints the version. Last, it prints the release URL. Deploy the SHA or the version tag, never `latest`.

### Verifying a release

```
gh release download vX.Y.Z --repo AgentFeedback/agentfeedback --pattern 'agentfeedback_*' --pattern SHA256SUMS --pattern install.sh
sha256sum -c SHA256SUMS          # Linux
shasum -a 256 -c SHA256SUMS      # macOS
```

Without `gh`, download from `https://github.com/AgentFeedback/agentfeedback/releases/download/vX.Y.Z/<asset>`. To check one asset only, feed its line to the same command: `grep ' install\.sh$' SHA256SUMS | sha256sum -c` (`shasum -a 256 -c` on macOS). Releases before 4.0.0 carry no assets; only the source tag exists.

### Reproducing a release

Two builds of the same tag produce identical binaries and identical archives. Check it after a release, from a clean checkout of the tag:

```
git checkout vX.Y.Z
export GOTOOLCHAIN=$(awk '$1 == "toolchain" { print $2 }' go.mod) GORELEASER_CURRENT_TAG=vX.Y.Z RELEASE_TITLE=check
goreleaser release --skip=publish --clean && cp dist/release/SHA256SUMS /tmp/SHA256SUMS.first
goreleaser release --skip=publish --clean && diff /tmp/SHA256SUMS.first dist/release/SHA256SUMS
gh release download vX.Y.Z --repo AgentFeedback/agentfeedback --pattern SHA256SUMS --output - | diff - dist/release/SHA256SUMS
```

No output from either `diff` means both local builds match each other and the published archives. The build line in [operate.md](https://agentfeedback.dev/docs/reference/operate#build-from-source) gives the same binary as the one in the archive: compare `sha256sum agentfeedback` with `tar -xOzf agentfeedback_X.Y.Z_linux_amd64.tar.gz agentfeedback | sha256sum`.

### Recovery

When `just release` stops, it says whether the tag is already public. Before the tag push nothing is public and the script has removed its local tag: fix the cause and run it again. After the push, inspect the remote tag, the GitHub release and the image tags on GHCR before doing anything, and never force-move or delete the published tag:

- **No release, or a draft** (GoReleaser failed before publishing, the image push included; it runs before the release is created): on a clean checkout of the tagged commit, rerun GoReleaser with the same title. It finds the draft by its name, `vX.Y.Z — <title>`, keeps its notes and replaces any asset already uploaded with its byte-identical rebuild, and pushes the image tags again. Use the name template from the tagged configuration when recovering an older release:

  ```
  export GOTOOLCHAIN=$(awk '$1 == "toolchain" { print $2 }' go.mod) GORELEASER_CURRENT_TAG=vX.Y.Z RELEASE_TITLE='Release name'
  GITHUB_TOKEN=$(gh auth token) goreleaser release --clean --release-notes /path/to/notes.md
  ```

- **A published release** (a later check failed): do not run GoReleaser again; it would try to create a second release. Run the checks of [Verifying a release](#verifying-a-release), confirm the state with `gh release view vX.Y.Z --json isDraft,isPrerelease,assets` and the image with `docker buildx imagetools inspect ghcr.io/agentfeedback/agentfeedback:X.Y.Z`, and fix the release on GitHub by hand if a check failed.
- **A published release whose image check failed**: GoReleaser pushed the image before it created the release, so the image exists. A tag that is missing or names another index is repointed at the version's index, which holds the release's binaries:

  ```
  docker buildx imagetools create -t ghcr.io/agentfeedback/agentfeedback:<sha> ghcr.io/agentfeedback/agentfeedback:X.Y.Z
  docker buildx imagetools create -t ghcr.io/agentfeedback/agentfeedback:latest ghcr.io/agentfeedback/agentfeedback:X.Y.Z   # stable only
  ```

    
  Then repeat the checks: `imagetools inspect` on each tag shows one digest with `linux/amd64` and `linux/arm64`, and `docker run --rm --pull always --platform linux/<arch> ghcr.io/agentfeedback/agentfeedback:X.Y.Z version` prints `X.Y.Z` on both. A version index that lacks a platform or whose binary fails is a defect of the release: cut a new version.

The notes file from step 3 is uncommitted, so it does not exist on another machine: recovering there means rebuilding it from this file's section for that version. Rewrite relative document links as absolute URLs under `https://github.com/AgentFeedback/agentfeedback/blob/vX.Y.Z/docs/` (including links to sections of this file). Corrections to source need a new version; corrections to release prose need no new tag. For prose-only repairs, use `gh release edit <tag> --repo AgentFeedback/agentfeedback --title '<tag> — <title>' --notes-file /path/to/notes.md`; leave tags, assets, pre-release status and the latest release unchanged.

## v4.4.0 — Session capture and Cloud onboarding

Compatible with every 4.x client and server; the HTTP API stays `1.0`. The client can upload scrubbed session transcripts when the configured server's organisation enables processing, and offers hosted authentication and a machine-settings editor. Local mode remains local; upgrading does not grant capture permission.

- **Session capture:** `sessions push` sends complete session revisions through resumable uploads for Claude Code, Codex, OpenCode V1 and 2, and hook-indexed Cursor transcripts. Existing turn-end hooks and eligible CLI commands can launch a bounded upload child after the quiet interval; no resident daemon or scheduler is installed. Organisation policy, collection restrictions and repository upload permission are checked before sending. Transcripts are scrubbed, never spooled.
- **Onboarding and settings:** capability-advertised servers support email device login, agent self-enrolment and enrolment tokens, alongside key paste. `login` explicitly reauthenticates a configured client. `agentfeedback config` edits machine settings without overriding organisation policy or repository restrictions.
- **Harnesses:** OpenCode has explicit `opencode-v1` and `opencode-v2` integrations; the install alias selects the detected major version and replaces the other variant's wiring. Cursor capture uses hook-provided transcript paths, not undocumented databases. Devin, Amp and Cline gain failure nudges; omp and pi distinguish aborted tools from failures.
- **Reliability:** the UI shows local session status in both modes; successful stdio MCP friction submissions mark the session as filed. Installation honors the configured Copilot home and rejects relative Claude Code and Codex homes. Doctor accepts the Cloud initialization destination and treats unversioned Git builds as unknown.
- **Source builds:** a pinned Nix flake builds the client from source. Decoder and export/import conformance checks cover more of the existing API contract.

**Upgrade:** install the new binary and run `agentfeedback init` or `agentfeedback install <harness>` to refresh harness wiring. OpenCode V1 references and state keep working; an OpenCode 2 database migration exposes sessions under `opencode-v2` without carrying over V1 session marks. Hosted authentication and capture require the server to advertise the corresponding capabilities; self-hosted OSS continues to support key paste. Full transcripts can contain sensitive content despite scrubbing: review the [session contract](https://agentfeedback.dev/docs/reference/sessions) and [security boundaries](https://agentfeedback.dev/docs/reference/security) before enabling organisation processing. See [authentication and machine settings](https://agentfeedback.dev/docs/reference/operate#authenticate-a-client) for setup.

**Verification scope:** release acceptance uses isolated mock hosted endpoints for the client capture path, plus the repository release gates. Live Cloud rollout, extraction and candidate generation are not verified by this release.

## v4.3.0 — External friction remediation CLI

Compatible with every 4.x client and server; the HTTP API stays `1.0`. The canonical client now exposes `agentfeedback issues`: list and rank retained issues, inspect details and source reports, copy an evidence-linked prompt, correct targets and evidence, merge or split issues, and record environment-scoped outcomes. The existing server selection and API key apply; read operations require `read`, mutations require `process`.

These operations require a capable hosted server. Local mode and the self-hosted OSS server do not gain an aggregation backend. The client discovers each operation independently from the server's OpenAPI document; an unavailable operation is an error, not an empty result. `issues recheck` is independently gated and remains unavailable until the server provides upstream release discovery. No command executes a prompt, installs an upstream update, or treats a new release as proof of resolution.

Install the new binary to use the commands. See the [client command reference](https://agentfeedback.dev/docs/reference/operate) for flags and JSON input. Prompts print alone on stdout by default; `--json` preserves the server's response for automation.

## v4.2.1 — Go 1.27.3 and current dependencies

Compatible with every 4.x client and server; the HTTP API stays `1.0` and nothing changes in behaviour. The binaries are built with Go 1.27.3 and the current stable releases of their modules (among them `modernc.org/sqlite` v1.61.0 and `prometheus/client_golang` v1.25.0), and the image's runtime base is refreshed. Releases are now cut with GoReleaser 2.19.0. Nothing to do on upgrade beyond installing the new binary.

Verify the release as a downloader:

```
gh release download v4.2.1 --repo AgentFeedback/agentfeedback --pattern 'agentfeedback_*' --pattern SHA256SUMS --pattern install.sh
sha256sum -c SHA256SUMS                                      # shasum -a 256 -c on macOS
docker run --rm ghcr.io/agentfeedback/agentfeedback:4.2.1 version   # prints 4.2.1
```

## v4.2.0 — The skill sets itself up; triage ships with the binary

Compatible with 4.0.0 and 4.1.0 clients and servers; the HTTP API stays `1.0` and the server is unchanged. Everything here is in the client, the installer and the skills.

- **The `agentfeedback` skill sets itself up.** A skill installed on its own (the `skills` CLI, a plugin marketplace, a hub) now carries a Setup section: with no binary, or the harness not wired, the agent asks the human, runs the bundled checksum-verifying `scripts/install.sh`, then `agentfeedback init --yes --harnesses <harness> --json`. `init` and `install` leave a skill they did not write as it is and report it `external`, wiring the rule and the hooks around it; a Claude Code or Codex plugin that provides the skill means no second copy. An install interrupted between a file write and the manifest update is adopted on the next run instead of refused.
- **The triage skill ships in the binary.** `init` installs `agentfeedback-triage` by default ( `--no-triage` skips it), `install` keeps it ( `--with-triage=false` removes it), and its version is always the binary's; the `npx skills` route remains for machines without the binary. Its playbooks no longer describe a hosted version.
- **A shorter session start.** `agentfeedback prime`, which the session-start hooks of Claude Code, Codex and Cursor run, prints about 900 bytes (the triggers, the one command and where the rest is) instead of the whole guide; `prime --full` prints the whole guide.
- **Switching to a server names the local reports.** `init --server` and `doctor --init` count the reports in the local database and print the `migrate --local --to <URL> --to-key-from-stdin` command; `init` offers the copy on a terminal. Nothing leaves the machine without that yes.
- **`agentfeedback mcp` serves a server too.** With a server configured it relays the server's tools and adds this machine's session tools, and `install --mcp` writes a stdio entry for a server as well ( `mcp --server <URL>`), so the API key stays out of harness files. The stdio `submit_feedback` tool takes `context_from` and `ordinal`, like `submit --context-from`.
- **Local mode is sturdier.** A database path containing `?`, `#` or `%` opens the file it names. `submit` keeps a report in the spool when the local database is busy or was written by a newer binary, and delivers it later. Spool entries bound to the local database keep 30 days. The legacy `flush --hook` does nothing in local mode.
- The docs state once what still differs between local mode and a server ([operate.md](https://agentfeedback.dev/docs/reference/operate#local-mode-or-a-server-what-differs)). The skills' versions stay `5.0`: their command contract is unchanged.

**Upgrade:** install the new binary, then run `agentfeedback init` (or `agentfeedback install <harness>`) once: it installs the triage skill, wires the short `prime`, rewrites a URL MCP entry as the stdio entry, and adopts or leaves alone a skill another tool installed.

Verify the release as a downloader:

```
gh release download v4.2.0 --repo AgentFeedback/agentfeedback --pattern 'agentfeedback_*' --pattern SHA256SUMS --pattern install.sh
sha256sum -c SHA256SUMS                                      # shasum -a 256 -c on macOS
docker run --rm ghcr.io/agentfeedback/agentfeedback:4.2.0 version   # prints 4.2.0
```

## v4.1.0 — Bounded warnings

Compatible with 4.0.0 clients and servers; the HTTP API stays `1.0`. One contract addition: the warnings of a decode are bounded.

- **Warnings are bounded.** A response lists at most `limits.warnings_max` warnings (100, the closing entry included) whose `code` and `pointer` together stay within `limits.warnings_bytes` (65536); both limits are in [`/api/v1/meta`](https://agentfeedback.dev/docs/reference/api#meta). A list that fits is returned as before; one that does not is cut to the first entries in pointer order and closed by one `warnings_truncated` entry at the record pointer `""` whose message counts the withheld ones. Pointers are never shortened. Import bounds its response the same way in line order. Every surface inherits the bound: `POST /api/v1/submissions`, `POST /api/v1/import`, the MCP `submit_feedback` tool and the CLI's local decode. The code joins the closed list in `conformance/warnings.json`; the conformance kit gains `decode/interactions/warnings-truncated`; the Python reference mirrors the rule.
- The `agentfeedback` skill's "Warnings are advice" paragraph says a long list is cut; its version does not change (the command contract is the same).

Verify the release as a downloader:

```
gh release download v4.1.0 --repo AgentFeedback/agentfeedback --pattern 'agentfeedback_*' --pattern SHA256SUMS --pattern install.sh
sha256sum -c SHA256SUMS                                      # shasum -a 256 -c on macOS
docker run --rm ghcr.io/agentfeedback/agentfeedback:4.1.0 version   # prints 4.1.0
```

## v4.0.0 — Local first: one binary, the v1 contract, skills 5.0

Release 4.0.0 is the first one with release assets and an image published by the release pipeline ([Assets](#assets)); every earlier tag is source only. It is a new major: the HTTP API is the v1 contract, version `1.0` (3.x served `1.1`), and the v3 API is gone; the Go module path is `github.com/agentfeedback/agentfeedback/v4`; both skills are 5.0; a v4 binary refuses a v3 database ([operate.md](https://agentfeedback.dev/docs/reference/operate#upgrading-and-downgrading): keep the old database with the image that wrote it and start empty; a v3 export is not format 2 and does not import); a spool left under `~/.cache/agentfeedback` by 3.x is reported by `doctor` and never sent.

- **Local mode is the default.** `agentfeedback init` sets a machine up in one pass: reports go to a SQLite database in the data directory ( `${XDG_DATA_HOME:-~/.local/share}/agentfeedback`) with no server and no key; `init --server cloud|URL` points it at a server instead. Every client command works on the local database; `--server URL` targets a server once. Envelope files dropped into the data directory's `inbox/` are submitted at the start of every local-mode command but `doctor` and `hook`, or by `ingest`.
- **One binary, every command.** `submit` (friction, review, any kind; `--stdin`, `--dry-run`, `--scrub`), `list`, `get`, `stats`, `done`, `undo`, `redact`, `rekind`, `export`, `import`, `backup`, `migrate --to cloud|URL --to-key-from-stdin`, `digest`, `flush`, `ingest`, `doctor` ( `--e2e`, `--init`), `schema`, `skill render`, `version`; `hook` (per-session failure counters and a bounded nudge, replacing `flush --hook`), `sessions list|digest|mark|status` over the coding-agent session logs on the machine (Claude Code, Codex, Copilot CLI, Gemini CLI and OpenCode readers; read on demand, never sent), `ui` (a read-only loopback page over the queue), `mcp` (the tools over stdio on the local database), `serve` and `serve --init`, `server install --systemd|--launchd|--compose`. The bash client of 3.x is retired; `install.sh` installs the binary.
- **Harness installer.** `install`, `uninstall`, `install --check`, `install --project`, `install --mcp` and `prime` wire the skill, a rule in the global instruction file, session-start and failure hooks or an MCP entry into fourteen harnesses: Claude Code and OpenCode live-checked on 2026-10-07; omp, Codex, Cursor, pi, Copilot, Antigravity, Devin, Kiro, Cline, Amp, VS Code and Gemini CLI written from their documentation and listed as such by `install --list` until a live check is recorded. `doctor` reports version skew between the hook binaries and the one on `PATH`. Client data is created 0700/0600 (not on Windows); the spool lives in the data directory and is bound to its destination.
- **The v1 contract.** Envelope and kind schemas under `schemas/`, the OpenAPI document and the conformance kit under `conformance/` ([api.md](https://agentfeedback.dev/docs/reference/api)); context carries `origin`, `detector` and `session_harness`, friction carries `evidence[]`; `client.min_version` is the constant `4.0.0-rc.0`, so 4.0 release candidates are admitted. Importable packages: `pkg/schema`, `pkg/canonjson`, `pkg/envelope`, `pkg/client`, `pkg/collect`, `pkg/scrub`.
- **Server.** The v1 API on a SQLite store with numbered migrations and pinned query plans; export and import in format 2 (the HTTP import keeps uids and assigns new ids; the local `import` command restores ids); remote MCP on `/mcp` (Streamable HTTP, the six tools, instructions), the served skill on `/skill` and the discovery document on `/.well-known/agentfeedback.json`; `API_KEY_FILE`; opt-in `INGEST_SCRUB`. A bare `serve` listens on `127.0.0.1:8090` and, with `DATABASE_PATH` unset, uses the data-directory database rather than `/data/agentfeedback.db`; the image keeps `/data/agentfeedback.db` and listens on `0.0.0.0:8080`.
- **Skills.** `agentfeedback` 5.0 is generated from `internal/skillgen/source` ( `just skills`), `agentfeedback-triage` 5.0 is a fix-it session that clusters by root cause, verifies read-only, interviews, acts and marks, starts from the session logs on an empty queue, and has an MCP-only route; `agentfeedback-docs` carries the reference docs, schemas and OpenAPI document. An Agent Plugins bundle ships under `plugins/agentfeedback`, with marketplace manifests at `.claude-plugin/marketplace.json` (Claude Code) and `.agents/plugins/marketplace.json` (Codex).
- **Distribution.** The six archives, `SHA256SUMS` and `install.sh` on the GitHub release; `ghcr.io/agentfeedback/agentfeedback` (distroless, `linux/amd64` and `linux/arm64`, `CMD ["serve"]`) tagged `4.0.0`, the commit SHA and `latest`; `go install github.com/agentfeedback/agentfeedback/v4/cmd/agentfeedback@v4.0.0`. Homebrew, npm, PyPI, RubyGems and the rest follow as separate releases of their own channels.
- **One domain.** The project's site is agentfeedback.dev; `--to cloud` and `init --server cloud` resolve to `https://api.agentfeedback.dev` (public beta). The 3.0.0 binaries named a domain that is retired.
- **Gates.** `just ci` runs every gate in a toolchain container and ends with a live Claude Code check; `just playbooks <tag>` runs both install playbooks ( `AGENT-INSTALL.md`, `AGENT-INSTALL-STACK.md`) in a clean container; GitHub Actions is gone, there is no hosted CI.

Manual checks for this release, recorded by the maintainer:

- The paste check (both README prompts in two harnesses over the local path, and one live MCP desktop client over stdio) was waived by the maintainer on 2026-10-19 and not run for 4.0.0.
- The remote MCP header check (an MCP entry carrying the key lists the tools; a wrong key yields `unauthorized` with no OAuth discovery) was not run for this tag: every harness's header support, Claude Code, OpenCode and omp included, is written from documentation and unverified until a live check is recorded here.

Verify the release as a downloader:

```
gh release download v4.0.0 --repo AgentFeedback/agentfeedback --pattern 'agentfeedback_*' --pattern SHA256SUMS --pattern install.sh
sha256sum -c SHA256SUMS                                      # shasum -a 256 -c on macOS
tar -xOzf agentfeedback_4.0.0_linux_amd64.tar.gz agentfeedback | sha256sum
docker run --rm ghcr.io/agentfeedback/agentfeedback:4.0.0 version   # prints 4.0.0
```

## v3.0.0 — AgentFeedback: new home, new names, fresh start

The project moved to [github.com/AgentFeedback/agentfeedback](https://github.com/AgentFeedback/agentfeedback) and is the open-source, self-hostable AgentFeedback ([agentfeedback.dev](https://agentfeedback.dev)); a hosted version with the same API is in public beta (it was announced here for `agentfeedback.io`, a domain retired on 2026-10-18: the project has one domain, and `--to cloud` resolves to `https://api.agentfeedback.dev` from release 4.0.0). Every name changes and v3 is a fresh start: no migration from or compatibility with 2.x deployments and skill installs. The HTTP API (1.1), payloads and hash forms are unchanged.

- **Skills** `agent-feedback` → `agentfeedback` 4.0 and `agent-feedback-triage` → `agentfeedback-triage` 3.0: new directory and invocation names ( `/agentfeedback-triage`). Client environment variables keep their names ( `AGENT_FEEDBACK_*`); the spool moves to `~/.cache/agentfeedback` and triage digests to `${TMPDIR:-/tmp}/agentfeedback-triage/`. The skills work against a self-hosted service or the hosted one ( `https://api.agentfeedback.dev` from release 4.0.0; this release's binaries name the retired domain).
- **Service**: Go module `github.com/agentfeedback/agentfeedback`; binary `agentfeedback` ( `cmd/agentfeedback`, `/opt/agentfeedback`, runs as user `agentfeedback`); image `ghcr.io/agentfeedback/agentfeedback`; default database `/data/agentfeedback.db`; metrics renamed `agentfeedback_*` ( `agentfeedback_submissions_unprocessed`, `agentfeedback_db_bytes`, `agentfeedback_sqlite_busy_total`).
- **Deploy**: stack directory `infra/agentfeedback`, compose service `agentfeedback`, volume `agentfeedback-data`, server directory `~/agentfeedback`, variables `AGENTFEEDBACK_IMAGE` and `AGENTFEEDBACK_BIND_ADDRESS`.
- **Removed**: the 1.x PostgreSQL export script and migration and uninstall docs, and the `docs/agent-usage.md` redirect.
- CI lowercases the image name (the org name has capitals).

## v2.2.1 — Documentation sweep

Docs and skill documentation only; the service and scripts behave as in v2.2.0.

- **Skill `agent-feedback-triage` 2.1**: the optional clustering contract moved to `reference/clustering.md`, read only when clustering is used, and repeated rules were collapsed: SKILL.md is a third shorter per invocation. Install the whole directory, including `reference/`. Resolutions now start with their verdict ( `FIXED`, `INVALID`, `DUPLICATE-OF-<id>`). Fixed: the close-out commands' path to the sibling skill, digest exit codes, the meaning of `unchanged` versus `updated`, and cluster.py's statuses, reasons and exit codes.
- **Skill `agent-feedback`** (contract unchanged): corrected the `machine` override, `--sweep` age/lock/outcome behaviour, backlog-warning scope, TSV column 5, `slots` usage, 1xx/3xx outcomes, export digest tools, and added `AGENT_FEEDBACK_TRIAGE_ROOTS`.
- [api.md](https://agentfeedback.dev/docs/reference/api) states its version (1.1), the non-JSON responses and the `include=payload` row shape.
- [operate.md](https://agentfeedback.dev/docs/reference/operate): the retention purge runs as root, backups create their directory, `openssl` and `DEPLOY_DIR` are documented, and uninstall covers the triage variables.
- `CLAUDE.md` routes to [develop.md](https://github.com/AgentFeedback/agentfeedback/blob/c7573e1b301aa1495f290c417ce2fb390caee544/docs/develop.md), the single home for commands, rules and gates; the README quickstart checks out the latest tag and keeps an existing key.

## v2.2.0 — Triage skill renamed; batched, measured clustering

- **Skill `feedback-triage` is now `agent-feedback-triage` 2.0.** The invocation name and the install directory change: update installers, links and prompts that name `skills/feedback-triage`, and remove the old copy ([operate.md](https://agentfeedback.dev/docs/reference/operate#uninstall) lists both names). Digests move to `${TMPDIR:-/tmp}/agent-feedback-triage/`. No service/API or storage changes.
- The triage skill is direct invocation only: `disable-model-invocation: true` (Claude Code) and a description that forbids loading it from phrasing about the queue. Invoke it as `/agent-feedback-triage` or by name.
- Docs: install guidance for the triage skill, the rule to re-measure after any `cluster.py` prompt, threshold or batching change, and the eval script's disclosure boundary in [security.md](https://agentfeedback.dev/docs/reference/security).
- `cluster.py` batches comparisons: up to 8 reports per request, every pair asked once over a shared state, so 24 reports need 15 requests instead of 276 (which exceeded the old cap and skipped advice). One request per pair remains the fallback for batch sizes below 4 and for chunks over the model's token budget; a pair too large alone is marked unassessed without a request. One invalid answer in a batch marks only that pair.
- **`--max-pairs` is replaced by `--max-requests`** (default 200); the old flag is rejected because its unit changed. New `--batch-size` (default 8).
- Probability sums tolerate the model's per-option two-decimal rounding.
- Calibration recorded in the skill: on 112 labelled pairs, no different pair was grouped at the 0.8 threshold; consent, dry-run, key handling and complete-link grouping are unchanged. `scripts/eval-cluster.py` repeats the measurement and refuses to send any report whose exact remote was not approved with `--allow-repo`.
- Go module dependency updates (indirect only).

## v2.1.0 — Optional advisory triage clustering

- **Skill `feedback-triage` 1.1** adds a Python 3.9+ helper that compares report mechanisms through TypeSafe and suggests clusters. The manual workflow remains the default; no service/API or storage changes.
- Disclosure requires explicit approval for each exact repository identity. Preview is local; unapproved or unidentified reports are never sent. No credential is copied, no queue item is marked, and no report is removed.
- Advice retains source IDs, the digest hash and individual probabilities. Groups require agreement for every member pair, not transitive matches. Uncertain, unavailable and invalid answers fall back to manual triage; bounded requests preserve partial results without dropping reports.

## v2.0.0 — SQLite, generic events, triage skill

Breaking operational contract, compatible API.

- **Storage**: PostgreSQL replaced by SQLite ( `modernc.org/sqlite`, pure Go). One container, one named volume, no database service. Physical backups via `feedback backup`, logical via `GET /api/v1/export`; restore and migration via `feedback import` (all-or-nothing, header/count/digest verified, hashes recomputed, `--family` filter, ids never reused). See [operate.md](https://agentfeedback.dev/docs/reference/operate#restore-and-migration) for the 1.x migration procedure; `scripts/export-v1-postgres.sh` produces the import file from a 1.x deployment with ids, timestamps, processing state and hashes preserved.
- **API 1.1** ([api.md](https://agentfeedback.dev/docs/reference/api)): additive. `family` and `payload_hash` on every record, `POST /api/v1/events`, `resolution` when marking processed, keyset pagination ( `before_id`, `has_more`, `next_before_id`, `total`), `include=payload`, `GET /api/v1/export`, six-digit timestamps. Every 1.0 request and response field is unchanged.
- **Service**: stdlib `net/http`, Prometheus with bounded labels plus backlog, database size and busy counters. OpenTelemetry, chi, sqlc and the PostgreSQL-specific configuration are gone. `GRACEFUL_SHUTDOWN_TIMEOUT` default is now 30s; the fixed 5s drain sleep is removed. Payloads are returned byte-exact (large integers no longer round).
- **Deployment**: `scripts/deploy.sh <sha>` installs the compose file, preserves the host `.env`, pins the image there and runs `docker compose pull && up`. Requires the GHCR package to be pullable by the host. The `crane` streaming path is gone.
- **Skill `agent-feedback` 3.0**: new `submit-event.sh`; `process.sh list` pages through the whole queue and takes `--include-processed` (the old `--all` errors), `done` takes `--resolution`; `query.sh export`; `submit-review.sh --sweep` scans `REVIEW_LOG_DIR` and `AGENT_FEEDBACK_REVIEW_DIRS` only (set the latter where hardcoded cache paths were relied on). Fixes: spool persistence is verified (an unwritable spool now fails loudly instead of reporting `spooled`), review receipts are validated before a run is marked submitted, large prose no longer passes through argv, `--dry-run` applies the server's validation, rejected spool files are kept 30 days as documented.
- **New skill `feedback-triage` 1.0**: end-to-end queue processing with one consolidated interview. `scripts/digest.sh` pulls and groups the open queue.
- **Docs** rewritten for agents first: README route table, `api.md`, `operate.md`, `develop.md`, `security.md`. Template-era documents removed; `docs/agent-usage.md` redirects to `api.md`.

Upgrade: follow the migration procedure; the 1.x PostgreSQL volume is not read by 2.x. Producers need skill 3.0 only for the new features; 2.1 clients keep working against the 2.0.0 service.

## v1.0.1 — Public documentation and release workflow

Compact README with dedicated guides, guarded release tooling, updated Go modules, toolchain, container bases and CI actions. No API or migration changes.

## v1.0.0

Initial stable API and companion client release.

[Session logs \`agentfeedback sessions\` reads the session logs a coding-agent harness keeps on disk, on demand and read-only, so an agent can turn what went wrong in a past…](https://agentfeedback.dev/docs/reference/sessions) [Client installation You are an AI agent asked to install the AgentFeedback client and set it up for the harness you run in.](https://agentfeedback.dev/docs/reference/agent-install)

[Canonical HTML](https://agentfeedback.dev/docs/reference/releases)
