v1.0.0-beta.6
Released to production on August 19, 2026 at 20:21 CDT. See every commit in this release on GitHub
The tree cut as v1.0.0-beta.5 never reached production, so its changes ship here. This version reached production in 4 deploys; the last landed on August 20, 2026 at 19:05 CDT.
New
- Console: a /v1 list can be searched, so a sync stops sweeping the whole collection
- Assist: the monthly spend ceiling ships ARMED at $40
- Console: a merchant can see the sales tax their own storefront collected
- Tooling: derive the shipped-but-still-open queue by STATE, not by label
- Platform: the collaborator seat add-on is a POOL, allocated per site
- Assist: a monthly spend ceiling the reservation can refuse on
- Console: the console tells an author they cannot publish, instead of the database
- Marketplace: the abuse queue gets something that can feed it
- Email: the suppression list gets a reader
- SEO: a shared card says what it shows
- Console: the campaign send cap gets an odometer, not just a ceiling
- Email: a bounce on transactional mail stops dropping on the floor
- Tooling: a guard that asks whether ANY copy of production data is off-project
- Operations: a cron job that stops being scheduled stops being invisible
- Accounts: the signups lock refuses the account itself, not just its session
- API: an agency can push a client's assets over /v1
- Operations: restore the storage-backup guard a third concurrent commit swept away
- Operations: restore the storage-backup guard a second concurrent commit swept away
- API: an integration can publish the records it just wrote
- Operations: restore the storage-backup guard a concurrent commit swept away
- Sites: an author can describe a collection entry cover and an event cover
- Operations: the buckets nothing copies get a guard that measures the copy
- Console: the billing page keeps the interval a visitor was quoted, and stops guessing their plan while it loads
- Tooling: prove no secret is shared between production and dev/preview
- Billing: one account stops holding unlimited free workspaces
- Console: a customer's bug report reaches the Customer bug reports project, carrying who and where
- Console: the assistant stops taking orders from the text it is reading
- Console: the assistant stops telling publishers a $1 listing will publish
- Email: a platform send-rate governor, with a staff ramp
- Console: staff can see and unstick a customer's domain
- Consent: a non-Google ad tag becomes something consent can gate
- Consent: give the opt-out control the icon CPRA also specifies
- Bookings: a paid booking reports revenue to both properties
- Console: analytics defaults ON where implied consent is lawful
- Sites: site search answers across collections, with count tabs
- Plugin UI: the search box can suggest instead of filtering
- Operations: customer media, plugin bundles and the export get a real off-project copy
- Bookings: a merchant can charge their own service tax on a paid booking
- Billing: the usage trend the rollups could always have answered
- Commerce: a merchant can charge their own lodging tax on a stay
- Platform: an instance can override a component's inner attributes
- Console: the console can be searched, and says what it can and cannot find
- Accounts: enforcing SSO cannot lock an org out of itself any more
- Security: a disputed domain can be locked without taking the site down
- Operations: the Connect destination stops being the one thing the billing tile cannot see
- API: an agency can provision a client's site over /v1, once
- Accounts: a staff-attested SSO domain has a representation publish recognizes
- Operations: a server error stops being invisible to everything that can page
- Accounts: an SSO sign-in prefills the address the directory already holds
- Self-hosting: an operator can deploy the Firestore indexes without the Firebase CLI
- Accounts: a custom console domain can be signed in to, once, and never replayed
- Privacy: a breach can name the Member States it has to file in
- Accounts: a device you do not recognize can actually be signed out
- Privacy: a host can ask visitors for an advertising basis, default still deny
- Privacy: the vendor sweep can see a package-mediated egress, repeatably
- Console: the maintenance jobs get a screen, and the destructive two get rails
- Analytics: our own paid transactions stop reporting as real revenue
- Media library: the contentSha256 backfill gets a plan and a gated script
- Media library: a large signed upload finally carries a strong digest
- Analytics: a signup remembers which campaign produced it
- Console: the deployment says out loud what config it resolved
- Security: an upload has to be the kind of file it claims to be
Fixed
- CI: the legal-drift comment stops tripping the retired-name sweep
- Commerce: a stock movement and its ledger row cannot diverge
- Console: the org-library ceiling closes while its meter is off
- Brand: the tax summary and branding helper read the configured brand
- Sites: skip App Check registration when the site key is unset
- Security rules: deny the six host subcollections nothing writes from a client
- Commerce: a signed-in member cannot double-subscribe on the storefront
- Tooling: generate the metered pass-through table from the billed rates
- Console: the pricing-parity guard typechecks, not just runs
- Commerce: membership/recover stops being an unauthenticated mail relay
- Documentation: give apps/docs the jest types its own tsconfig asks for
- Tooling: the legal-drift comparator stops counting page furniture as drift
- Build: pin useTypeScriptCli off so the typescript alias resolves
- Commerce: a supplier ships only their own lines, and the token model allows it
- Commerce: a partial refund takes back exactly what it paid for
- Commerce: a promotion slot is held at checkout, so N shoppers cannot pass a cap of one
- Repository: restore the three commits AGL-2444 reverted by a moving parent
- Console: every advertised org permission is enforced server-side
- Console: a downgrade restates per-item tax_rates and phase-0 metadata
- Console: the usage sweep stops skipping every never-subscribed org
- Brand: a white-label org's blank Support URL links NOWHERE
- Commerce: a draft payment link reports the stock it cannot cover
- Commerce: a room is held in the transaction that checks it
- Commerce: a gift card is held at checkout, so two carts cannot spend it
- Tooling: say which Firebase variable was refused instead of dumping a GaxiosError
- Self-hosting: a container's frame-ancestors names only the operator's hosts
- Permissions: the SSO route reads the permission, not the raw role
- Assist: the history budget is shared across turns, not granted to each
- Self-hosting: name the request-geo headers, and stop calling a container "development"
- Docker: copy the .npmrc that npm ci reads into the deps stage
- Console: a paid add-on the schedule will drop no longer reads as "updated"
- Console: a site collaborator cannot list the workspace's API keys
- Console: the revalidate gate reads HOST_PUBLISH_ROLES, not a private copy
- Permissions: site creation and org settings read the permission, not the raw role
- Permissions: the server honors custom roles and per-member overrides
- Bookings: the reminder emails the docs promise now actually send
- Tooling: the Texas tax code on our own products exists in the repo now
- Console: dunning ends in a CANCEL, and three things now notice
- Console: an org-scoped site list holds off instead of listing every client
- Brand: the error and offline screens name no operator, lowercase included
- Console: the other three usage-alerts doubles answer the paged host query
- Console: an org-scoped route resolves the ORG brand, not the deployment brand
- Console: the usage-alerts sweep pages an org's hosts
- Email: the unsubscribe link stops firing on a prescanner's GET
- Sites: the free bandwidth cap engages at the beacon, not only in the cron
- Commerce: the tax card's brand import stops disabling its own use client
- Commerce: put 'use client' back above the import that displaced it
- Sites: an entry's published date reads the same on the server and in the browser
- Marketplace: a purchase licenses the organization that installs it
- Privacy: the collections the erasure grew get a disclosure decision, and one it could not see
- Self-hosting: the extracted revalidate helper stops hard-coding our apex
- Bookings: a merchant pricing a service is told no tax is added
- Commerce: a confirmed reservation says it carried no lodging tax
- Commerce: a storefront subscription records the tax it will bill forever
- Sites: a configured designated agent is actually published
- Platform: a CSAM reporter is no longer told we filed a report nobody files
- Build checks: eslint reaches the tools/ tree, and its 18 errors are fixed
- Data: a seed or migration that lands media bytes moves the storage counter with them
- Sites: a rich-text body reaches the crawler, and so does Custom HTML
- Build checks: the sx-after-spread guard can see an optional chain — and now runs at all
- Privacy: three org-keyed residues an erasure could not reach are collected
- Data: the last document carrying the listener's synthetic $id is scrubbed, provably
- Console: the reserved-slug refusal stops naming the platform to a white-label org
- Self-hosting: a self-host install stops pointing SSO at our own Firebase project
- Build checks: the Base UI exemption matches the file it names again
- Billing: contacts and dataset storage are measured inside the month they bill
- Build checks: the last seven dead initializers, four of them in coverage guards
- Commerce: a billing webhook that answers 200 and moves nothing stops being invisible
- Sites: a page named 404 stops pretending to be live, and four ordinary slugs come back
- Build checks: a defensive initializer that nothing can ever read is removed
- Commerce: one storefront order can say which kind of tax it carried
- Marketplace: a plugin sale names its own tax code, not the subscription's
- Tooling: a deliberate shared credential becomes a recorded decision
- Console: the workspace picker stops loading a workspace you never opened
- Console: two lockdown specs stop colliding in the global scope
- Console: the staff Users merge survives a second page
- Tooling: bootstrap stops copying production credentials into preview
- Console: restore AGL-1993, which 38e61ed35 reverted by accident
- Console: a cache module git called binary becomes readable code
- Console: an SSO staff session reaches the staff console it was already granted
- Console: a Google sign-up lands in a ready workspace, like the form one
- Security: locking a workspace for abuse also kills its raw asset links
- Billing: a storefront sale stops costing Aglyn more than it earns
- Commerce: a cash sale at the register pays the same platform fee as a card sale
- Marketplace: a $1 listing that loses money on every sale is refused, and the minimum is on the form
- Commerce: a paid dropship order still reaches the supplier when their server is down
- Console: the screen count a site sees is the one its plan enforces
- Commerce: the restock prompt asks about the lines the refund took back
- Security rules: three stale tests, not a rules bug — and a denial message that lied
- CI: the staff send-rate card stops hardcoding the brand
- Console: a verified account lands where it was sent from, not the app root
- Console: a custom role or a cleared override now decides who can invite
- Email: the campaign cap is per-org and atomic
- Console: /v1 bounds the pre-auth key lookup before it spends the read
- Site data: the durable limiter counts by atomic increment, not a contended transaction
- Console: a concurrent bundle import cannot overshoot screensPerHost
- Console: the two client-direct document classes get a hard cap
- Console: the four-slot error-screen bound becomes a property of the rule
- Permissions: a plugin-declared permission becomes a real control
- Console: drop a naming exemption whose text is gone
- Console: a claim-less staff account stops READING as super
- Console: a chargeback nobody claims stops being invisible
- Deploys: the alias verifier stops crying wolf on docs
- Documentation: clear the three defects the promotion gate caught
- Besigner: a version id stops being painted in the wrong case
- Console: cards fill the space beside a tall neighbor, and the badge links a page
- Consent: give the opt-out control the title CPRA actually specifies
- Sites: drop a revocation-cache initializer nothing reads
- Analytics: an authored step stops being able to refund real revenue
- Documentation: the trust page separates a pinned consent denial from a configured one
- Documentation: the trust page stops asserting a Google Ads state that is about to change
- Console: a revoked token stops working everywhere, and the promise stops lying
- Redirects: a 9-character redirect rule stops halting every tenant
- Security: four boundaries that were each one condition short
- Console: a refused site read stops claiming "No sites yet"
- Analytics: the one key event nobody could ever have seen starts firing
- Platform: the pricing CTA states the cadence it just quoted
- Tooling: the generated price list stops selling an SLA, an uncapped add-on and a silent 20%
- Sites: a tab pointing at an unpublished screen stops pretending to be a control
- Console: a joiner reaps the co-edit mirror instead of inheriting it
- Sites: a 404 stops being an untitled tab
- Sites: a screen link can point at the blog again
- Sites: the consent pill stops sitting on the copyright line
- Build checks: two guards that stopped guarding on main
- Besigner: correct what live component propagation actually rides on
- CI: the two reds blocking the gate — an over-strict prop type and a literal NBSP
- Besigner: the canvas honors an instance's attribute overrides too
- Console: the docs help registry catches up with the domain-scope anchor
- Build checks: three dead stores in the dependency egress sweep stop reddening check:lint-tools
- Build checks: the deferred-import guard now covers instrumentation.ts, the file that last broke the gate
- Build checks: the server error hook stops making every static import of tenant-data-admin illegal
- Console: the Live pill sits in the card header, and the terms banner stops being inset
- Besigner: a local undo stops destroying a co-editor's work
- Tooling: a commit that deletes another issue's just-added file is findable
- Besigner: the media browser moves onto the field that promises it
- Tooling: the /legal card dates are re-derived from the documents, not remembered
- Privacy: the handoff verifier is a declared cookie, not an undisclosed one
- Accounts: the session specs' IdP mock knows about the address resolver
- Accounts: the SSO card reports an attestation it can now actually see
- Operations: a deliberately partial wire run stops calling itself a failure
- Self-hosting: the docs origin and the legal origin each get ONE reader
- Console: an image used only in a site's email stops reporting as unused
- Self-hosting: a deployment that never had payments stops reporting a failure
- CI: typecheck is green again — a narrowing quirk and a required field
- CI: a self-host install gets the handoff TTL, and a white-label org stops reading our name
- Accounts: the sso-lookup spec stops registering a dynamic nx edge
- Sites: a site that is switched off stops counting page views
- Marketplace: a restored install stops minting per-version installs
- Operations: the presence and co-edit rooms stop being readable an org at a time
- Commerce: the console stops promising a retry window nobody has read
- Media library: a takedown stops saying it recalled what it cannot
- Tooling: the demo-brands Firestore double models runTransaction
- Self-hosting: the v1 media bucket is read in the form Next actually substitutes
- Self-hosting: the version resolvers read metadata a bundler can actually see
- Console: the four signup specs my campaign parse reddened can see it
- Self-hosting: an App Check debug token cannot quietly become live
- Self-hosting: attaching a console domain permits its uploads
- Tooling: the gate stops sharing a cache with the checkout it was supposed to be isolated from
- Analytics: the marketplace revenue beacons stop being fired and forgotten
- Self-hosting: an operator can read which version they are running
- Tooling: both ratchets survive an index entry with no file on disk
- Dependencies: the plugin-fetch SSRF guard stops renting its HTTP client from a dev dependency
- Tooling: the color ratchet sees a color written as rgba(), not just as a hex
- Commerce: a test-mode Connect account stops reading as payments-ready
Performance
- Sites: a page's version read stops queueing ahead of its chrome
Documentation
- Commerce: the reserve spec stops advertising a gap it closes
- Documentation: an API key never spans organizations
- Self-hosting: say plainly that no Docker images are published
- Commerce: the shipping refusal cites the issue it came from
- Assist: the Assist signal board gets the staff-console page it lacked
- Self-hosting: the template and the runbooks describe the deployment an operator actually gets
- Database: the three owed TTL policies are enabled, so the doc stops saying they are not
- Console: delete the comment for the naming exemption ba77f0ab4 removed
- Documentation: branch and worktree hygiene — we commit directly to main
- Documentation: beta.6 state, the gate's missing production build, and the freeze
- Consent: stop calling a shipped advertising feature an open question
- Design: TOTP MFA for non-SSO accounts — the design, and its real cost
- Console: the plugin registry AGL-1867 asks for would govern the empty set
- Security: record what the tenant img-src reports actually said
Behind the scenes
- Dependencies: hold @base-ui/react at the 1.6 line until jest has PointerEvent
- Dependencies: bump five production minor/patch deps
- Console: pin the published /pricing table to the constants that charge it
- Tooling: baseline the unsubscribe page's two email-HTML colors
- Dependencies: bump @fontsource/roboto and roboto-mono in /apps/docs
- Dependencies: bump the docusaurus group in /apps/docs
- Dependencies: bump @eslint/eslintrc from 2.1.4 to 3.3.6
- Dependencies: bump firebase in the firebase group across 1 directory
- Dependencies: bump the actions group across 1 directory with 5 updates
- Dependencies: bump the nx-workspace group across 1 directory with 16 updates
- Tooling: assert legal-drift.yml refuses to no-op without its Drive variable
- Documentation: the two projects no repo-wide command could reach get real targets
- Dependencies: bump the mui-emotion group across 1 directory with 9 updates
- Dependencies: bump typescript-eslint to 8.67.0 in /cloud/functions
- Dependencies: guard the functions manifest's typescript alias and admin major
- Dependencies: bump firebase-functions to 7.3.2 in /cloud/functions
- CI: migrate the label config to the schema v5+ requires
- Self-hosting: drop the buildx action the repo's Actions policy forbids
- Console: the two stale-seed editor specs carry AGL-2334's host-role hook
- Self-hosting: assert what the tenant ROUTED the request to, not only its status
- Self-hosting: build both Docker images and serve one request through the tenant
- Platform: the branding guard names its pre-auth gap instead of omitting it
- Console: the cap suite can see the merge flag, and the ceiling comment does its own arithmetic
- Dependencies: bump the linters group, eslint 9 -> 10
- Dependencies: group typescript-eslint with its own scoped siblings
- Dependencies: bump eight dev tools from the dev-minor-patch group
- Dependencies: bump eslint to 10.8.1 in /cloud/functions
- Dependencies: guard the docs TypeScript major and keep react/react-dom paired
- Dependencies: @eslint/js catches up to the ESLint 10 we already run
- Dependencies: web-vitals goes to 6, and two lockstep pairs stop splitting
- Dependencies: web-vitals goes to 6, and two lockstep pairs stop splitting
- Console: the round-trip double gains the transaction the import now uses
- Dependencies: hold @babel/* majors while nx is on Babel 7
- Dependencies: move /apps/docs to React 19
- Dependencies: bump typescript to 5.9.3 in /apps/docs
- Dependencies: bump the next-react group across 1 directory with 4 updates
- Dependencies: bump @types/node in the types group across 1 directory
- Tooling: prove the commerce backfills are no-ops on a second run
- placeholder
- Console: the co-edit mirror's replay rule is pinned to what production does
- CI is a release gate on production until launch, not a firehose on main
- Accounts: the SSO publish gate is refused-on-purpose, both ends
- Sites: the plugin-fetch IPv6 fixture stops risking the two tests that matter
- Accounts: the locked-out notice is pinned to configuration, not to us
- Deploys: re-trigger the production build for console and tenant
Share this article
We're building the open web platform. Follow along as we ship — and tell us what you need.