Skip to content

Changelog

What each release of Winner AI changes, from 0.4.0 on, and whether it asks anything of the people running it. The format follows Keep a Changelog, and versions follow semantic versioning.

A change customers would notice adds a line to Unreleased in the same pull request that makes it. Cutting a release renames that section to the version being tagged.

Releases 0.5.1 to 0.9.0, published before the release workflow began taking its notes from this page, still carry notes generated from pull request titles. From the next release on, each released section is the body of that version's GitHub release: the release workflow copies it into the draft and refuses a tag with no section here before the build. A section's Requires of you always carries a Members: line saying whether members must reinstall the client or sign in again, "nothing" when they need not. Released sections use plain Markdown, because GitHub shows MkDocs-only syntax such as admonitions as raw text.

Unreleased

0.13.5 - 2026-11-05

Changed

  • Laptops and the Dashboard run the session collector (agentsview) 0.44.0. An empty Cursor conversation row no longer stops every push. A cut-off one still stops that laptop's Cursor sessions, and a new message to another agent's session it already sent can wait for the next periodic push, every 15 minutes. The first push after a laptop updates sends every session again, and takes longer than usual: one test laptop with 237 sessions took about 8 seconds, and a real laptop's history is larger.
  • The guide and the control plane's pages describe Winner AI in its own terms: the laptop program is the session collector, and the server's session browser is the Dashboard. The Dashboard's remaining "agentsview" chrome is renamed too: the About dialog's label, the chart palette's name in Settings > Appearance, and the Remote access description.

Requires of you

  • Operators: upgrade the server first: its first start migrates every organisation's data, within the deploy's thirty-minute wait. Then every laptop takes the new collector through winner update. From the first laptop push on 0.44.0, a laptop still on collector 0.42.0 is refused until it updates, and going back to the previous release means restoring the backup the upgrade took.
  • Members: nothing on a laptop whose winner login installed its services: the daily update brings collector 0.44.0. A laptop enrolled with --no-service gets it with winner update.

0.13.4 - 2026-11-04

Changed

  • The guide now reads right for a server installed from the bundle, after an audit of every page against the release: JumpCloud lists the India region and says to ask support first in the European Union and India regions, the private-network steps say the zone check needs outbound port 53, the Postgres jail example is switched on, pointing the stack at a hosted model recreates Ollama too, and the macOS client's folder-access limit on an unsigned build is stated.
  • The server install guide now says how to install Docker Engine and the Compose plugin on Ubuntu from Docker's own repository, removing Ubuntu's older docker.io packages first.

Fixed

  • On a server installed from the bundle, laptops were told to push to POSTGRES_PORT, which the template sets to 5433, while Postgres is published on 5432; laptops are now always told 5432.
  • The files the bundle ships name the guide's pages instead of source files the bundle lacks, and name the settings an operator sets. A restore whose stack failed to start says so instead of "started again", and an upgrade refuses an unreadable .env with the real reason.
  • Admin showed "1 sessions" on a laptop that had pushed one session; it now reads "1 session".
  • A repo choice made on the web page is no longer shown applied while a background push that did not stop, or agentsview's own push service that could not be removed, is still sending the old list. The choice stays pending until a later report sees every push on the new list.
  • A Member approving a laptop login saw the Manager sidebar, whose Admin, Settings and Dashboard links each answered "Manager role needed"; the page now shows a Member only Home and Sign out.
  • A laptop whose pass the control plane refuses told a removed person only to run winner login, which cannot let them back in; winner report and the hostname reporter's log now add that if the sign-in page says the account was removed, a Manager restores it.
  • After an upgrade a browser could keep showing the previous release's guide pages; the guide now tells the browser to check for a newer copy on every visit.
  • After a Restore nothing told the Manager what the person does next; Admin and the identity guide now say that the restored person runs winner login on their laptop again.
  • A model whose calls all failed made Skills and Coaching look like a team with no data. Both pages and Settings now say the model call failed, with its HTTP status or Bedrock error type, whose model it was and when a call last worked; a Skills pass whose naming calls all failed is recorded as failed.

Requires of you

  • Operators: nothing to change. On a server installed from the bundle whose .env kept the template's POSTGRES_PORT=5433, laptops enrolled before this release were told the wrong port: each runs winner login again after the upgrade. The post-login Action changed only in a comment, so it need not be deployed again.
  • Members: nothing.

0.13.2 - 2026-11-04

Added

  • On AWS, the server's .env secrets can live in AWS Secrets Manager: ./scripts/env-from-secrets.sh reads one secret with the server's instance role and writes its keys into .env, before the install and again after a rotation. The bundle ships it.
  • Each guide page offers its Markdown with a Copy page as Markdown button, and the guide serves an llms.txt index for AI agents.

Changed

  • Getting started and help now gives the support address, support@getwinner.com.
  • The identity guide and the configuration reference now give one answer on admitting a sign-in whose e-mail the provider has not verified: it stays on by default, and an operator who wants verified addresses only sets OAUTH2_PROXY_ALLOW_UNVERIFIED_EMAIL=false.
  • The guides now match 0.13.1 on the points a first install meets: sign-in through any OpenID Connect provider, check-env.sh before the install, full-tunnel VPN and macOS laptops, what a network change mid-push does, the licence's first-start grace, and the commands each page gives.
  • The guide now lays out the install in order, from choosing the server's name to backups, and adds the install steps for the licence, the features, laptops and backups. Pages written for Winner AI's own team no longer ship in it.

Fixed

  • The server bundle now ships the Auth0 post-login Action that the onboarding guide deploys to the tenant; earlier bundles lacked it, so an operator who installed from a bundle had no copy to deploy or compare.
  • The client installer now warns when git is missing or older than 2.36, which winner login and winner repos need to list a laptop's repos, and the client guides say how to get it on Ubuntu 20.04 and 22.04, Debian 11 and macOS. Such a laptop used to install without a word and then choose no repos at sign-in.

Requires of you

  • Operators: only on Auth0, and only where the server was installed from a bundle: compare the tenant's post-login Action with this release's copy (docs/onboarding.md, "The post-login Action", has the commands), and deploy it if it differs or is missing.
  • Members: nothing.

0.13.1 - 2026-11-03

Fixed

  • The command beside OAUTH2_PROXY_COOKIE_SECRET in .env.example made a secret the sign-in gate refuses about three times in four, so the gate stopped at start and nobody could sign in. The comment now gives a URL-safe command, and ./scripts/check-env.sh refuses a secret the gate would not start with, before anything starts.
  • The server diagnostics file could keep the domain of a person's e-mail address, and drop the log fields beside it, when the edge logged a request's headers. Every address is now masked in full, on the server and in winner diagnostics.
  • A laptop that changed network during a push, by joining or leaving a VPN for example, could leave its database session holding locks for about two hours, so every push from that laptop waited behind it. The server's Postgres now drops a client that stops answering within about two minutes, and the laptop's next push goes through.
  • A new installation no longer names its organisation "Winner AI Test" in its page headers. The name is now ORG_DISPLAY_NAME in .env, read when the organisation is first made, and Winner AI when it is unset. An installation that already exists keeps its name.
  • ./scripts/check-env.sh, run by hand in the unpacked bundle before the install, now accepts a .env filled in as install step 4 says. It used to require the release and image keys the installer writes, and told the operator to ask the repo owner.
  • On a JumpCloud organisation in the United States region, signing out now ends the person's JumpCloud session. The identity guide and the JumpCloud checklist now give the User Portal's logout as the end-session address, https://console.jumpcloud.com/userconsole/logout. The address they gave before refused the sign-out and left the person signed in.
  • The upgrade command and the installer, refusing a bundle older than the release the server runs, no longer tell the operator to roll back to that bundle's release: the rollback goes back to the release the last upgrade replaced, and the refusal now says so and names --bundle and --backup for an older release. The upgrade command's --help now says the default backup goes in the folder the new bundle's archive is in.
  • After an upgrade that failed or was cut off, scripts/rollback-server.sh in the release it started from now refuses and names the restore that undoes the attempt; it used to offer to undo the upgrade before it, from that upgrade's older backup.
  • On a laptop with a long history of coding sessions, the background push now starts agentsview and waits up to 30 minutes for its first sync to finish before pushing, rather than running beside it, which could leave that sync stalled part-way with nothing pushed. Meanwhile winner repos says agentsview is still starting and how far its sync has got, instead of that it is not running. On macOS winner push stop now also stops the running agentsview daemon, including one started from the agentsview desktop app or a shell, which it used to leave running.

Requires of you

  • Operators on a JumpCloud organisation in the United States region: set OIDC_END_SESSION_URL=https://console.jumpcloud.com/userconsole/logout in .env, and in OAUTH2_PROXY_WHITELIST_DOMAINS replace oauth.id.jumpcloud.com with console.jumpcloud.com, keeping any other host already listed. Then run docker compose up -d. In the European Union region, step 10 of the JumpCloud checklist says what is still unconfirmed.
  • Members: nothing on a laptop whose winner login installed its services: the daily update brings the client's first-sync and diagnostics fixes. A laptop enrolled with --no-service gets them with winner update.

0.13.0 - 2026-11-03

Added

  • With usage counts on, a script error on a Winner AI page is reported with its type and our own line numbers, never its message.
  • A guide page, Upgrade and roll back, gathers installing a later release and going back to the previous one, says why an older release is refused, and what laptops do after each.
  • A Licence page in the guide: installing and renewing the licence file, the dates its banner counts, and what switches off when the grace ends.
  • Model and telemetry now says in one place what blank telemetry settings guarantee, which setting switches each kind and what Settings shows for it, what is never instrumented, and where the values we hand over send events.
  • A repo choice a Member saves on the web page now takes effect on their laptop at its next hourly report, with no terminal: the laptop sends the name and state of each of its repos and nothing else about them, applies each choice itself as winner repos allow or block would, and reports a choice it refuses with the reason. A laptop enrolled with --no-service keeps using winner repos.

Changed

  • Enrolling a laptop whose hostname contains a comma is now refused, because the Dashboard's machine filter would read that one name as several laptops.
  • fleetview-deploy, the host deploy timer, now installs each release from its signed server bundle placed in /srv/fleetview, through the bundle's own scripts/upgrade-server.sh, and goes back to a pinned previous release through scripts/rollback-server.sh, which restores the database as it was before that upgrade. Only FLEETVIEW_PIN in the running release's .env rolls back; a release named on the command line must be newer. It needs no registry token and pulls none of our images, it does not retry a failed upgrade every tick (an upgrade still migrating is slow, not failed, and each tick runs its --finish until it is done), and it proves that the running backend is the image loaded from the bundle with every migration applied, the web server is the pinned stock Caddy base running the bundle's binary, and Postgres reads the certificate mode's certificates; in the DNS certificate mode also that the certificate helper holds a certificate and the edge is told of each renewal, as the installer checks. Each tick still checks the web server, the edge, the proxy and the certificate wiring, and starts the release's services again from its folder when one has drifted, unless the certificate settings in its .env are not the ones it was last proved with, a rollback is under way, or the database is fenced for a restore. It refuses to start a compose file COMPOSE_FILE names that anyone but root can write.

Fixed

  • A server installed from the bundle now has the server diagnostics command: sudo ./scripts/diagnostics-server.sh, run in the folder of the release that runs now, writes into your home directory the same redacted file for a support case that sudo fleetview-diagnostics writes on a server set up with the host scripts, and names its path. It needs jq on the server.
  • The guide's Model and telemetry, Connect your identity provider, Onboard on Auth0, Deploy and Operations pages now give the commands for a server installed from the bundle, Install the server says once how to read a host's commands there, and Configuration and Architecture name the .env check every install runs. Before, they gave only a host's /srv/fleetview, make check-env and an explicit compose file pair, which fail in an install folder or leave out the bundle's own compose file.
  • A person's "You spent" on Prompt Coaching counts each session once when their laptop is known by more than one name, such as its old hostname and the ID a newer client records.
  • winner report now sends a laptop's earlier hostnames, and from agentsview 0.43.0 its installation ID, when agentsview has closed the local session database cleanly before the hourly report; it used to send none then.
  • winner login now says when the client is older than the control plane's sign-in and gives the step that updates it, naming the control plane's winner version, instead of saying the control plane returned an incomplete config; winner update now reads that version from such a control plane instead of failing the same way.
  • The server install guide now says, at the step that fills in .env, that Prompt Coaching, Skills and Benchmarks show Soon until FLEETVIEW_FEATURES lists them, and that they fill only once a model answers; it used to leave all three showing Soon without saying why.
  • Prompt Coaching, Skills and Benchmarks no longer treat the prompts a zcode agent wrote to its own subagents as prompts a member typed, and Benchmarks prices those subagents' replies in its subagent saving like any other agent's. Coaching results already judged for such prompts are not recomputed and stay on the Coaching page until they leave its window.
  • The server install guide now gives a trial's laptops their own install and sign-in lines; the documented line only accepted an https control plane, so a trial's laptop could not install the client.

Requires of you

  • Operators: on a hosted model, the upgrade spends model calls once, on every organisation whether or not it uses zcode: every Benchmarks task is replayed on each candidate Route and judged again, within benchmark_daily_runs a day, and typed patterns are renamed, twenty per sweep. Until its replays return, a task that showed Tested and a proven saving shows its estimate again. The subagent and context saving lines are missing until the first sweep after the upgrade. A Skills workflow found again keeps its name.
  • Operators: only where fleetview-deploy runs: it now moves only a release installed from the bundle (docs/install-server.md) and takes each release's winner-ai-server-<X.Y.Z>.tar.gz from /srv/fleetview. On a host still on the registry deploy, do this before this release is published: stop the old deploy with sudo systemctl disable --now fleetview-deploy.timer, install the running release from its bundle, first carrying /srv/fleetview/.env into the release folder (root's, mode 0600), then run the host scripts' installer from a checkout that holds it, which starts the timer again. The host scripts are not in the bundle. Left running, the old deploy copies this release's files over /srv/fleetview and hands over to the new script, which fails every tick while the containers stay on the previous release. /etc/fleetview/ghcr-token is no longer read, and can be removed. The deploy keeps the certificate mode the installer set up and never switches it.
  • Operators: nothing, unless a host overlay overrides OAUTH2_PROXY_SKIP_AUTH_ROUTES: it must add ^/api/v1/devices/repos$ and ^/api/v1/devices/repo-choices$, which laptops now call.
  • Members: nothing; the daily update brings the new client.

0.12.0 - 2026-10-30

This is the first release you can install on your own server from the signed self-hosting bundle. Releases 0.10.0 and 0.11.0 were prepared but never published, so an installation upgrading from 0.9.0 takes their changes with this one: their own sections below list them in full, and Requires of you here gathers what each asks of an operator.

Added

Signing in through your own identity provider

  • A production installation can sign people in through JumpCloud or any other OpenID Connect provider, not only Auth0. The sign-in gate's issuer, scopes, groups claim and the hosts sign-out may send a browser to are .env settings (OAUTH2_PROXY_OIDC_ISSUER_URL, OAUTH2_PROXY_SCOPE, OAUTH2_PROXY_OIDC_GROUPS_CLAIM, OAUTH2_PROXY_WHITELIST_DOMAINS), each defaulting to Auth0's, and sign-out ends the provider's session at the address OIDC_END_SESSION_URL names. The .env check refuses an end-session address the gate would not send a browser to, an issuer or end-session address that is not https on an https installation, and a whitelist entry for a whole public suffix (.com, *.co.uk).
  • Each person is keyed on the provider's issuer and their id there together, so a second provider presenting the same id is another person, and an Auth0 installation keeps every person and laptop through the upgrade with nothing to do. With a provider other than Auth0, leave both AUTH0_MGMT_ keys blank and name the Managers with FLEETVIEW_MANAGER_GROUP; the .env check and the server refuse the Management keys there. Keep the issuer once people have signed in: a new one meets everyone as a new person.
  • On an installation with no Auth0 Management credentials, the control plane reads a person's role from the sign-in provider's groups: a person in the group FLEETVIEW_MANAGER_GROUP names is a Manager, and where sign-in brings no usable groups the addresses in FLEETVIEW_MANAGER_EMAILS are. Settings shows both and the groups claim under Features and host. The .env check refuses FLEETVIEW_MANAGER_EMAILS unless OAUTH2_PROXY_ALLOW_UNVERIFIED_EMAIL is false. An installation with Auth0 Management credentials resolves roles as before.
  • On an installation with no Auth0 Management credentials, a Manager removes a person on Admin: their laptop passes end, their laptops' database logins are dropped and the row reads revoked. Restore makes them a Member again with no laptop until they run winner login. With Management credentials, Admin says people are removed in Auth0. A removed person who signs in is told they were removed from the team. Revoking one laptop also ends its laptop pass, and the person's other laptops keep reporting.
  • The control plane serves its own laptop login on any sign-in provider: a laptop starts a login, a signed-in person approves its code at /login/approve, and the laptop collects a laptop pass once. winner login signs in through it whatever the provider: it prints a code and the complete approval address, which work in any browser on any machine, so it also works over SSH. The hourly reporter keeps the laptop pass and asks no sign-in provider for a token. With --no-service, a reporter an earlier login installed is handed the new pass. A laptop that last signed in with Auth0 keeps reporting as before until its next winner login.
  • A trial installation signs in through a bundled, stock Dex under the compose profile trial: two users in deploy/dex/config.yaml, manager@example.com (a Manager) and member@example.com, password winner-trial, behind the same sign-in gate and on loopback only. The .env check and the control plane refuse an https base URL with the trial on or with the bundled Dex as the issuer. Four gate settings, OAUTH2_PROXY_SKIP_OIDC_DISCOVERY, OAUTH2_PROXY_LOGIN_URL, OAUTH2_PROXY_REDEEM_URL and OAUTH2_PROXY_OIDC_JWKS_URL, default to discovering from the issuer, and the .env check refuses them on an https base URL.

Installing, upgrading and backing up the server from the bundle

  • Each release attaches the self-hosting bundle, winner-ai-server-<X.Y.Z>.tar.gz: the compiled control-plane image, the stock agentsview and oauth2-proxy images at their pinned versions, the web-server binary for linux/amd64, the compose files, the environment template, the configuration the stack mounts, the notices file and the documentation PDF. Its SHA256SUMS lists every file and is signed with the release key, in the same namespace as the winner download's. The database, web-server base and local-model images are not in it; the server pulls those itself, by digest, from Docker Hub with no login.
  • The bundle installs itself: ./scripts/install-server.sh in the unpacked bundle checks the bundle's signature against the release key it carries, never one from the bundle, then every file against SHA256SUMS, all before it loads any image, and refuses a bundle with no signature, a changed SHA256SUMS or a signature by another key, naming which. A server without ssh-keygen is told to install OpenSSH 8.1 or later. Checking the bundle by hand first, as the install guide shows, is still how you know the installer itself is ours. It then runs ./scripts/check-host.sh, which names every fault of the server in one pass, one line each (linux/amd64, Docker Engine 28.0 and Compose 2.24.4 or later, free disk, ports 80, 443 and 5432 free, Docker Hub in reach, the clock within 5 seconds and a working ssh-keygen), and stops on any. It starts the stack and proves the web server runs the bundle's binary and the control plane reports the bundle's release. It refuses an environment file the check refuses and an image Docker Hub will not serve, each before anything starts, and fails rather than reports success when an org schema holds code stock agentsview does not create.
  • An operator upgrades a server installed from the bundle with one command, scripts/upgrade-server.sh <new bundle>. It checks the new bundle's signature and every file, the new release's environment check and Docker Hub images, and backs up the database, all before it touches the running release. It then loads and starts the new release and waits for it to report the new version with every migration applied. On a failure it puts the previous release's containers back and prints the restore command with the backup's path. The installer and the upgrade command refuse a bundle older than the release the server runs, saying that migrations do not reverse.
  • An operator rolls a server back to the release an upgrade replaced with one command, scripts/rollback-server.sh, from the newer release's folder. It checks the previous release's signature and every file, refuses a backup that is partial or marked failed, says that everything written since the upgrade will be replaced and waits for the operator to confirm. It then restores the pre-upgrade backup, keeping laptops out and the database as it was before the rollback in a backup of its own, and starts the previous release only once the restore has passed. A laptop enrolled since the upgrade must run winner login again, and a Device revoked since must be revoked again. Known limit: sessions laptops pushed between the upgrade and the rollback are lost from the archive, since stock agentsview does not push them again; they are in the pre-rollback backup.
  • The bundle carries scripts/backup-server.sh <file>, which writes one tested, owner-only backup of the whole database, and scripts/restore-server.sh <file>, which refuses a partial or failed backup, backs up what it replaces, keeps laptops and the stack out until the restore matches the backup, and names any Device revoked since the backup was taken. Both refuse a database holding a CHECK constraint or generated column stock agentsview does not create, which a restore would run as the database superuser, and the deploy audit reports one.
  • The bundle installs as a trial: with trial in COMPOSE_PROFILES and the trial block of .env.example, scripts/install-server.sh runs the stack on http://localhost:4180 with the bundled Dex, no edge and nothing published beyond loopback. The .env check refuses a trial that stacks the production overlay, and the installer refuses a trial in a folder that still holds a production install. A trial runs as its own compose project (fleetview-trial unless .env names one), so a production install made later on the same machine never shares its database.
  • An installation serves one organisation, the one AUTH0_TEST_ORG_ID names, configured once. The dashboard takes that organisation from the control plane at start, and nothing in the compose files or the web-server configuration names an organisation, schema or role. A manager of any other organisation gets a 403 at the Dashboard.

Private networks and the DNS certificate mode

  • CERTIFICATE_MODE=dns in .env starts a stock certificate helper (lego) beside the edge. It obtains one certificate for PUBLIC_HOST and PUBLIC_PG_HOST through a TXT record in their public Route 53 zone (AWS_HOSTED_ZONE_ID, AWS_REGION), using the server's instance role, and keeps it renewed. The edge serves that certificate for both names and asks no certificate authority for one, so the server needs no inbound port 80; port 80 still redirects to https. The edge presents each renewal within a minute without a restart, and Postgres within five minutes, so enrolled laptops keep verifying it with nothing pinned. Until the first certificate exists the edge serves nothing. The default, http, changes nothing.
  • The bundle installs in the DNS certificate mode: the installer starts the certificate helper, waits for its first certificate and fails, saying why, when the helper cannot get it. It records the mode's profile in .env, so a later docker compose up -d in the bundle folder keeps it.
  • Before such an install, scripts/check-dns-zone.sh on the server checks the certificate's prerequisites: with the server's instance role it writes one test record in the Route 53 zone, reads it back from the zone's name servers and removes it, then checks the certificate authority answers and the helper's image can be fetched. It prints a pass or fail line per check and no credential, and changes nothing else.
  • The .env check refuses a CERTIFICATE_MODE other than http or dns, and in the dns mode an .env without AWS_HOSTED_ZONE_ID and AWS_REGION, with a base URL that is not https, or with a PUBLIC_HOST or PUBLIC_PG_HOST that is not a lower-case DNS name. No AWS key is asked for.
  • Where laptops reach Postgres through a VPN and share its addresses, the operator can declare the VPN's ranges in VPN_RANGES. The host watch then counts refused logins from them apart, against AUTH_FAIL_VPN_LIMIT (60 in ten minutes), and a second fail2ban jail, fleetview-postgres-vpn, bans them on that count, so one laptop with a stale password no longer locks out every laptop behind its address for an hour. A deploy refuses ranges it cannot trust. With nothing declared, nothing changes.

Amazon Bedrock

  • An operator can run Prompt Coaching, Skills and Benchmarks on Amazon Bedrock (FLEETVIEW_LLM_PROVIDER=bedrock, FLEETVIEW_LLM_REGION), signed with the server's instance role or a Bedrock API key. A team's own model stays OpenAI-compatible. The model guide gives the settings, the instance role's policy, what the AWS account needs and what each Bedrock error means. No Claude model on Bedrock has passed the model check yet.
  • fleetview-model-check checks the server's model before Prompt Coaching is switched on, from the installed stack alone: it runs the coaching judge over the labelled set the release ships, compares the scores with the release's baseline and ends verdict: pass or verdict: fail, with the run's cost in calls and tokens. It prints no prompt and nothing the model wrote. --limit N is a quick try that is never a verdict.

Members' own pages

  • A Member's Home shows their own sessions and nothing of the team's: sessions over time, today and in the range, output tokens, sessions by coding agent, active sessions, when their data was last seen, their latest sessions, and how many of their own prompts were flagged while Prompt Coaching is on. Only sessions the control plane has matched to them are counted. A Member with none yet is told why and pointed to their laptops.
  • A Member can open Prompt Coaching at /coaching for the findings on their own prompts and what their own sessions spent, with no person picker and nothing of the rest of the team.
  • A Member can open Skills to see the repeated workflows found in their own prompts, with their own evidence only, and download an approved Skill made from one of them.
  • A Member can open Benchmarks to see their own prompt patterns: each pattern whose latest run on its usual model was one of their own sessions, and what a cheaper model did when it re-ran their own example. No figure counted across the team is shown, and Run benchmark stays a Manager's.
  • /devices shows a person their own laptops: each one's name, when it was enrolled, and whether it is still enrolled or was revoked. Someone with no laptop is shown how to run winner login.
  • /repos shows the repos each of a person's laptops last reported, and lets them allow or block each one. The page only queues the choice for the laptop, which alone applies it; until the laptop reports back, the page shows the choice as pending, or the laptop's reason if it refuses. A name that stands for more than one checkout shows as refused and cannot be allowed.

Choosing which repos a laptop sends

  • winner login at a terminal on a laptop with no repo choice lists the laptop's repos with none ticked and sends only the ones the developer ticks; quitting the list saves nothing and sends nothing. Without a terminal it chooses nothing, sends nothing and prints the command to choose. A laptop that has chosen keeps its choice and is not asked again.
  • winner repos and winner repos list show each repo agentsview knows on the laptop, grouped into sent to your team, chosen but waiting for winner repos apply, waiting for you, and not chosen, with its session count and the checkouts behind it, and take a filter (winner repos list web). They need git 2.36 or newer and say so on an older one.
  • winner repos pick opens the same list, filtered by typing /text, ticked with numbers and ranges, a and n; winner repos allow and winner repos block take repo names (web-app is read as web_app) or --all. winner repos mode ask|block says what happens to a repo found later: ask, the default, keeps it unsent and lists it as waiting; block keeps it unsent without asking. Allowing a repo says its earlier sessions are sent too; blocking one says its new sessions stop and those already sent stay.
  • winner repos apply applies a changed choice without signing in again: the background push stops, takes the new list and resumes. A push stopped with winner push stop stays stopped and takes the list when started.
  • A repo name that several checkouts share, Cursor's folder names included, is never sent: allowing it would send all of them. winner repos separate <repo>, or allowing the name at a terminal, asks a new name for each checkout and offers to allow each once agentsview lists it. A name already sent cannot be separated: what was sent stays merged under it. winner repos rename <repo> changes nothing and says why: renaming a repo already sent would make the next push delete what was sent from your team's server.

Support and the guides

  • winner diagnostics writes one file for a support e-mail: the winner and agentsview versions, the push service's state, the control plane the laptop enrolled against, the newest push failure and the last lines of the push log, with passwords, tokens, e-mail addresses, paths and machine names removed. It sends nothing; read the file before you attach it.
  • On a server set up with the host scripts, sudo fleetview-diagnostics writes one file for a support case: the build, every setting on the Settings ledger with the layer it came from, each service's image and state, and each service's last log lines, redacted. Keys show only as set or not set, and the stack's secrets are masked wherever their exact values appear; any other secret a log line carries is caught only by pattern, so read the file before you send it. It sends nothing.
  • When winner login or winner update fails on an enrolled laptop, winner sends a short report of the command, the step, the HTTP status, the kind of error, the versions, the operating system and the processor type to the control plane it enrolled against, and nowhere else; winner login prints a notice saying so. The report never holds the error's text, a path, a URL or a repository name, and never changes how the command ends.
  • New guides: a self-hosting overview and prerequisites page; Install the server, from the signed bundle start to finish; Network, for choosing between a public deployment and a private one reached over a VPN; Connect your identity provider, with a JumpCloud walk-through and a checklist for a JumpCloud administrator, both written from JumpCloud's documentation and not yet followed on a live organisation; backup, restore and uninstall; a laptop client guide for macOS and for Ubuntu or Debian; troubleshooting for an installation from the bundle; and getting started and getting help, whose support address and response targets are still to be confirmed. The Auth0 steps stay on Onboard on Auth0.

Licence

  • Settings has a Licence section. A Manager uploads the licence file Winner AI sent, and the page shows the customer, licence id, issue and expiry dates and seats. A file that was changed, signed by another key, or issued before the licence in force is refused with the reason.
  • Settings shows how many seats are in use: the people with at least one enrolled laptop, each counted once however many laptops they have. When the licence's seat number is exceeded, Settings and Admin both say by how many; nobody is refused, and the difference is settled at renewal. Nothing reports the count to Winner AI.
  • Until a licence is installed and in date, the Manager pages carry a banner naming the expiry date (or saying that none is installed), and for the 30 days of grace after that, the day Coaching, Skills and Benchmarks switch off. Without a licence the 30 days count from the installation's first start, which a restart or an upgrade does not move.
  • After the grace, Coaching, Skills and Benchmarks show a page that says the licence has lapsed: their jobs stop, their actions and Skill downloads are refused, the sidebar no longer lists them, Home hides their figures, and Settings shows them off with the reason. fleetview-jobs replay and fleetview-jobs gate refuse a task while Benchmarks is off for its team. Nothing is deleted: uploading a valid licence brings them back with everything they had. Sign-in, the roster, laptops, pushes, downloads and the Dashboard keep working.

Changed

  • Anyone your identity provider admits can now sign in. A Member sees their own pages, listed above; every manager page and the Dashboard answer them with a page saying the Manager role is needed, and show no team data.
  • A sign-in lasts one hour, not a week. When it ends the gate sends the person back to your identity provider, which admits or refuses them again, so a person you remove loses web access within the hour. A provider that keeps its own browser session signs people straight back in. FLEETVIEW_GATE_SESSION_SECONDS sets the lifetime, and Settings shows it.
  • An installation that signs in through Auth0 may leave AUTH0_MGMT_CLIENT_ID and AUTH0_MGMT_CLIENT_SECRET blank and take each person's role from the gate's groups, as one on any other provider does: FLEETVIEW_MANAGER_GROUP=manager, the Auth0 role the post-login Action already sends. The .env check then requires FLEETVIEW_MANAGER_GROUP or FLEETVIEW_MANAGER_EMAILS, and refuses one Management value set without the other.
  • On Auth0, the post-login Action refuses a sign-in to the control plane through any Organization but the installation's own, or through none, once it is redeployed from this release with its two secrets. Laptops are not affected.
  • A laptop sends sessions only from the repos its developer chose. winner login writes the chosen list into the laptop's agentsview config and restarts the background push; a laptop with no choice, or one winner cannot read, sends no session at all. The choice is a file on the laptop, ~/.agentsview/fleetview-repos.json. The hourly start-commit report covers only the chosen repos too.
  • A laptop enrolled before repo selection keeps sending the repos it has, and is asked only about repos found later: its next winner login to the same organisation, or its first winner update after the one that installs this release, chooses every repo agentsview lists on it then, once. If agentsview holds sessions under a name outside that list, or the check cannot complete, the laptop keeps sending every repo, says why, and checks again at the next update or login.
  • The laptop's repo picker and winner repos help say what is sent, that managers see it, and that sessions already sent stay with the team and cannot be withdrawn. Of the repos not chosen they say "Sessions from repos you don't choose stay on this laptop, unless one of them carries the name of a repo you chose.", and, when the laptop's search index embeds through a server other than the laptop itself, that their text goes there.
  • The images your server pulls from Docker Hub are pinned to exact digests: PostgreSQL 16.15 with pgvector 0.8.7, Caddy 2.11.7 at the edge, and Ollama 0.6.8. The dashboard web-server image is built from pinned Caddy 2.9.1. An upstream fix to any of them arrives with a Winner AI release rather than on its own.

Removed

  • The second organisation's dashboard slot: the acme compose profile, the pg-serve-b service and its two _B keys. On a deployment that ran it, that organisation's dashboard stops at the upgrade and its data in Postgres is untouched; its Docker volume and .env lines are no longer read and may be removed by hand.

Fixed

  • A winner repos separate that stops partway no longer removes a folder rule under the name you chose for a checkout once that name was sent: removing it would have made the next push delete the sessions stored under it since.
  • Prompt Coaching and Skills no longer judge or show the block the Codex app sends when a person edits a writing block by hand; a prompt that is only that block is skipped, and Benchmarks counts it as an agent's. Coaching re-judges the last 30 days under the daily budget, so its findings thin out until the sweeps catch up.
  • A person removed in Auth0 also loses their laptop passes at the next sync. A pass they had not yet used to enrol used to work again once Auth0 added them back.
  • On Linux, when winner login cannot reach a systemd user manager, the hint it prints carries your user name (loginctl enable-linger alice), so it works on a machine with no login session.
  • A laptop enrolling with an older winner on an installation without Auth0 Management credentials is told to update winner and run winner login, instead of getting a server error.
  • On an installation from the bundle, the installer, backup-server.sh and restore-server.sh reach only the installation in their own folder. A shell that exported COMPOSE_FILE, COMPOSE_PROJECT_NAME, COMPOSE_ENV_FILES or COMPOSE_PROFILES could point them at another installation's database.

Telemetry

Telemetry is off, and stays off unless your operator enters values Winner AI supplies. Error reports, timings and cron check-ins leave only once FLEETVIEW_SENTRY_DSN is set; usage counts only once FLEETVIEW_POSTHOG_KEY, FLEETVIEW_POSTHOG_HOST and the telemetry secret are all set. The telemetry secret the installer writes into .env (FLEETVIEW_TELEMETRY_SECRET) only hashes ids and sends nothing by itself. Settings shows the state of each in its Telemetry group. What is sent, once switched on:

  • Error reports from the control plane and the jobs service: the failure's type, its code location, the route template and a few closed tags, never request bodies, local variables, error text or raw ids. Timings for 2 in 100 requests and jobs passes go with them, never statement text, an address or a prompt; FLEETVIEW_SENTRY_TRACES_SAMPLE_RATE changes the share and 0 turns timings off.
  • With the telemetry secret set, the jobs sweep checks in with Winner AI's cron monitors at its start and end, and fleetview-checkin lets a host job such as the backup do the same: its monitor, status, schedule, duration and environment, never an error's text.
  • Usage counts under hashed ids (a page with no person to hash uses a random id per browser tab) and never with text: a Manager's saved changes, each pass run's outcome, each model call's tokens and timing, when the installation is installed or upgraded, when usage counts are switched on, when a laptop enrols, when the licence state changes, one page view per control-plane page naming its route (never its address or query), and one heartbeat a day with the version, the seats in use, the laptops per push state and counts of laptop versions, systems and processors. Never a person's name, a host name or text. The page analytics library is a pinned build the control plane serves itself; with usage counts off no page loads it, and page recording stays off whatever FLEETVIEW_POSTHOG_REPLAY says.
  • A laptop's failure report goes only to the control plane it enrolled against, which passes it on, closed fields only, at most ten an hour per laptop and never stored or logged, only while error reports or usage counts are on.
  • agentsview's own usage ping and update check are off on the server and on laptops.

docs/model-and-telemetry.md, "Telemetry", lists every field and every event.

After you install

  • Run the checks in docs/install-server.md, "Check the installation": /health answers ok, every service in docker compose ps is healthy, Postgres presents a certificate a laptop can verify, a Manager signs in and out, and a first laptop's push shows on Admin with a session count or a last-push time.
  • In the DNS certificate mode, give Postgres up to five minutes after the first certificate before a laptop's first push; until then laptops cannot verify it.
  • A new laptop sends nothing until its developer ticks at least one repo in the list winner login shows, or the Dashboard stays empty.
  • Upload the licence file Winner AI sent on Settings, and check that its seat number covers the people with an enrolled laptop.
  • Before you switch Prompt Coaching on, run fleetview-model-check against your model and switch it on only on verdict: pass.
  • Check that Settings' Telemetry group shows what you expect: everything off unless you entered the values Winner AI supplied.

Requires of you

A new installation: follow docs/install-server.md from step 1. The upgrade steps below do not apply; those under Every installation do, each where it says it applies.

An installation upgrading from 0.9.0: this release migrates the control database at its first start, with nothing to run by hand. Do these first, in this order.

  • Operators: take a backup (sudo fleetview-backup) before you deploy. A rollback to 0.9.0 after the migration is not code-only: expect to restore that backup.
  • Operators: add two lines to .env, with your tenant's domain written out, or the deploy's .env check refuses it and names both: OAUTH2_PROXY_OIDC_ISSUER_URL=https://<AUTH0_DOMAIN>/ and OIDC_END_SESSION_URL=https://<AUTH0_DOMAIN>/v2/logout.
  • Operators: the sign-in proxy no longer admits only managers, so who may sign in at all is your identity provider's decision. Check that it admits only your team before you upgrade: on Auth0 the sign-in proxy's application must require an organisation, and the organisation's enabled connection must keep assign_membership_on_login: false, or anyone who registers and verifies an address can join the organisation at the login prompt (docs/onboarding.md, "Who may sign in", has the check).
  • Operators: on Auth0, redeploy the post-login Action from this release with its two secrets, the .env values of AUTH0_PROXY_CLIENT_ID and AUTH0_TEST_ORG_ID (docs/onboarding.md, "The post-login Action", has the commands and a check). Before you do, mark verified only the accounts you created yourself and know; the Action refuses an unverified one. Until you redeploy, nothing changes; an Action deployed without the secrets refuses every sign-in until they are set. Then sign in yourself to check it. With the Management credentials blank, also Remove from Admin's roster anyone who is not a member of this installation's Organization (auth0 orgs members list <org id> --number 1000; the default lists only 100).
  • Operators: upgrade first, then switch provider. The migration stamps every existing person with the issuer the installation signs in through at that moment, so moving from Auth0 to another provider in the same step stamps them with the new one. Once people have signed in through the new provider, they are new people: their old rows keep their laptops and history, and nothing carries them across.
  • Operators: PUBLIC_BASE_URL must be the bare address a browser shows, such as https://devtool.example.com: lower case, no trailing slash, no path and no default port, or the deploy refuses it.
  • Operators: the production overlay pins the compose subnet, and the first deploy takes the whole stack down once to move its network there. The server's own networks, VPC and routes must not use that subnet. Afterwards, narrow the fleetview-postgres jail's ignoreip to the pinned subnet (docs/network.md, "The Postgres jail").
  • Operators: a deploy fails when a team schema holds code stock agentsview does not create; docs/troubleshooting.md, "Code in an org schema that agentsview did not create", says how to find and clear it. The postgres and template1 databases admit only a superuser or a role granted CONNECT there by name.
  • Operators: use fleetview-jobs and fleetview-provision in any script of your own; python -m fleetview_backend.jobs and python -m fleetview_backend.provision no longer run in the backend image. A mirror you point FLEETVIEW_AGENT_URL at must publish the release's SHA256SUMS.sig beside SHA256SUMS, unchanged, or the laptop installer refuses it.
  • Operators: on a hosted model, the upgrade spends model calls once: the coaching window is judged again, and every benchmark task is replayed and judged again under the daily limit.
  • Operators: once Linux laptops are enrolled, do not roll back below 0.11.0. winner 0.10.0 cannot update itself on Linux, so laptops told to converge to it stay on it after you roll forward again; if you did, re-run the one-line installer on each Linux laptop, which keeps its enrolment and its running push.
  • The 0.10.0 and 0.11.0 sections below list the rest, each marked for whom it applies, such as the demo seed and a fleetview-postgres jail set up before 0.10.0.

Every installation:

  • Operators: upload the licence file Winner AI sent on Settings within 30 days of the installation's first start (for an upgrade from 0.9.0, its first start on this release), or the Prompt Coaching, Skills and Benchmarks jobs stop, and the sidebar and Home drop them, until you do. Nothing is deleted meanwhile.
  • Operators: only on Amazon Bedrock signed with the instance role: set the instance's metadata hop limit to 2 (aws ec2 modify-instance-metadata-options --instance-id <instance-id> --http-put-response-hop-limit 2 --http-tokens required). A container is one hop further from the metadata service than the server, and at hop limit 1 every model pass fails. docs/model-and-telemetry.md, "Amazon Bedrock", says what that opens to every container.
  • Operators: only in the DNS certificate mode: give the server the instance-role policy docs/network.md gives, run the deploy checks from a machine on the VPN, and expect laptops to push only once Postgres has taken the first certificate, up to five minutes after the edge has it.
  • Operators: only where laptops reach Postgres through a VPN and share its addresses: set VPN_RANGES in .env to the VPN's whole associated subnets, add them to the fleetview-postgres jail's ignoreip, and add a second jail named fleetview-postgres-vpn with a higher count and a short ban (docs/network.md). Otherwise nothing.
  • Operators: nothing to set for the sign-in lifetime: FLEETVIEW_GATE_SESSION_SECONDS is one hour by default. Raise it only knowing it is also the longest a removed person keeps web access.
  • Operators: nothing, unless .env sets only one of AUTH0_MGMT_CLIENT_ID and AUTH0_MGMT_CLIENT_SECRET: set both or leave both blank, or the .env check refuses it.
  • Operators: only if your deploy account is to run fleetview-diagnostics: add it to that account's sudo allowlist beside fleetview-ps and fleetview-logs.
  • Members: on macOS, nothing to reinstall. On Linux, install with the one-line command and run winner login; this is the first published release whose installer runs there. A laptop already enrolled keeps sending the repos it has: its next winner login or winner update keeps every repo agentsview lists for it. A repo found after that, and every repo on a new laptop, is sent only once chosen, at the list a login shows at a terminal or with winner repos pick (docs/laptop-client.md). You are also sent back to sign in about once an hour, silently where your provider keeps its own session; a form left open across that moment is lost.

0.11.0 - 2026-10-15

Added

  • The one-line installer now installs winner and the control plane's agentsview on Linux: Ubuntu 20.04 or later and Debian 11 or later, amd64 or arm64, into ~/.local/bin with no sudo. Before downloading anything it refuses a C library agentsview cannot run on (musl, or glibc older than 2.28) and an ssh-keygen too old to check the release signature (older than OpenSSH 8.1, as on Debian 10), and says which.
  • winner update now installs on Linux (amd64 and arm64): it brings winner and agentsview to the control plane's versions, verified against the same signed and upstream checksums as on macOS, and restarts the background push. A Linux winner login whose agentsview is ahead of or behind the control plane now points at winner update instead of a manual download.
  • On Linux, winner login now installs two systemd user timers: winner-update.timer, which runs winner update at sign-in and daily at noon (a missed noon runs at the next start), and winner-reporter.timer, which reports this laptop's names hourly. --no-service installs neither. Without systemd, login prints cron lines with the absolute path to winner instead, and says nothing was installed.
  • The Dashboard's web server and the production edge now carry health checks. When either cannot run its program, or refuses its configuration, docker compose up --wait fails and docker compose ps no longer shows it healthy, where Compose used to report a running service; the host watch reports one that runs but stops answering as unhealthy.
  • Settings shows a Telemetry group: whether error reports and usage counts are on, where they would go and whether the identity hashing secret is set, never a key. Six operator variables configure them (FLEETVIEW_SENTRY_DSN, FLEETVIEW_SENTRY_ENVIRONMENT, FLEETVIEW_POSTHOG_KEY, FLEETVIEW_POSTHOG_HOST, FLEETVIEW_POSTHOG_REPLAY, FLEETVIEW_TELEMETRY_SECRET); nothing is sent yet.

Changed

  • fleetview-jobs run --once now exits 1 when an organisation's sweep raised, where it always exited 0, so a script that reads its exit code sees the failure. --org <Auth0 organisation id> sweeps that organisation alone and exits 2 when no organisation has that id. fleetview-seed-demo passes it: a deployment's demo seed now sweeps only the demo org, and its sweep step fails when that sweep raised.
  • make seed-demo is now the whole local demo in one command. It seeds the team, attributes every session, reads Team spent, runs one jobs sweep on the stack's local Ollama model, never the model .env configures unless SEED_DEMO_CONFIGURED_MODEL=1 asks for it, and prints what Home, Prompt Coaching, Skills and Benchmarks now show. It refuses before seeding, with the fix, when the stack is not up and healthy, when the Ollama profile is off or its models are not pulled, when FLEETVIEW_FEATURES leaves out Coaching, Skills or Benchmarks, or when it cannot stop the stack's jobs service for the run.
  • The production TLS edge runs Caddy 2.11.7, up from 2.9, which brings upstream fixes, security fixes among them. Request headers are now capped near 16 KiB over HTTP/2 and 20 KiB over HTTP/1.1, where 2.9 allowed 1 MB: past the cap the edge answers 431 Request Header Fields Too Large, or over HTTP/2 may close the connection instead. It aborts a connection whose upload or download makes no progress for a minute; a stream that is quiet between writes is not affected. It drops request header names that contain a dot or an underscore. Nothing to do on upgrade: the edge keeps its certificate and ACME account.
  • The backend image now runs the control plane as one compiled module instead of Python source. Its templates and migrations stay plain files. The API schema no longer carries operation and model descriptions, fleetview-jobs --help and fleetview-provision --help no longer print their description paragraph, and the response schema sent to your model for Skills names and Benchmarks labels no longer carries a description.
  • The backend image no longer carries the demo seed scripts; fleetview-seed-demo copies them in from a directory you name.
  • A team's model endpoint must now be plain ASCII with no spaces or control characters, and its host may not have an empty label (a..b). A host written with a non-ASCII dot or a trailing space could otherwise name an address on this host's own network. An internationalised name still works in its xn-- form.

Requires of you

  • Operators: python -m fleetview_backend.jobs and python -m fleetview_backend.provision no longer run in the backend image. Use fleetview-jobs and fleetview-provision, as the 0.10.0 notice asked.
  • Operators: fleetview-seed-demo now needs --seed-files <dir>, a directory holding the six demo seed scripts of the deployed release, owned by root and writable by no one else.
  • Members: on macOS, nothing to reinstall or sign in again. On Linux, this is the first release whose installer runs there: install with the one-line command and run winner login. winner update replaces a release binary downloaded by hand as it does an installed one, but leaves a winner built from source alone, updating only agentsview, unless --force is given.

0.10.0 - 2026-10-08

Added

  • Benchmarks now measures and prices tasks from agents that record only session-level token totals, such as Windsurf, VS Code Copilot, Roo Code, Zed and Goose, when a session holds a single prompt. Claude Code and Codex are measured as before.
  • The Benchmarks page now says which of a team's agents it cannot measure (Cursor, Kiro CLI and Aider record no model) and no longer lists their tasks as untested opportunities.
  • Enrolled macOS laptops report each session's start commit and branch to their control plane, the commit read from the reflog without touching the repository. A session with no commit reports the reason instead, such as a folder that is gone or is not a repository. The folder's path never leaves the laptop.
  • On macOS, winner login asks once whether winner may read Desktop and Documents when recent sessions ran there, after saying what it reads (the git reflog, nothing else). Allow lets the hourly reporter record start commits for those sessions; Don't Allow leaves them without one. Laptops with no session in either folder are asked nothing.
  • winner login on macOS installs a daily winner update, so an enrolled laptop converges to its control plane's versions after a release without anyone running it; --no-service skips it.
  • A configuration reference lists every variable in .env.example and the host's monitoring file with its meaning, default, whether it is required and which layers can set it.
  • A manager sets on Settings how similar two prompts must be for Skills to group them, and how many prompts and sessions a workflow needs before it is shown. A change regroups on the next sweep, and the new groups are named within the naming budget over the sweeps after; skills already generated stay as they are, and a team that sets nothing sees the same workflows as before.
  • A generated skill draft now lists, above Approve, each tool, command, service or domain it names that the prompts it came from never mention, so a manager can check it before approving. The lint result now says it checks the file's structure, not what the skill says.
  • Each release now publishes static winner binaries for Linux on amd64 and arm64 beside the macOS one, listed in SHA256SUMS, and every control plane serves them for download without sign-in. The installer and winner update do not use them yet.
  • The documentation has a page on pointing Winner AI at a hosted OpenAI-compatible model, checking it with the coaching eval before Prompt Coaching is switched on, and whether the stack sends telemetry (docs/model-and-telemetry.md).
  • The same page lists, call by call, everything Prompt Coaching, Skills and Benchmarks send to the model, and says what happens to a session agentsview flagged as holding a secret. A test per call holds the list to what the code sends.
  • Prompt Coaching's Omit / Mark as wrong preview is now a real Disagree control: a manager marks a finding's category wrong or the prompt fine, the finding stops counting in that person's findings and figures at once and in their points to improve after the next sweep, stays listed under its category as a closed card marked Disputed, and is kept to measure the next rubric change. "Main points to improve" names the rubric version the findings were judged under.
  • The documentation has a troubleshooting page that maps what an operator sees to its likely cause, the command that confirms it and the section that fixes it. The configuration reference now also lists every team setting on Settings, with its release default and who can change it, and the winner client's options.
  • fleetview-watch reports a problem when the certificate served on 443 or on 5432 has fewer than CERT_MIN_DAYS (14 by default, set in the host's monitoring file) days left. Let's Encrypt no longer e-mails before a certificate expires, so this is the warning that renewal has stopped.
  • Every deployment serves the documentation at /guide/ to whoever signs in to the web app, with its fonts and assets included, so reading it sends nothing to another site; the sidebar links to it. Each release also carries the same pages as one PDF, winner-ai-docs-<version>.pdf.

Changed

  • The jobs and provisioning commands now start as fleetview-jobs and fleetview-provision, for example docker compose exec -T jobs uv run --no-dev fleetview-jobs rekey or docker compose exec -T backend uv run --no-dev fleetview-provision audit. The jobs service, the deploy's audit step, the demo seed's sweep, the docs and every printed hint use them. The python -m forms still work on this release (see Requires of you).
  • Re-running fleetview-seed-demo on a deployment already seeded, or make seed-demo locally, is expected to take minutes rather than hours. Each demo session's words and token counts now come from its own id, so only its timestamps move between runs; the deployment seed keeps each persona's vectors.db and prompt digests beside its sessions.db under /var/lib/fleetview-seed-demo, so an unchanged message is neither embedded nor judged again; kept Coaching verdicts move to their sessions' new start times; and the live personas push once more at the end, so Home's Active sessions reads above zero straight after the run. The first run after upgrading is the exception (see Requires of you).
  • Prompt Coaching reaches the prompt feedback sooner. The band keeps its four figures and moves each one's sentence into "How to read these numbers", above that figure's explanation; "Main points to improve" is now a closed toggle under it that shows how many points there are; and each finding shows its first five cards, with the rest behind "Show N more".
  • Each Benchmarks row now says whether a cheaper model can be tested on it now and, if not, why. "Can be tested now" means the row has a benchmark task to run; a prompt that carries everything it needs but is not a task reads "Cannot be tested" and says so. A prompt a person types, with no task to run, reads "Cannot be tested": typed work waits for a team to opt its repository in, which is not available yet, and the row adds what its latest example's laptop reported about its start commit. The "could be tested" count and the Testable filter now count only rows with something to run, so both can be smaller than before. A pattern whose benchmark task no longer qualifies no longer offers a Run benchmark button that the click would refuse.
  • Prompt Coaching no longer shows, for a newly judged prompt, a suggested rewrite that adds a number, file path or code name the original prompt never mentioned; the card says there is no rewrite to show instead, and its findings stay. The upgrade judges the coaching window again (see the last line of Changed), so every rewrite shown has been through the check.
  • Home's heading is now the single line "Attention and live state."; the muted second line "Risk first, then current activity." is gone.
  • The sidebar now opens with a larger Winner AI wordmark alone. The team name and organisation id that sat under it on every page are gone from the sidebar; Settings shows both.
  • A nightly backup whose restore test fails now keeps its dump as fleetview-<stamp>.sql.gz.failed instead of under the good name, so choosing a dump from /var/backups/fleetview, or anything that globs fleetview-*.sql.gz there, can no longer take it for a backup (the off-box copy only ever took a passing run's dump). A dump is never deleted on a failure, and failed dumps are pruned on the same KEEP_DAYS window as good ones.
  • The restore procedure now stops the deploy, watch and backup timers for the length of a restore, keeps laptops out by taking Postgres off TCP until the restored data is verified, checks the row counts before the stack comes back up, and takes login away from any device revoked after the dump was taken.
  • The "Subagents on a cheaper model" and "Context re-read above the budget" lines under Could be saved now say when their figure was last computed. If the job behind them has not refreshed one for over a day, that line is marked Stale and left out of the Could be saved total on Benchmarks and Home, and it counts again as soon as the next sweep refreshes it.
  • The Skills page opens on the candidates and the selected skill: the demo simulation panel moved to the bottom of the page. The candidates and library lists now scroll inside their own box, sized to the window, and a list reopens on the row just chosen.
  • Leaving flagged sessions out (see Security) measures Prompt Coaching and Benchmarks again. After upgrading, the next sweeps judge the coaching window again once; replay every benchmark task again on every candidate Route, under the daily limit, and judge each replay; and rename typed patterns, twenty per sweep. Until its replays return, a task that showed Tested and a proven saving on Benchmarks and Home shows its estimate again. A Skills workflow found again keeps its name.

Fixed

  • The backend and jobs containers no longer contact the Python package index when they start, so they start on a host with no outbound internet access instead of exiting.
  • Coaching's "Your prompt" and the prompts it judges, and the Skills evidence and candidates mined from them, now hold only what a person typed. Text an agent wraps around a prompt (Codex approval reviews and their agent history, stop-gate task blocks, image attachments, subagent hand-backs, messages from other sessions, command templates, the Codex app's in-app browser context and heartbeat block) is cut, and a prompt that is nothing but that text, or opens with a hook, command or task block, is skipped, as are the Codex app's scheduled automation runs that open with its Automation: header. Coaching re-judges the last 30 days under the daily budget, so its findings thin out until the sweeps catch up. The Benchmarks pattern inventory shows text from a prompt only when it opens with a marker an agent or tool writes, and then only that opening (see the Benchmarks lines below): the stricter rules can mistake a person's words for an agent's, and there that would show those words to managers.
  • The installer now installs the agentsview version your control plane runs, verified against upstream's checksums and placed next to winner without sudo, instead of upstream's latest release, which winner login then refused for running ahead of the control plane. Where it cannot learn that version (the control plane reports none, is reached over plain http to a host that is not loopback, or a mirror install names no FLEETVIEW_CONTROL_URL) it now fails after installing winner and names the release page, instead of installing the latest.
  • A laptop the roster has only just started tracking no longer reads Stale from an old embeddings heartbeat when it pushed a session change in the last day; it reads Pushing, on the roster and on Home, for the first day.
  • A roster row no longer shows a session time that belongs to another row. When two rows claim one hostname, only the row the name counts for reads it, on the roster and in Home's status, so a revoked laptop no longer shows its replacement's fresh "last change" beside its Revoked pill.
  • The Skills demo's Install button now reports itself disabled to assistive tech once it starts, instead of announcing "Delivered" as a button that can still be pressed; keyboard focus stays on it, and a reload still resets it to Install.
  • Adding a member whose address already has an Auth0 user no longer fails with a server error. Admin adds that user to the organisation with the chosen role and no temporary password, and they sign in with their existing login or reset it. The add is refused, with nothing changed in Auth0, when the address or its Auth0 user is already on another organisation's roster on the same deployment, or the user is an Auth0 member of another organisation provisioned there. It is also refused when Auth0 has not verified the address and the user was not created by this control plane, is not in the organisation and is not on its roster, so a login someone registered for an address they do not hold never receives the organisation's role. Any other Auth0 failure is shown on the page.
  • Benchmarks no longer marks a pattern whose runs read files as testable: it reads "Cannot be tested" and is left out of the band's "could be" count and the Testable filter. A pattern with a runnable task under its signature reads "Can be tested now" whatever its other runs needed.
  • Skills candidates no longer count prompts from background runs, subagent sessions, sidechains or automation, nor agent replies stored beside a Codex prompt, so a workflow's prompt and session counts and its evidence are what people typed, as on Coaching. On the next sweep a candidate whose prompts no longer form a workflow is dropped, while one found again keeps its name and is refreshed with the new counts and evidence, as is the candidate behind a generated skill; dismissed candidates are left as they are.
  • Benchmarks no longer describes the review prompts Claude Code composes for Codex as typed by a person: it reads who wrote a prompt from its text as Coaching and Skills do, and shows no text for those prompts, only a name. A prompt with no words, such as a lone screenshot, stays a person's. Slash commands, shell output and the agent's own interruption and continuation text are no longer called hooks. Pattern rows are rebuilt and the new ones named over the next sweeps.
  • Benchmarks no longer shows words a person typed after a command, shell or reminder opening: a slash command's arguments, a command run in Claude Code's shell mode, and text typed after a reminder or task block are cut from the prompt shown, and a shell command's pattern shows a generated name instead while still being described as a shell command. The model that names a pattern is sent no more of such a prompt than the page shows, so a shell command or a slash command's arguments never reach it. A prompt whose opening block is never closed, or holds a shell command or a slash command's arguments, shows no text and is not sent. Pattern rows are rebuilt and named again over the next sweeps.
  • A jobs heartbeat URL (FLEETVIEW_HEARTBEAT_URL) that is plain http to anything but the stack's own hosts no longer stops the jobs sweep: the jobs service logs a warning and never pings it.
  • The Benchmarks passes no longer stall the jobs sweep on a team with long sessions of many prompts. Finding which prompt each reply answers took time that grew with the square of a session's length, tens of minutes on a large team, and held up Benchmarks and every pass after it; it now takes seconds. What the passes store is unchanged, and nothing needs doing on upgrade.
  • The Benchmarks passes no longer stall on one very long prompt. Grouping a prompt read all of it to keep its first 100 characters, and a long run of dotted or hyphenated words with no spaces took time that grew with the square of its length, 45 seconds for 160 KB; only the start of a prompt is read now. Which prompts group together is unchanged.
  • A Benchmarks replay that timed out, or came back from the provider in a form that could not be read, now counts against the daily run limit. It had been treated as costing nothing, although the provider may have billed it. A replay the provider refused or never received still takes no slot.
  • winner push status used to quote the oldest end of a progress line, so a long push read "1% … 10%" and dropped the current figure; it now quotes the latest redraw. A log that ended in a bare erase-line used to be quoted as nothing, and now quotes the readable line above it. winner push uninstall, and winner push stop on macOS, now pass what launchctl and systemctl printed through the same sanitiser before echoing it; on Linux a stop echoes nothing, because systemctl writes to the terminal itself.
  • winner push status used to say "running" while every push was failing, because the reasons land in agentsview's own pg-watch.log, which it did not read; it now reads that file too. While the push is running and the last two or more pushes failed with none succeeding since, its first line reads "running (pid N), but the last N pushes failed:" with the newest reason, the "(pid N)" left out only when the service manager reports no pid, and its next line says when that failure was. A keyword-form password= is now masked too, in the quoted last line of every reading and in what winner push stop and uninstall echo through the sanitiser above; nothing else in the other readings changed, and winner push logs still prints the service's log as it is.
  • Revoking a laptop no longer drops a column, a default or a whole shared table that leaned on a sequence, type or table that laptop created: those are now handed over first, tables and sequences to the team's device group and types to the schema's owner. What still has to go is named in the backend's log when it can be found.
  • Off macOS (Linux included), winner login no longer tells a laptop whose agentsview is behind or ahead of the control plane to run winner update, which installs macOS builds only and refuses there. It links upstream's release page for the control plane's agentsview version instead, and winner update no longer tells such a laptop missing agentsview to rerun it.
  • The reload database password logs in through psql and libpq again when it holds some non-ASCII text (a zero-width space, a character SASLprep prohibits, some right-to-left text). Since 0.9.0 the control plane prepared such a password differently from libpq, so the role refused it. The next backend start sets it again.
  • The subagent and context lines of Benchmarks' "Could be saved", Prompt Coaching's Model fit estimates and its "Could be saved" band now date each figure by every price row it was priced from, as a range when they differ, instead of by the newest of those rows. A Benchmarks line stored before the upgrade keeps its one date until the next sweep reprices it; a Model fit estimate is priced once, when its session is judged, so one judged before the upgrade keeps its one date.
  • Benchmarks no longer offers Run benchmark where the click would be refused or the run silently skipped. When the team's model key cannot be read with this host's settings keys, the page says so and offers no Run; when the host does not lend its local model, the local Routes say so on their card, and a run asked for on one is refused instead of queued. A Route the page will not run reads Cannot be benchmarked, with the reason, instead of Ready to benchmark. When the team has used its daily run limit, each Route card says so and offers no Run, and the row reads "Cannot be tested" with that reason, until a slot frees.
  • A Skills workflow's summary no longer opens by calling the engineer "He" or "She": it says "The engineer". The upgrade rewrites the summaries already stored the same way.
  • A feature the host enables after a team saved Settings' Features row now runs for that team. The team's saved value used to list what it left on, so a feature added later stayed off for it; the row now records what the team switched off, and the upgrade converts every saved row. One choice cannot be recovered: a feature a team switched off that the host no longer enables at the upgrade comes back on if the host enables it again.
  • Settings' Frontier model families list offers gpt-5.6 as the release list spells it, with its session count, instead of a bare gpt that would mark every GPT model frontier. Each family counts a session once, where a session on two models one entry covers used to count twice.
  • Settings' Routes editor answers a JSON client's Add row or Remove row with a 422 JSON error telling it to post op=save, instead of the HTML page; nothing is saved. Browsers are unchanged.
  • winner update no longer tells a Mac still on agentsview's own push service that it was enrolled with --no-service, and no longer leaves that service running the agentsview it just replaced. On a Mac, every update that is not --check now replaces it with Winner AI's, as winner login does, though a Winner AI push stopped with winner push stop stays stopped; the update that installs this release still runs the old code, so the one after it does the replacing. The --no-service line appears only when neither service is installed. winner push status names agentsview's own service while it is there, and the command that replaces it: winner update on a Mac, winner login on Linux.

Security

  • The hourly reporter no longer runs git. It works out where a session's repository really is and reads the repository's reflog file itself, so a link, a .git file naming another repository, a repository's settings, or anything inherited from whatever started the job can no longer make it report another repository's commit, or, on macOS, read a repository in a folder you did not allow. A Mac without the developer tools now gets start commits too, and no git version is needed on any system. Sessions inside a git submodule, and in a repository that uses git's reftable format or has a link in place of its .git or its reflog, are recorded without a start commit.
  • A failed organisation bootstrap can no longer write the organisation's database owner password to the log or into the error it reports.
  • The control plane's cross-team reads (Home, Coaching, Skills, Benchmarks, the roster's session counts and attribution) now log in as their own read-only Postgres role instead of borrowing the superuser's connection, so nothing a read runs can climb back to the superuser. A read refuses a team schema holding a view, a materialized view, a foreign table or a row-level-security policy (switching row-level security on without one is not refused), and every start and deploy reports any function, view, operator, trigger, rule or policy there that stock agentsview does not create.
  • Enrolled laptops no longer send agentsview's anonymous usage ping or ask GitHub for a newer agentsview, matching the server: every service winner login installs switches both off, and the agentsview config enrollment writes switches off the update check, the one of the two it has a setting for. Any laptop gets this at its next winner login. A Mac whose push is running also gets it from winner update, but only from the update after the one that installs this release, and that update rewrites only the push service; the reporter and update timer, which never start the agentsview daemon, wait for the next login. docs/install.md, "What a laptop contacts", lists everything a laptop still reaches.
  • A laptop's database role could create a function, view, trigger or policy in its own team's schema during the moment the backend re-installed its guard at start, and could alter a routine it could not otherwise alter. Both are closed: the guard is now replaced in one step, and it refuses the two ways of altering a routine it used to miss.
  • An enrolled laptop's database role could take the locks the control plane takes turns on, and so stop it upgrading every team's database at start, or hang enrollment and hostname reports for a name, for as long as it stayed connected. Those locks now sit on tables a laptop's role cannot touch. A hostname claim still waiting on another enrollment of the same name after five seconds now fails with a message to try again, instead of waiting indefinitely.
  • A laptop's database role could hand its team's search tables to another team's role or to everyone, which let that role read sampled text from them, could connect to the server's postgres and template1 databases, and could pass data to a cooperating laptop of another team through a large object. A laptop's role can no longer grant its tables or set default privileges, and grants that already exist are revoked at every start and logged (the first twenty in a team's schema by name, the rest as a count), or reported where a start cannot remove them; every start also closes those two databases to laptops and takes large objects away from them, and a deploy fails if any of this is still open. A laptop can still move its group's tables to the group every team's laptops share by reassigning their ownership: a deploy now fails on that too, and it is not yet prevented.
  • On a deployment running the production overlay, a client with a private source address (a VPC peer, a VPN user, a host on the same LAN) could reach Postgres's password prompt as any role, the superuser included, with or without TLS. Roles other than a laptop's are now admitted only from the stack's own network, on a subnet the overlay pins. Every other address, private or public, gets a laptop's role over TLS and nothing else, refused before a password is read. A deploy loads this release's access rules into the database and fails if they do not take (see Requires of you).
  • A page on a neighbouring address of the deployment's own site (another subdomain, say), open in a signed-in manager's browser, could star, rename or trash that team's sessions in the dashboard. The dashboard now refuses any change that does not come from its own pages.
  • A session agentsview flagged as holding a secret is not sent to the model by Prompt Coaching, Skills or Benchmarks while it is flagged, whatever the finding's confidence, and neither are results already made from it. A skill candidate or draft with an example from such a session leaves the Skills page and cannot be generated; an approved skill stays. A benchmark run from such a session is not shown or counted toward the proven saving. A session whose findings are removed from agentsview's table is sent again; docs/model-and-telemetry.md says what the rule does not do.
  • An address nobody verified and the control plane did not create can no longer sign in to a team, in the browser or with winner login. The browser sign-in is refused; winner login prints the reason, to verify the address. The tokens never carry a role or an organisation. People a manager adds through Admin sign in as before.
  • A failed model call could leave part of a member's prompt, or of the model's answer about it, in the jobs log and in the error stored for the run. A failure is now recorded by its HTTP status or kind, the model, the shape asked for and the number of tries, and a failed write to the control database no longer prints the values it was writing. The provider's own explanation is no longer in the log: to read it, send a minimal request with the same model and response_format using curl.
  • Text a member typed, or that the model wrote from it, could pose as instructions in a later model call inside the same team. A prompt could close the marker around it or open a new one; a workflow's name and summary went to Skills' Generate outside any marker; an agent or model name a laptop reported could forge a line of the coaching judge's request; and one judge call mixed several members' prompts. Now such text cannot hold a marker as the requests write it, nor one spelled with the lookalike characters Winner AI lists (the list is not every glyph a model might read as a bracket); the name, summary and scope are sent as data; those names and the team's own Routes and model families are reduced to plain names; a workflow or pattern name must be one short line or it is not stored; and one judge call holds the prompts attributed to one member. Whether a model obeys text inside a marker was not tested.
  • On a deployment running the production overlay, a request that carried its own X-Forwarded-Uri header naming a public path, such as /health, was let past sign-in to the path it really asked for. That reached only pages that check no identity of their own: the build version (/internal/version) and the API schema and its viewers (/openapi.json, /docs, /redoc). Manager pages, the admin API and the dashboard still answered 401, and no session or customer data was readable. The edge now removes that header and writes X-Forwarded-Proto and X-Forwarded-Host itself on every request, so the sign-in proxy believes no forwarded header a client or a CDN's client sent. The localhost stack was never affected, and OAUTH2_PROXY_REVERSE_PROXY is no longer a setting: only the production overlay switches that mode on.
  • A skill draft nobody approved could be downloaded. Download and the install text now exist only for an approved version; a draft above an approved version no longer replaces the file the page hands out.
  • Benchmarks could call a run the same answer on the judge's score alone when the original reply had no decision (ALLOW or BLOCK and the like) to check the run against. Such a run is still scored and is now always a different answer, and its card says there was no structured check to confirm the answers match. Runs already stored that way are corrected by the upgrade, with no model call.
  • The installer and winner update install winner only when the release's SHA256SUMS carries a valid signature by the Winner AI release key, so a control plane or mirror that swaps in a binary we did not release, with a checksum to match, is refused. The signature does not say which release: a control plane can still serve an older signed one. The installer checks it with the ssh-keygen macOS already ships; agentsview keeps upstream's own checksum, and a digest you supply with FLEETVIEW_AGENT_SHA256 skips the signature. A laptop's first update to this release is still checked by checksum alone.

Requires of you

  • Operators: OAUTH2_PROXY_REVERSE_PROXY in .env is no longer read. If you had set it to true on a stack without the production overlay, run the production overlay instead: it switches the mode on behind an edge that cleans the headers the mode believes. A deployment already on the overlay needs nothing but this release.
  • Operators: redeploy the post-login Action from this release to each tenant (docs/onboarding.md, "The post-login Action" has the commands and one to compare the deployed copy). Before you do, mark verified only the accounts you created yourself and know, such as the localhost placeholders. A demo user an earlier seed run left unverified is deleted and seeded again, and marked only if you kept your own record of the Auth0 user id that run created. Do not mark any other unverified account, and never one that someone signed up with: it either proves its address with the verification email or is deleted. The query on that page lists who the Action will refuse, not who to mark.
  • Operators: on a hosted model endpoint this update spends model calls once: the coaching window is judged again, and every benchmark task is replayed and judged again under the daily limit (see Changed).
  • Operators: a Prompt Coaching judge call now holds one member's prompts, ten at most, or one session's when the session is not yet attributed to anyone, where it used to hold any ten prompts, so a team with several members can take more calls. A sweep stops at twice the calls its daily budget would take in full batches (60 at the default budget of 300) and the next sweep continues; over a day the budget still bounds the prompts judged. This change adds no benchmark re-judging.
  • Operators: a deploy now fails when a team schema holds code stock agentsview does not create, most likely planted by a laptop before 0.6.0. docs/troubleshooting.md, "Code in an org schema that agentsview did not create", says how to find and clear it.
  • Operators: the postgres and template1 databases now admit only a superuser, or a role you have granted CONNECT there by name (GRANT CONNECT ON DATABASE postgres TO <role>). A grant to everyone does not last: the next start revokes it. The application database is unchanged.
  • Operators: PUBLIC_BASE_URL must be the bare address a browser shows, such as https://devtool.example.com: lower case, no trailing slash, no path and no default port. make up or a deploy now refuses any other spelling, because the dashboard would refuse every star and rename under it.
  • Operators: if you seed a demo org with fleetview-seed-demo, the first run after upgrading is as slow as a first seed (about 3.5 hours on a CPU-only host), and Coaching re-judges the whole demo org over the following sweeps, up to its daily budget (see Changed).
  • Operators: the production overlay now pins the compose subnet, and the first deploy of this release takes the whole stack down once to move its network there. The host's own networks, VPC and routes must not use that subnet. The deploy fails with the stack left up while a fleetview-seed-demo run holds the network; the timer's next run is the retry. A fleetview-postgres jail set up before this release still ignores every private range: narrow its ignoreip to the pinned subnet once that deploy has run (docs/network.md, "The Postgres jail").
  • Operators: a dump taken before this release kept the name fleetview-<stamp>.sql.gz even when its restore test failed. Before restoring one, confirm its stamp's restore test PASS line in journalctl -t fleetview-backup; from this release a failed dump is named .failed (see Changed).
  • Operators: move any script or note of your own that starts python -m fleetview_backend.jobs or python -m fleetview_backend.provision to fleetview-jobs or fleetview-provision (see Changed). Both old forms still work on this release and stop once the backend ships compiled.
  • Operators: this release migrates the control database at its first backend start, with nothing to run by hand. A rollback to 0.9.0 after that is not code-only: take a sudo fleetview-backup before you deploy and expect to restore it if you roll back.
  • Operators: a mirror you point FLEETVIEW_AGENT_URL at must publish the release's SHA256SUMS.sig beside SHA256SUMS, unchanged, or the installer refuses it. A release built by hand needs the release key holder to sign SHA256SUMS before it is published. Rolling the control plane back past this release, or serving a bundle with no SHA256SUMS.sig, makes every winner update on a laptop already on this release fail on winner until you roll forward; agentsview still updates.
  • Members: nothing to reinstall or sign in again. On macOS, winner update brings the winner push fixes above; on Linux, this release's winner-linux-amd64 or winner-linux-arm64, placed by hand, brings them and the winner login fix. agentsview's usage ping and update check go off at the next winner login; a Mac whose push is running gets that from winner update too, from the update after the one that installs this release, and one whose push is stopped only from the login.

0.9.0 - 2026-09-25

Added

  • Every enrolled laptop now reports a push heartbeat, whether or not it has run agentsview embeddings build: the jobs sweep watches the marker row each push rewrites. A laptop seen pushing since the upgrade whose push service then dies turns Stale on the roster within a day instead of reading like a quiet week.

Changed

  • The roster and Home show "Liveness unknown" where they showed "Quiet", and on Home a member none of whose devices has ever pushed reads "Never pushed" instead of "Enrolled".
  • On a wide monitor Settings now widens with every other page instead of stopping at 1180px, and the "Why" on a Prompt Coaching finding keeps a comfortable line length. Nothing changes below 1600px.
  • The wide-screen step shipped in 0.5.1 without a note here: from 1600px the page column and the type grow, and from 2400px the column keeps widening on its own, so tables and grids take the room that used to sit in the margins. Prose keeps its line length, so a wider screen buys more columns and wider tables and never a longer line. The step follows the reader's own browser font size and zoom.

Fixed

  • A failed role statement no longer writes a database password into the backend's log or Postgres's own: the control plane now sends Postgres the password's SCRAM verifier, never the password. Existing roles keep working and pick up a verifier the next time their password is set.
  • The jobs log no longer calls a pass skipped when it did its model-free work without a model (the benchmark queue drain, the coaching owner back-fill, the Skills stale-candidate cleanup): it now says the pass ran without a model. The per-sweep line now reads N passes had no model to call instead of N passes skipped for no model; update any log search that matched the old text. A run's recorded settings now name only the settings that run read.
  • A benchmark run requested while the organisation's stored team key can no longer be unsealed is refused on the click with the reason, instead of being queued and then dropped by the next sweep without a word.
  • winner login now points at winner update against a control plane that publishes no winner version too (every deployment before 0.5.0, and any untagged build). That run converges agentsview and leaves the winner binary alone; the message used to send the developer to a manual agentsview install instead.
  • Benchmarks dates each money figure by the price rows it actually read, as a range when they differ, instead of by the newest row in the price table. Its notes now also say an "up to" estimate appears on patterns marked "Cannot be tested", so the estimate is never read as a sign the pattern is testable.
  • A benchmark replay that fails no longer uses up the day's replay limit: only replays that answered or were cut at the token cap count against it, so one provider error no longer stops benchmarking until the next day.
  • Benchmarks' pattern costs and "Could be saved", and Prompt Coaching's cheaper-Route estimate, no longer count one Claude reply several times. A long reply is stored in several parts that each repeat its input, so these figures read several times too high for Claude sessions; each reply is now priced once, so Home's "Could be saved" tile and its yearly figure go down with them. The next sweep measures every recurring pattern again, so after upgrading each pattern is renamed once and its benchmark runs start over. Prompt Coaching keeps the estimate it already showed for a session it judged before the upgrade; only sessions judged after it get the corrected figure.
  • Every laptop on a team replicates vectors into a new embedding generation, not only the one that started it, and the dashboard's semantic search can read them. Revoking that laptop no longer deletes the team's vectors for the generation. A backend restart repairs laptops enrolled earlier; nothing needs re-enrolling.
  • The benchmark sweep's log no longer calls a pair "already replayed" when it is only waiting out the 24 hours after a failed attempt; it now says it is waiting.
  • A skill Winner AI writes from a candidate on Skills is written from the candidate's different prompts. When one teammate repeated a prompt word for word, the model could be shown that one prompt ten times and none of the variations; each prompt now reaches it once, nearest the cluster's centre first. A candidate whose cluster forms again takes the new order on the next sweep, and its Evidence list then opens on different prompts too.
  • winner update no longer stops both binaries when one sits in a directory this user cannot write: it updates the other, then exits non-zero naming the one it skipped and why. A failed agentsview download or install likewise no longer stops winner from updating. --force now also reinstalls an agentsview whose version cannot be read, and an agentsview release archive that opens with a pax global header no longer fails the update. winner login against a different control plane than the one recorded on the laptop says it replaced the record and prints the command that goes back.
  • Home, Benchmarks and Prompt Coaching no longer take 10 to 20 seconds to open, and their spend figures no longer read "unavailable", for a team with a large month of usage. Winner AI now reads spend from the dashboard every ten minutes in the background and the pages show the stored figure; Home says when it was read ("last 30 days, as of 14:05"). After an upgrade the figures appear within a few minutes of the control plane starting.
  • Sessions a laptop pushes late (its history on first enrollment, or a backlog after days offline) are now attributed to their person. Upgrading re-scans each team's sessions once to recover the ones missed before.

Requires of you

  • Operators upgrading a running deployment: the upgrade clears every team's attribution cursor once so the next ticks re-scan. If the old backend was still attributing while the migration ran, it can write its old cursor back and that team's re-scan never happens. If a team's older sessions still show no owner after the upgrade, run this once against the control database; sessions that already have an owner are skipped:
UPDATE control.orgs SET attribution_watermark = NULL,
  attribution_watermark_id = '', attribution_scan = NULL,
  attribution_scan_id = NULL;
  • Members: nothing to reinstall or sign in again. On macOS, winner update brings the winner update and winner login fixes above; it installs macOS builds only.

0.8.0 - 2026-09-25

Added

  • Home's "Could be saved" tile now says what its monthly figure comes to over a year ("about $847K a year"), for teams that budget annually.

Changed

  • fleetview-seed-demo seeds a 30-person team spending about $300k a month in place of the five-person one. The five keep their names, so a re-seed refreshes their sessions rather than adding to them. A fresh seed takes most of an hour, most of it spent building embeddings.

Fixed

  • The nightly backup's restore test no longer fails at random with "the scratch Postgres never became ready". It waited on the scratch server's first-start init phase; it now waits for the real server.

Requires of you

  • Operators who seed a demo org: the 30 demo accounts must exist in the Auth0 tenant as members of that org before fleetview-seed-demo runs; it creates no account. Run make seed-demo once against the same tenant to create them.

  • Members: nothing.

0.7.1 - 2026-09-24

Fixed

  • fleetview-seed-demo now embeds every persona on a host whose Ollama runs on CPU. It had timed out and pushed without vectors, leaving Skills on stale prompts.

Requires of you

  • Members: nothing.

0.7.0 - 2026-09-24

Added

  • Benchmarks and Home's "Could be saved" now include context re-read above a per-turn budget: what long sessions pay to re-read their conversation past 150,000 tokens a turn, labelled as an estimate with its pricing date and linked to Prompt Coaching's Context findings. The budget is a team setting on the Settings page.
  • Operators can seed or refresh a deployment's demo organisation from its host with fleetview-seed-demo --org <id>: five demo members with a month of sessions, pushed the way a laptop pushes, after a verified backup. It needs the demo accounts to exist in the deployment's Auth0 tenant already.

Requires of you

  • Members: nothing.

0.6.0 - 2026-09-24

Added

  • Benchmarks' "Could be saved" block now lists its figure by saving lever, starting with recurring patterns.
  • Benchmarks and Home's "Could be saved" now include subagents that could run on a cheaper model, labelled as an estimate with its pricing date.

Fixed

  • Vectors replicate again after a migration pass. Before, the pass handed the embedding generation's chunk table to the org's owner, and every laptop's push then skipped vectors, so Skills and semantic search stopped seeing new prompts.

Security

  • A laptop's Postgres role can no longer switch to its team's shared device role to get around the rule that stops it creating functions, triggers and other code objects. The same rule now also refuses aggregates, views and row-level-security policies, so a laptop cannot put code in the path of the control plane's cross-team reads.

Requires of you

  • Managers whose Skills stopped growing: click Migrate on Admin once after upgrading. That hands the chunk table back to the laptops, and their next push replicates the vectors they missed.

  • Members: nothing. Once a manager has clicked Migrate, each laptop's next push replicates the vectors it missed.

0.5.1 - 2026-09-22

Added

  • The edge serves Postgres under its own hostname when one is set (PUBLIC_PG_HOST), and obtains and installs a certificate for it, so a deployment whose web hostname sits behind a CDN can still let laptops reach Postgres by a name the CDN does not front. With it unset the edge serves one name, as before.
  • Behind a CDN the edge can record the visitor's address rather than the CDN's: when the peer is in EDGE_TRUSTED_PROXIES, the edge takes the client address from that peer's Cf-Connecting-Ip header; from any other peer the header is ignored and the peer address stands. Access logs carry both. What the edge forwards onward is the one address it resolved, never the inbound X-Forwarded-For list.

  • winner login on Linux installs Winner AI's own background push, a systemd user unit, the way it already does on macOS, and winner push status|logs|stop|start|uninstall drive it. A Linux laptop enrolled before this pushed nothing until someone ran agentsview's installer by hand; the next winner login replaces that service with ours. A machine reached only over SSH needs loginctl enable-linger for the push to start at boot.

  • Every Benchmarks row without a tested saving shows an "up to" estimate: its own tokens priced again at the cheapest candidate model the team's settings map it to. The "Could be saved" tile shows it too, never added to a tested saving.

Fixed

  • On a deployment that does not lend its model, a queued benchmark run is now answered with the reason it could not be replayed instead of waiting forever, Skills stops listing workflows the team no longer repeats and keeps each kept candidate's counts current, and coaching rows are still credited to the teammate who ran the session.
  • A winner push status whose log ended in a progress redraw no longer overwrites the line printed above it: the one line it echoes has control characters stripped, while winner push logs still prints the file as it is.
  • When winner login finds a laptop's agentsview out of step with the control plane's, it now points at winner update, which moves the laptop to exactly the version the control plane runs. It used to suggest the upstream installer, which takes the laptop to the latest release instead and leaves every push failing.
  • The hourly hostname report no longer asks Auth0 to resolve the organisation: it reads it from the reporting member's own record, so a fleet of laptops no longer spends a Management API call each, every hour, against a rate-limited quota.
  • A benchmark that failed on a cheaper model, for example during a provider outage, is no longer blocked for good: the next day's sweep tries it again, a manager can retry it at once from Benchmarks, and the failed attempt stays on record.
  • A skill candidate on Skills reports the members it actually has. Its repeated prompts, distinct sessions, contributor count, last-seen date and Evidence used to stay at the values of the sweep that first stored it when a teammate repeated a prompt word for word; every sweep now rewrites them from what it found. A dismissed candidate keeps the numbers it was dismissed on.
  • winner push stop used to report success for every failed bootout; it now exits non-zero and shows launchctl's own message when the stop genuinely failed, rather than only when the push was already stopped. A stop systemd refused on Linux now says the push may still be running too.
  • A failed background-push install now says when it already removed agentsview's own push service, and how to restore it, instead of leaving the laptop with no pusher and no explanation.
  • A PATH that cleaned away to nothing no longer overrides launchd's own default with emptiness, which could leave the background push unable to resolve any binary at all.
  • Enrolling a laptop under a name another of your own laptops already answers to is refused, as it already was for another member's laptop: two laptops on one name leave every session under it unattributed. Rename the machine and run winner login again, or revoke the older device first.
  • Home's per-person session count no longer counts a name two of a member's laptops claim twice, so it agrees with that member's roster row.
  • scripts/check-env.sh refuses a PUBLIC_PG_HOST that is an IP address — in either notation, including an IPv4 address written as IPv6 — with the reason: no public CA will certify one, so verify-full could never accept it.

Requires of you

  • Operators behind a CDN: set PUBLIC_PG_HOST to a DNS-only name that resolves straight to the host and EDGE_TRUSTED_PROXIES to the CDN's ranges; leave both unset when nothing sits in front. Port 80 must stay reachable from the internet, not only through the CDN: the second certificate is challenged at the host directly (docs/network.md, "Behind a CDN").

  • Members: on macOS, nothing beyond the hostname case below; winner update brings the push fixes above. No Linux build is published, so a Linux laptop builds winner from this release and runs winner login once to get Winner AI's background push.

  • Members whose deployment changed its Postgres hostname: the DSN in config.toml still names the old host. Run winner login once and the laptop pushes to the new name; until then pushes fail with a TLS name mismatch.

0.5.0 - 2026-09-18

Added

  • winner update converges a laptop's winner and agentsview to the versions its control plane runs, in either direction, after checking each download against its published checksums. --check reports what would change without installing anything.
  • winner push status, logs, stop, start and uninstall manage the background push. On macOS, winner login now installs Winner AI's own launch agent, which runs the stock agentsview pg push --watch, in place of agentsview's service.
  • A laptop keeps its sessions when its hostname changes. On macOS, winner login installs an hourly reporter that tells the control plane every name the laptop has pushed under, and the roster, Home, spend, Coaching and Skills count every one of them. Re-enrolling a renamed laptop replaces its old device row instead of adding a second. --no-service skips the reporter as well as the push.
  • Settings lists every value the organisation runs with, what it does and which layer set it (the release, the operator or the team). A manager changes the team's values in place, Reset returns one to the operator or release value, and a manager can switch Coaching, Skills or Benchmarks off for the team within what the deployment enables.
  • A manager can give their organisation its own model endpoint, model and API key on Settings. The key is stored encrypted with the new FLEETVIEW_SETTINGS_KEYS and never shown again; FLEETVIEW_LLM_FALLBACK decides whether an organisation without a key uses the host's model or none, and with none, Coaching, Skills and Benchmarks say "No model configured". Both are optional: without them nothing changes.
  • The Prompt Coaching page lets a manager omit a finding or mark it as wrong, labelled a demo simulation; nothing is recorded and a reload resets it.
  • The roster links each person to the dashboard's Usage page filtered to their laptops, labelled with their name; a person with no device shows a named empty state instead.

Changed

  • The Benchmarks controls (daily runs and quality threshold) move from the Benchmarks page to Settings, and POST /benchmarks/controls is gone. Saved values carry over; daily runs are capped at 500.
  • winner login now records the control plane it used, so a later bare winner login or winner update on that laptop needs no flag.
  • The Prompt Coaching judge reads the team's frontier model families and Routes to try from Settings, and only recommends a route on the team's Routes to try. Each new verdict records the lists it was judged with; stored verdicts are not judged again.
  • Every headline figure reads the same on every page: Home's tiles, Admin's metrics and the Skills, Prompt Coaching and Benchmarks bands now share one type style, so the Benchmarks band's numbers are no longer set in the mono face. No figure's value changes.
  • Prompt Coaching and Skills refuse a FLEETVIEW_LLM_ENDPOINT that is plain http to anything but a compose-internal or local host, as Benchmarks already did. A host pointing it at plain http on another machine must move that endpoint to https before upgrading, or those passes fail every sweep.
  • The public /api/v1/agent/config also returns winner_version, the release the control plane runs, which winner update converges to.
  • "How to read these numbers" starts closed on Benchmarks and Coaching.

Requires of you

  • Members: a laptop installed before this release has no winner update, keeps agentsview's own push service and has no hostname reporter. Re-run the installer, then winner login, once; after that, run winner update to keep it current.
  • Operators: the hostname reporter authenticates with a refresh token, so the Auth0 API must allow offline access (and the native app the Refresh Token grant). Without it, winner login says the reporter was not installed, and a renamed laptop's sessions stay unattributed until its member runs winner login again. A host overlay that overrides OAUTH2_PROXY_SKIP_AUTH_ROUTES must add ^/api/v1/devices/report-names$. Check that FLEETVIEW_LLM_ENDPOINT is https or compose-internal before upgrading. The control plane migrates the control schema at startup; read the backend log after upgrading.

0.4.0 - 2026-09-16

Added

  • The control plane serves the installer and the winner binary itself, so a developer installs with one curl from their own deployment, with no GitHub access and a checksum check.
  • The installer records the control plane URL on the laptop, so winner login needs no flag there.
  • The Dashboard carries a "Back to Winner AI" control that returns to Home.
  • Benchmarks records every recurring prompt, with the reason one cannot be replayed kept beside it, and names the patterns people type.
  • The Skills page carries a labelled demo panel that simulates delivering a suggested skill to the team. Nothing is installed and nothing is recorded.
  • A documentation site built from this repository, with a local preview (make docs, make docs-serve) and a build that runs on every pull request.

Changed

  • winner login no longer falls back to a built-in control plane address: it takes --control-url, FLEETVIEW_CONTROL_URL or the installer's record, and exits non-zero naming all three when none is set. It refuses a control plane URL that is not https, unless it is localhost.
  • winner login refuses a laptop whose agentsview is newer than the server's, and the server re-migrates each organisation's schema after an agentsview bump, so a laptop that ran ahead no longer fails every push silently.
  • The Benchmarks page is a ranked table of prompt patterns, by cost, runs or time, and Run benchmark queues the run for the next sweep instead of holding the page.
  • The Prompt Coaching band explains each figure in plain English and marks which are estimates.
  • Values a team may tune are stored per organisation; the Benchmarks controls move there and behave as before.
  • With Management API credentials set, the control plane refuses to start when the Auth0 tenant lacks the manager or member role, naming the missing one.
  • Session attribution reads a bounded batch per tick, and FLEETVIEW_ATTRIBUTION_INTERVAL_SECONDS tunes it (0 turns it off).
  • The control schema is migrated automatically at startup.
  • The jobs service receives only the settings it reads, and every read of an organisation's data runs as the read-only control_miner role.

Fixed

  • Re-running winner login on the same laptop replaces its old device instead of counting the machine twice.
  • winner login no longer fails at random with "token is not yet valid (iat)".
  • On Windows and Linux, winner login no longer points at a push command that cannot run there.
  • Benchmark savings price each token type at its own rate, count one prompt at a time, show one row per prompt, and no longer clip the table.
  • A coaching Finding with no rewrite says so instead of showing "None".
  • The API reports the real version and the name Winner AI.
  • The installer's FLEETVIEW_AGENT_URL download works without a GitHub token.
  • The restore runbook stops every service holding the database and has the operator check the replay's errors and row counts before starting the stack.

Requires of you

  • Members: a laptop installed before this release has no recorded control plane, and winner login never records one itself. Each login needs --control-url or FLEETVIEW_CONTROL_URL until the installer is run again, which records it. A laptop whose agentsview is newer than the server's must install the server's version first.
  • Operators: a control plane served over plain http must move to https, because laptops refuse it anywhere but localhost. The Auth0 tenant must hold roles named manager and member before the control plane will start with Management API credentials set. The control plane migrates the organisation schemas and the control schema at startup. A failed migration is logged as startup provisioning failed; serving anyway and tried again at the next start, so read the backend log after upgrading. Benchmark figures are recomputed on the next sweep, so they will move.