Skip to content

Changelog

What shipped

Stemmory releases several times a day. This is what actually shipped, in plain terms.

26 September 2026

the graph fills the screen with Floating, Tree and Radial views (STEM-471)

  • **The project graph fills the screen, and you choose how it's laid out (STEM-471, #908).** The graph canvas now runs from the sidebar to the edges of the window, with the title, search, filters and controls floating over it. A new **View** control in the top-right offers three layouts, remembered on your device:
  • **Floating view** (default): the layered map you know, now with the whole window to breathe in.
  • **Tree view**: the same map folded into rows, so every feature card is readable without zooming.

26 September 2026

import stops duplicating existing features (STEM-470) + dashboard follows the newest import (STEM-469)

  • **Import no longer duplicates features you already have (STEM-470, #905).** A re-import now recognises an existing feature when the proposal shares a linked doc path, the same title (case and spacing ignored, matched against existing roots or siblings under the same parent), or the same slug, and it does so for subfeatures too, not only top-level features. The check runs when the tree is drafted and again when you confirm, and it never merges two proposals into one existing feature. Deprecated features are left alone by the new checks. On the Stem project's last re-import this would have prevented all 18 duplicates.
  • **The dashboard's import attention row follows each project's newest import (STEM-469, #902).** A confirmed proposal no longer keeps "Review import" on the dashboard, and an older failed import no longer shows once a newer one has run.
  • **CI:** the baselines guard no longer reports a committed screenshot as missing on a loaded runner (a `pipefail` + `grep -q` race), which is what failed the previous release gate.

25 September 2026

hotfix — the dashboard no longer shows a stale "Review import" for a confirmed proposal (STEM-469); kit programme close-out docs

  • The dashboard's "Needs your attention" section no longer lists a confirmed import proposal as "Review import". Confirmation is recorded in `import_jobs.confirmed_at` while `state` stays `proposal_ready`; the query filtered on `state` alone, so a confirmed proposal was an attention row forever and linked to the confirmed view. Seen on production for Stem (confirmed 12 August). Fixed in #898 (STEM-469): the query filters `confirmed_at is null` and the row builder skips a confirmed proposal, both tested red-first.
  • Docs only: the kit adoption programme's closing record and the page-mapping reconciliation (#887), and the changelog entry for #896 (#897).

25 September 2026

promote main — kit adoption waves 0–6, one design system and one feedback vocabulary, auth shell, hero v2 (STEM-445…461)

  • One design system, end to end. Every button, field, select, menu, dialog, table, card and empty state in the app now comes from one set of primitives on one token scale: 32px controls, one radius scale, one hairline shadow, sentence case everywhere. The uppercase tracked labels are gone from every header and card.
  • Feedback you can trust. Every failure, refusal and empty state uses one vocabulary: a dot-marked line beside the control that failed, a section notice with Retry and a reference code when a whole section could not load, a table row that says "nothing here" under the real header, and a quiet "Saved" that fades. Screen readers get the right announcement for each.
  • Sign-in, sign-up and the MFA step in a split shell with slotted code fields. A real ⌘K palette on cmdk, real menus with tooltips and keyboard hints, an accessible member-remove dialog, avatars with brand fallbacks.

16 September 2026

promote main — UI polish wave, palette, E2E diet, Doors & Rooms docs (STEM-218)

  • Softer borders across the whole app, and a settings area that reads as one system: each subject in its own card, a quiet "Saved" that fades, a member count in the heading, and a failed load that names what failed and offers Retry.
  • Billing shows one allowance meter as a percentage, keeps your cached plan visible with a reference code when the payment provider is slow, and lists payments as Date, Description, Amount, Status; the import wizard has one heading, one footer and a landing card that shows the real state.
  • Activity gains All / Imports / People / Agents filters that live in the address and folds repeated system rows into one line; long decisions clamp with Show more; archived projects get a Restore banner; notifications and the 80% email now say "import allowance".

9 September 2026

promote main — M12 · Error & interrupt pages (STEM-218)

  • ## release: promote main → release — M12 · Error & interrupt pages
  • Routine `main → release` promotion per `docs/runbooks/release-day.md` §6, carrying the whole M12 milestone (all 19 tickets Done, milestone sweep "SHIP WITH FIXES" with the fixes merged — see the milestone comment in Linear), the STEM-365 CI tiering, the STEM-366 Next.js 16.3.3 bump, and the hygiene lane.
  • ### What ships (PRs since the last promotion, #734)

7 September 2026

Workspaces hotfixes — rail follows the URL, email guard, invites in seconds (STEM-361, STEM-363, STEM-362)

  • the rail and workspace switcher follow the workspace in the URL instead of the last server render: switching or creating a workspace updates the header, the checked item, every rail link and the role-gated rows without a reload. Review findings applied (sibling test for the new `api/rail/workspace` route, a confirmed fetch that was discarded, a stale sync timestamp after a switch).
  • `lib/email/send.ts` refuses reserved/fixture recipient domains outright (permanent, non-retryable, logged at info) and refuses the real provider outside production unless `EMAIL_REAL_SEND=1`; the same guard on the sign-in OTP and e-mail-change chokepoints applies only where a real provider would send (the first CI run proved the unconditional form broke local sign-in); CI asserts no job hands the app a Resend key; `scripts/lane-env.sh` strips it. Closes the 46.67 % bounce-rate incident at the code level.
  • an invite's email leaves with the invite (bounded `after()` drain, idempotent) instead of on the next five-minute cron tick.

7 September 2026

M11 · Workspaces — orgs become workspaces, /w/:slug/ routes, per-project visibility (STEM-335)

  • Phases 1–5 of the Workspaces feature (STEM-322 … STEM-335, all Done or code-complete on main):
  • `orgs.kind` + `create_workspace` (cap 3 owned team workspaces, 3/24 h); project visibility `open|restricted` with `project_members` and `private.visible_project_ids()` in RLS; `lib/authz` as the one authorization module with two CI guards; `billing_accounts`; `/w/:workspaceSlug/` on every app route with legacy 302s until 2026-12-04; the workspace switcher and create dialog; hashed invite tokens + `/invite/:token`; Members & roles per the spec (Viewer everywhere, role ceiling, read-only 11×4 matrix, billing owner-only); project-settings tabs with the Access tab; visibility on every surface with 404-not-403 proven byte- and timing-identical; OAuth state bound to the workspace; eleven audit events and nine telemetry events; the H5 visual pass (112 baselines), H6/H7 + axe, three journeys in CI.

4 September 2026

Waves 17 + 18 — systemic UI fixes, dashboard + graph per docs/ux, one workspace and one installation per project

  • **Wave 17 — UI polish batch 1 (#655, STEM-315)**
  • Every hand-rolled checkbox replaced by the shadcn Checkbox with a positioned wrapper; the shell no longer scrolls on project settings, members, account and five more routes (guard: `shell-scroll.spec.ts`).
  • One `PageHeader` per route (eyebrow = section, H1 = page; workspace name never a title), enforced by a filesystem-enumerating test over all 35 pages; `/projects/<slug>/import` canonical with `/review` and the write-back router redirecting to it.

3 September 2026

Wave 16b — enforce the nonce CSP with a report-only twin, nothing else

  • ## What ships — one change, on purpose
  • the nonce Content-Security-Policy on app routes flips from report-only to **enforcing**, with a `Content-Security-Policy-Report-Only` twin carrying the identical policy retained so any post-flip regression still reports to `/api/csp-report` and the drain. Report-route caps doubled for the doubled volume. Tests reversed to pin the new premise; click journeys added on a marketing page and an app page to catch the "renders fine, every handler dead" failure mode. `SECURITY.md` §6/§9 updated.
  • Founder rulings 2026-09-03 (STEM-211): 1a probe proved the reporting channel on the live deployment; 2a 3.4-day zero-violation window accepted; 3a enforce + twin; **4b this release carries nothing else, so a Vercel instant rollback of it reverts only the CSP**; 5a CI's Database job is the "journeys under enforce" evidence; 6b Paddle checkout under the policy is done live after this deploys.

3 September 2026

Wave 16a — graph ceilings wired honestly, off-page-one citations anchored, UX workshop docs

  • six post-forest CI reads recorded honestly (the review caught a censored subset), the first-node ceiling (13,000 ms) asserted at runtime, the layout reversion detector pinned as a literal 7,026 ms that no future read can ratchet. STEM-302 verified and closed; STEM-191 stays open on two proxy-only bullets.
  • an Intelligence citation to a decision older than page one now opens `/decisions` at that decision's group, anchored and scrolled into view; unknown or foreign ids fall back to page one with byte-identical output; "← Most recent" on any non-first page. Verified and closed.
  • the 2026-09-03 UX workshop bundle under `docs/ux/` (docs only).

3 September 2026

Wave 15 (take 2) — audit gate fix on top of #636: fast-uri/qs pins

  • ## Why a second release PR
  • #636 merged to `release` but its run (33686755116) failed the **Dependency audit (blocking on release)** gate — four new high advisories in the transitive `fast-uri` — so migrate and deploy were skipped and production is still on the Wave 14 release (`41700a8`). This PR promotes the fix on top; the Wave 15 code from #636 is already on `release` and ships with it.
  • ## What ships (delta on top of #636)

3 September 2026

Wave 15 — Intelligence add-on sellable, ticket citations, workspace ⌘K, forest layout, CI hardening

  • Operator customers can now buy Stemmory Intelligence as an add-on from `/billing/subscription`: an attach card mirroring the extra-seat block, amount verbatim from Paddle's preview, inline confirm, and a remove that schedules to 30 minutes before renewal so the cron beats Paddle. Both actions require a billing admin plus AAL2 step-up; a pending removal suppresses plan-switch controls so it can't be silently discarded; the end date shown is the renewal day.
  • Intelligence answers now cite tickets as a fourth source kind, and an integration test proves every cited id belongs to the scoped project. Decision citation chips land on their `#decision-<id>` anchor on `/decisions`, every member of a grouped card included. Seed fixture FK ordering fixed.
  • ⌘K in workspace scope now searches the project list (the last open STEM-168 bullet). Palette recents are cleared on log out, sign-out-everywhere and account deletion. New owner/admin setting `show_origin_user` (default off) controls whether activity rows name the linked account; the feed's read never selects `origin` and the renderer never prints it unless it is on, both pinned by binding tests and pgTAP.

2 September 2026

Wave 14 — Intelligence completes, add-on truth, activity writers, worker layout, isolation proven

  • Intelligence rounds out: answers stream with a Stop that keeps what arrived and still meters what was spent; questions can narrow to one node's subtree; owners get /settings/intelligence (enable, project scope, agent-decisions-as-sources, retention, allowance %) and every knob is enforced server-side; ⌘K hands the typed question straight into ⌘J.
  • leaving Portfolio now offers to keep Intelligence for $15/mo (never pre-ticked, amounts verbatim from Paddle); the pricing page stops calling shipped features "Not built yet", with a structural test that fails if that ever drifts again.
  • activity now records sync runs, decisions and member joins (the feed shows real history); the ⌘K palette tells the truth about Intelligence availability and ignores held keys; decisions pagination accepts non-v4 ids.

1 September 2026

release guards read Paddle ids from Vercel; changelog job lands via PR

  • the release guard reads production's Paddle price ids from Vercel at run time, so a price lives in one place and the live-catalogue check reports on what production actually charges.
  • the changelog job lands its entry through its own auto-merged pull request instead of a direct push that protected main refuses; the entry for the 1 September price-correction release is included.

1 September 2026

Sonnet 5 stays $2/$10 — price row corrected, live margin guard, changelog job fixed

  • Sonnet 5's price stays $2/$10: the $3/$15 row scheduled for 1 September (an increase Anthropic withdrew) is superseded, so usage metering, credits, the breaker and invoice reconciliation cost every call at the real rate again.
  • the margin-floor guard now reads the live model_prices row instead of a pinned dollar figure, so the next real re-price trips CI rather than passing silently.
  • the changelog job can read release PRs (it failed on its first run), the Wave 13 entry is on /changelog, and Fluid Compute is recorded as verified ON.

1 September 2026

Wave 13 — graph at scale, Intelligence, activity + ⌘K + share links, digest + changelog, infra truth, audit retention

  • the graph mounts only what is in or near the viewport; a 500-root project no longer builds ~4,400 DOM nodes before the first one is interactive, and the minimap steps aside above 500 nodes.
  • Intelligence: ask a question about one project's record and get an answer whose every citation resolves to a real node or decision, or no answer at all; ⌘J opens it, threads persist per project, and plans that do not include it see a stated Gate.
  • workspace and project Activity feeds over the record that was being written but never read; a ⌘K palette scoped to the project's nodes, decisions and actions; revocable read-only share links that serve a snapshot, never a live read.