Skip to content

v2.0.0

Choose a tag to compare

@github-actions github-actions released this 02 Nov 11:13
· 19 commits to main since this release

2.0.0 (2026-11-02)

⚠ BREAKING CHANGES

  • sso: SCIM tokens issued before the move to managed connections
    no longer authenticate, since the legacy scim_provider table is dropped.
    Every organization that provisions through SCIM must issue a new token from
    the SSO settings page and paste it into its identity provider. The API also
    needs a new SCIM_CREDENTIAL_HASH_SECRET (at least 32 characters, required
    in production), the HMAC key directory tokens are stored under; rotating it
    invalidates every issued token.

Features

  • admin: add accounts, organizations, audit, team and approvals screens (9ea6652)
  • admin: add four-eyes approval of sensitive actions (e3bb4c3)
  • admin: add plan overrides and staff notes to the account screens (58c3dc7)
  • admin: add staff roles and permissions behind the admin routes (2cdab7e)
  • admin: add the back office app shell (77e5cdf)
  • admin: add the inbox home, the palette and private saved views (063280d)
  • admin: add the operations screen with requeue, heartbeats and stripe replay (945321a)
  • admin: announce every end of an impersonation (e375a26)
  • admin: make admin writes atomic and require a step-up (402790d)
  • api: add behavioural security signals and a captcha hook (719c4b4)
  • api: let instrumentation flush pending events on demand (eba6575)
  • app: explain icons, truncated values and disabled controls with tooltips (7de1858)
  • app: rebuild every screen on the sober tool direction (1001166)
  • app: remove the admin screens and return to the back office after impersonation (47c3ef1)
  • app: show a not-found page on unknown urls (8ce5373)
  • consents: record when pre-login cookie consent is attached to an account (af3a9f3)
  • cron: ping a heartbeat url around the sweep run (9b4aab8)
  • ddd-kit: add map, flatmap, maperror, match and all to result (03a4a82)
  • ddd-kit: add toresult, trymap and equals to option (4f76953)
  • ddd-kit: add uuid parse and make uuidv7 monotonic (34ad911)
  • ddd-kit: carry the transaction and collected events in one ambient scope (b519af4)
  • ddd-kit: give domain events an id and compare value objects by json (8dbbc16)
  • email: claim and settle queued mail by lease with a replayed dead state (e640cf9)
  • outbox: add dead state and per handler delivery columns (4a82c3a)
  • outbox: claim events by lease and settle them per attempt (6c0c92d)
  • outbox: return the stored event id and document delivery bookkeeping (40770fb)
  • outbox: run handlers outside transactions with retry and a dead state (d3c6d26)
  • sso: provision scim directories through managed connections (4db5983)
  • sso: require reconnecting scim directories with managed tokens (efa4464)
  • ui: replace the theme with the sober tool direction (1f28182)
  • webhooks: claim and settle deliveries by lease with a replayed dead_letter (1dc2a63)
  • webhooks: record who replays a webhook delivery (f2feafb)

Bug Fixes

  • account: show a wrong current password under the right field (95fa666)
  • admin: close the approval, override and list gaps found in review (d0edd2e)
  • admin: close the four-eyes bypasses found in review (e66a0e5)
  • admin: close the privilege gaps of the staff model (cf1c34e)
  • admin: close the production and reuse gaps of the back office shell (8785ec3)
  • admin: close the replay, inbox and read failure gaps found in review (e37a96d)
  • admin: close the step-up and session gaps found in review (f3abfd8)
  • admin: end impersonations when staff access is lost (968c882)
  • admin: settle stripe verification, replay scope and saved view filters (8e62034)
  • api-token: answer 400 to a scan payload that is not a list of entries (cc227cb)
  • api: attribute an org auto-deleted by scim deprovisioning to its owner (bbeef4a)
  • api: attribute system events to no user in the audit trail (8524710)
  • api: close the review pass defects in errors, auth, limits and csrf (177c61b)
  • api: commit the public api name change and its event together (90c25cc)
  • api: keep a failed lease release from failing a committed digest flush (3ef56f2)
  • api: keep the api running when the email worker's first drain fails (da2b873)
  • api: keep the api running when the outbox dispatcher's first drain fails (90a9a3a)
  • api: record signup policy acceptance with the trusted-proxy client ip (6476584)
  • api: scrub query params and emails from sentry exception text (dbaa8fb)
  • app: accept only a bare origin as the back office url and close phase k (a338583)
  • app: close the defects found by the final review (baf6f8c)
  • app: fall back to the build mode when the sentry environment is blank (8f918e7)
  • app: keep a page heading on admin detail pages while they load (1edee9b)
  • app: keep loaded data on failed refetches and share page states (23efcb7)
  • app: keep status and code on api failures so 4xx stay out of telemetry (fb0081d)
  • app: keep the user menu initials in its accessible name (ad51923)
  • app: stop reporting sso sign-in redirects as unexpected errors (95b5715)
  • app: stop the app shell overflowing small viewports (c0c7ee0)
  • app: surface silent failures and keep invitees through sign-up (c3aee61)
  • app: tell the user when copying the backup codes fails (32893f2)
  • auth: record the trusted-proxy ip on new sessions (5b9e8bf)
  • auth: show translated copy when sso sign-in fails (97f04fa)
  • billing: let better auth write stripe subscriptions (b7a83e6)
  • billing: stop treating prototype names as valid plan tiers (43d3281)
  • ci: fail the pre-push chain on api type errors (666e9f8), closes api#type-check
  • ddd-kit: keep watched list change tracking correct across re-adds (fe11cac)
  • docker: build on the latest published node 26 image (b9ab8d2)
  • docker: prune with the turbo version the repo resolves (5f8ec0c)
  • drizzle: roll back a unit of work whose callback returns a failed result (4b3b0bd)
  • drizzle: stop reporting every aborted transaction to sentry (6352bb5)
  • events: parse a stored api token expiry back into a date (d9aaaa9)
  • notifications: stop a rate-limited preference save from toasting twice (d6bee8e)
  • organization: label the new owner picker in the transfer dialog (4734922)
  • outbox: reconnect the listener with backoff and a keepalive (437b5ec)
  • policies: record the real client ip on policy acceptance (9e7cd14)
  • public-api: audit profile name changes made through an api token (0e7e89d)
  • rgpd: accept imported base32 totp secrets on account deletion (ab5464b)
  • rgpd: ignore unconfirmed two-factor enrolments on account deletion (0e66ff5)
  • rgpd: report totp secret decryption failures to telemetry (7ab08cc)
  • rgpd: verify totp with the rotated auth secrets (5f749da)
  • security: confirm copied recovery codes only after the clipboard write (5a09526)
  • sso: keep scim connection writes consistent under concurrency (df6b7bd)
  • sso: let a new user finish their first sso sign-in (5ed0add)
  • sso: stop reporting rejected sso calls as unexpected failures (45dae25)
  • ui: let the app name every label the shared primitives render (b456a84)
  • ui: only confirm a copied value once the clipboard write succeeds (391032a)
  • webhooks: report a failing first drain instead of crashing the api (de3a699)
  • webhooks: stop doubling the page padding on the webhooks settings page (ffed148)
  • webhooks: stop exposing the previous secret cipher in responses (526955b)

Refactor

  • access-control: derive the owner grants from the app statement (a2a95d4)
  • account: move the avatar upload mutation into its own hook (bfb65a4)
  • admin-audit-log: narrow the metadata diff instead of casting it (cb49d40)
  • admin-orgs: show a hyphen for an organization without a plan (2c8e4f6)
  • admin-users: derive every platform role type from one schema (051653f)
  • admin: fold the staff forms into the back office app (99adf6b)
  • admin: read schema columns lazily in the admin stores (019d122)
  • admin: report admin store failures once, as typed results (39e0bb9)
  • api-token: carry unset token fields as options (c5f7ca2)
  • api-token: keep the revoked reason nameable by the front (ac82455)
  • api-token: look up the leaked token owner as an option (1543af1)
  • api-token: map token rows through a mapper, not a cast (b561724)
  • api-tokens: keep the token schema free of react and its labels in the form (0323327)
  • api: attribute audit rows and notifications from one actor lookup (dc52f5a)
  • api: build every retention sweep route from one table pass (02ffda6)
  • api: declare the csrf and auth rate-limit guards as tables (47fd98b)
  • api: declare the sso enforcement body once (5c8b407)
  • api: map audit rows through a single record mapper (6c6df74)
  • api: move the plan entitlements catalog to the shared kernel (7d32a4f)
  • api: name tests after their subject and drop duplicated notes (676eadd)
  • api: pass the email batch idempotency key as an option (1bd794d)
  • api: point both sso enforcement routes at the shared body (2ce3486)
  • api: promote the api token port to the shared kernel (1b48f56)
  • api: read org roles and api tokens through one lookup each (eaa9c9d)
  • api: read the ambient transaction in api-token, profile, quotas, rgpd, webhooks (f36bab1)
  • api: read the ambient transaction in billing, consents, notifications, policies (62001ac)
  • api: read the ambient transaction in shared repositories (87299e0)
  • api: report password policy violations as an option (14973c6)
  • api: return failed results from units of work instead of throwing (6980c77)
  • api: return the next retry instant as an option (0cce360)
  • api: route worker and sweep transactions through the unit of work (44babdb)
  • api: shape store failures with one shared helper (4b597b4)
  • api: share one harness across the database check scripts (b6e2f74)
  • api: share the best-effort security event emit (a2b6897)
  • api: share the retry delay curve between the outbox and email workers (335c28b)
  • api: stop workers in order under a global shutdown deadline (8da0b12)
  • api: tidy shared kernel comments and dead fallbacks (3a8d5d0)
  • api: trace every email queue write under its real statement (196a62e)
  • api: trace the sso enforcement update as its own query (107d163)
  • api: write the sso enforcement flag through auth-queries (d18f044)
  • app: decide nav entry visibility in one place (0fceb33)
  • app: drop billing type re-exports nobody imports (824301d)
  • app: drop dash punctuation from shared auth, ui and notifications (1551853)
  • app: extract the shared web foundation into a package (0f94c36)
  • app: gate the org members and invitations queries on the org (243bbc4)
  • app: give notification category labels one home (21ec4bd)
  • app: keep the sign-out shortcut hint and binding together (da0299b)
  • app: name the placeholder shown for an absent value once (4d92587)
  • app: read api error fields through one guard (9666a4b)
  • app: read consent categories from the shared package (f1ae3f5)
  • app: refresh the own session and other tabs through one hook (53024b8)
  • app: replace dashes in shared comments and test names (1ba8c04)
  • app: resolve a missing active organization in one place (b4d269f)
  • app: resolve request fallback copy from a catalog key (fc27d2a)
  • app: stop naming the broadcast channel factory like a hook (7a9fe34)
  • app: tidy shared imports and platform admin checks (cddd57c)
  • app: type the current membership role as an org role (3b3d5b9)
  • auth: run the better-auth hooks in the ambient unit of work (f46af3e)
  • auth: share the sign-in completion and token consumption steps (6715112)
  • auth: share the totp settings between two-factor and account deletion (659da3a)
  • billing: derive subscription statuses from one list (2e96e99)
  • billing: open the billing portal through a service and gateway (6aae8fa)
  • consents: carry optional consent metadata as options (92a3cb2)
  • ddd-kit: flatten event collector add into guard clauses (4fb9b0a)
  • ddd-kit: let repositories declare their error type (7d38772)
  • ddd-kit: name event handlers and deliver per handler (0d5cf09)
  • developers: stack the event catalog with a flex gap (3502df1)
  • drizzle: share the database url guard between both pools (7cc17f4)
  • emails: build the digest subject once and name the package exports (a8e8939)
  • events: declare api token revocation reasons once (b8d4389)
  • i18n: replace em dashes in en and fr copy with plain punctuation (a47dba6)
  • jitter: drop the process-clock retry helpers (5761271)
  • legal: build policy docs from one helper and trim table markup (28cd92a)
  • organization: guard member roles instead of casting them (ce0cf94)
  • outbox: run audit, webhook and notification fan-out as named handlers (7268902)
  • outbox: share lease sql fragments and failure schedule (f024e29)
  • policies: carry the acceptance ip as an option in the store port (1cf9d54)
  • privacy: render the privacy card lists with the shared list rows (f2e5359)
  • quotas: share the usage row filter across quota store reads (f4fae41)
  • rgpd: load deletion state and purge user objects in one place (9e756ab)
  • rgpd: share the deletion dialog footer and flatten the preflight states (3a534c2)
  • router: render pathless gates as bare outlets (07ae823)
  • security: flatten passkey error branches and name the device label (672fb9e)
  • sso: narrow the provider tab value instead of casting it (6c39616)
  • ui: add a compact initials avatar for organizations (c475738)
  • ui: cover inline muted and mono text with primitives (7eb3ff6)
  • ui: drop the prose margins paragraphs and lists had to cancel (b093f97)
  • ui: give a list row one clickable content slot (932a4b7)
  • ui: give command items a hint slot (3809d44)
  • ui: let a checkbox field carry a label with inline links (a654b76)
  • ui: pin the cookie banner through a bottom banner primitive (e7b4233)
  • ui: render label and value pairs as a description list (cd891fd)
  • uow: join nested runs to the ambient transaction (aa7c1da)
  • uow: remove the transaction parameter from ports and repositories (c5a4439)
  • uow: roll back a run that raised events nobody can persist (1914d19)
  • uow: run better-auth transactions as their own outermost unit (f5b0764)
  • uploads: check key ownership through one guard (d1a9d05)
  • uploads: default the presign ttl bounds in the env schema (4282555)
  • webhooks: drive delivery badges and filters from the status lookups (7585c3a)
  • webhooks: validate event types with one shared schema (6545545)

Build

  • deps: load the drizzle env files with dotenv 18 (ca2ed2f)
  • deps: move @hookform/resolvers to 6 (003087b)
  • deps: move @sentry/vite-plugin to 11 (1c380f1)
  • deps: move inwire to 4 (e2354ff)
  • deps: move sentry to v11 without letting it start collecting pii (3e2fc4d)
  • deps: move stripe to 23 (c2ea1d1)
  • deps: move to node 26 lts, bun 1.4.4 and pnpm 12 (8c443c6)
  • deps: move tsup to 9 (196a62d)
  • deps: pick up the latest hono and aws sdk patch releases (235e5ce)
  • deps: pick up the latest minor and patch releases (9b07bc6)
  • deps: refresh every workspace to the newest in-range releases (c081d81)
  • deps: run every vitest suite on vitest 5 (7c6e131)

Documentation

  • api: bring the shared inventory and billing listing up to date (4ad8f5f)
  • claude: bring the seven claude.md files back to the as-built state (dbaa51a)
  • claude: drop the em dashes from the agent-facing guides (f23d8f8)
  • claude: one guide per app and per package (143c52c)
  • document the lease model for email and webhook queues (b8718d4)
  • drop the em dashes from every guide, inventory and roadmap (12ea3ce)
  • features: point the legal body selection at policies/bodies.ts (b4be41a)
  • outbox: document lease delivery, handler names and dead replay (6145f00)
  • readme: correct the clone and deploy path (36a0dbe)
  • record the better-auth 1.7 move and the three remaining pins (babb176)
  • record the october 2026 dependency refresh (9dbcbb3)
  • refresh event totals and the list of what is left (bfb8a78)
  • roadmap: add the openup resync phase and make every phase follow one shape (6b8476a), closes #70
  • roadmap: add the standalone back office as phase k (7818e77)
  • roadmap: mark the review pass delivered (1d3c944)
  • roadmap: plan a front redesign from scratch before the review pass (1d729a1)
  • roadmap: record the post phase k follow-ups and what stays open (f873f6e)