Edit one, and it shows. Each release is checked against its text as first published (pinned from git on 2026-10-07). Corrections are shown, not hidden.
2026-08-31cd359a← genesis
2026-08-3129be73← cd359a
2026-08-3138e930← 29be73
2026-09-014e1fd9← 38e930
2026-09-014fa97a← 4e1fd9
2026-09-0142254c← 4fa97a
2026-09-0746b241← 42254c
2026-10-1793f9f3← 46b241
2026-10-19f38711← 93f9f3
8 of 9 match their pinned hash
2026.08.31 corrected 2026-09-07 It said the row-level-security migration was complete, on every query. It was not; /security always said it was partial.
2026-10-192026.10.19
/migrate/openai-evals previews an OpenAI Evals import in the browser before you sign up.
Paste an OpenAI Evals export, or load the labelled sample, and the same parser POST /api/datasets/import runs converts it in the tab: how many tests it keeps, which graders it cannot carry over, and which rows it leaves out and why. Nothing is sent. OpenAI Evals becomes read-only on 31 October 2026 and shuts down on 30 November 2026.
/app/datasets?import=openai-evals opens the import form directly.
seq 9 · f38711817f2b… ← 93f9f315bdfc…
2026-10-172026.10.17
Run ids beginning demo- or sample- are now refused at ingest: they are reserved for Runback's own sample runs.
POST /api/ingest and POST /api/otel/v1/traces return 400 with code "reserved_run_id" for a run id (or OTel trace id) beginning demo- or sample-, naming the prefix, and store nothing. Previously such a run was stored and then treated everywhere as one of Runback's sample runs — excluded from your evidence. Use your own prefix; see /docs#reserved-run-ids.
seq 8 · 93f9f315bdfc… ← 46b2415547d0…
2026-09-072026.09.07
Community edition published and tagged v0.1.0; replay and the audit ledger are free on every plan; database row-level security enforced.
The Community edition is public at github.com/letsRunback/runback-community, tagged v0.1.0, under Community Licence v2.0 — source-available: read, modify and redistribute, with one limit (no hosted resale). v1.0 granted no source rights at all and was replaced.
Deterministic time-travel replay and the tamper-evident audit ledger are now granted on every plan including free. The licence described them as Community capabilities while the code gated them at Pro and Enterprise.
Evals and the CI release gate work on every tier, hosted or self-hosted.
Database row-level security is live: reads on the migrated paths run as a role that cannot bypass RLS, verified in both directions against production. Other read paths and all writes still run as a role that does bypass it — /security tracks the precise state.
API keys can be issued telemetry-only, so a key leaked from an application can post runs and nothing else.
Compliance exports verify the ledger before attesting to it, and controls evidenced only by a run count now report as partial rather than compliant.
seq 7 · 46b2415547d0… ← 42254c75fdba…
2026-09-012026.09.01.2
Published clause-by-clause regulatory maps for six more frameworks.
ISO/IEC 42001, NIST AI RMF, APRA CPS 230, APRA CPS 234, GDPR, and ISO/IEC 27001 each now have a public page mapping clauses to the exact Runback capability and evidence type behind them — generated from the same static definitions the in-app Regulatory tab evaluates live.
seq 6 · 42254c75fdba… ← 4fa97a75498e…
2026-09-012026.09.01.1
Added a live public verification badge for the audit ledger.
Any workspace with a sealed ledger can embed a badge that renders fresh, server-side, from the same public transparency log this changelog borrows its design from — not a static image.
seq 5 · 4fa97a75498e… ← 4e1fd980b95d…
2026-09-012026.09.01
Live hover tooltips on every dashboard chart; removed remaining static/placeholder data.
Every chart in the app now shows a real data tooltip on hover, sourced from the same query the chart itself renders from — nothing hard-coded.
seq 4 · 4e1fd980b95d… ← 38e9307e7152…
2026-08-312026.08.31.2
Published a measured onboarding number instead of an unmeasured claim.
"Time to first captured run" is now a real, scripted benchmark timing a fresh workspace through its first ingested event — published on the onboarding and pricing pages.
seq 3 · 38e9307e7152… ← 29be73a016d3…
2026-08-312026.08.31.1
Shipped Go SDK Phase 1: event capture, redaction, and cassette hash-chaining.
A first-party Go SDK now captures model/tool calls and posts them to ingest, alongside the existing TypeScript and Python SDKs.
Redaction and cassette hash-chaining were ported from the TypeScript implementation and are on by default, not opt-in.
seq 2 · 29be73a016d3… ← cd359afd6ab9…
2026-08-312026.08.31
Advanced the tenant-isolation (RLS) migration and added session revocation.
Ledger, compliance, runs, narratives, security findings and external grants now read through the tenant-scoped client, where Postgres row-level security is load-bearing. Other read paths and all writes still run as a role that bypasses RLS — see /security for the current, precise state.
Sessions can now be explicitly revoked (not just expired), with the revocation itself recorded in the admin audit trail.
seq 1 · cd359afd6ab9… ← genesis
text of 2026-09-01: 7e59a376a019… · corrected 2026-09-07 to cd359afd6ab9…
Recompute it
Check it yourself with one command.
Recompute the changelog chainShell
curl https://runback.dev/api/changelog | node -e '
const crypto = require("crypto");
const sha256 = s => crypto.createHash("sha256").update(s).digest("hex");
function canonical(v) {
if (v === null || typeof v !== "object") return JSON.stringify(v) ?? "null";
if (Array.isArray(v)) return "[" + v.map(canonical).join(",") + "]";
return "{" + Object.keys(v).sort().filter(k => v[k] !== undefined)
.map(k => JSON.stringify(k) + ":" + canonical(v[k])).join(",") + "}";
}
let data = "";
process.stdin.on("data", c => data += c);
process.stdin.on("end", () => {
const { entries, pins } = JSON.parse(data);
let prev = "";
for (const e of entries) {
const { seq, prev_hash, entry_hash, ...release } = e;
if (prev_hash !== prev || sha256(prev + canonical(release)) !== entry_hash) {
console.error("BROKEN at seq", seq); process.exit(1);
}
const pin = pins[release.version], h = sha256(canonical(release));
if (!pin || h !== (pin.corrected ? pin.corrected.hash : pin.hash)) {
console.error("EDITED at seq", seq); process.exit(1);
}
prev = entry_hash;
}
console.log("chain intact;", entries.length, "entries match their pins");
});'
Honest limits
What this page does not claim.
Not a git logThese are curated, customer-facing release notes, not a raw git log — a chain over a summary we wrote is not proof the summary is complete.
Pins live with the textThe pinned hashes are literals in the same repository as the releases. An edit to a release fails here until someone also changes its pin, and that change is a diff in our git history, which is private. Archive /api/changelog if you want your own copy to hold us to.
Chain history2026-09-07: 2026.09.07 was inserted at the head of the chain instead of the tail, which re-hashed every earlier entry. 2026-10-07: Moved to the tail, in date order. Chained hashes served before this date differ; content pins do not. 2026-10-07: Content pins computed from git history for every release.
No timestampingThere is no independent time-stamping on these entries the way there is for audit-log checkpoints (RFC 3161 witnessing, a public transparency log). This chain proves internal consistency — that nothing here was silently altered — not that it existed by a given date beyond git's own commit history.