← All updates

CHANGELOG

v1.0.0-beta.3

The register warns about a shortfall and never refuses. 290 changes in all: 49 new, 195 fixes, 2 reverted, 1 changed, 20 docs and 23 behind the scenes.

The Aglyn Team · Aug 2026

Released to production on August 19, 2026 at 10:57 CDT. See every commit in this release on GitHub

New

  • Tooling: the guards that ran nowhere get a home
  • Tooling: check:legal-drift gets a home — scheduled, loud, and gating nothing
  • Tooling: the back book's two money gaps get an audit that can come back red
  • Commerce: the register warns about a shortfall and never refuses
  • Commerce: the register warns about a shortfall and never refuses
  • Console: the clickwrap record answers what it was written for
  • Marketplace: a publisher can read why their own version was pulled
  • Console: the tax working papers get the reader the export exists to be
  • Commerce: a lost stock decrement stops being invisible
  • Console: stranded idempotency claims and unmatched refunds get readers
  • Marketplace: a publisher sees what a $1 listing costs to process
  • Console: the moderation reasons staff are made to type are shown to someone
  • Console: the audit window moves and the 365-day archive has a reader
  • Console: the Assist cost split by tier and by model reaches a screen
  • Console: a "new sign-in" email now has somewhere to send you
  • Console: the Assist corpus gets a consumer
  • Console: marketplace reports get a staff queue
  • Console: the named success manager is a person, and is copied
  • Console: the dataset export is the whole dataset, streamed
  • Commerce: stock movements get a history view, and referrers reach the aggregate
  • API: an integration can read the meter it is billed on
  • API: contact writes over /v1, metered against the audience band
  • Console: the data loop finally gets a reader
  • Console: the churn survey stops being write-only
  • Commerce: the Merchant Center feed URL is in the console, not in a comment
  • Console: the budget card says whether the budget has actually alerted
  • Tooling: the Assist key cannot reach the browser, and a guard that says so
  • Console: a plan change from the grid stops being invisible
  • Commerce: gift cards get a console — balances, liability, issue and void
  • Platform: every plugin console card gets a help affordance
  • Console: customers can report an issue, and it lands in Linear
  • Sites: a free site past its band is refused, ahead of the cache
  • Platform: the free plan's bandwidth band becomes enforceable
  • Sites: dwell time, so Avg. time on this screen can exist
  • Marketing site: the composer counts recipients BEFORE the send
  • Sites: the free tier gets its missing bandwidth brace
  • Besigner: the inspector says what is selected
  • Marketing site: popups can cap once per session, which is what we sell
  • Console: the DAM gives the asset back, tags as chips, and names its variants
  • Marketplace: a free listing says Free, and the listing page says what you get
  • Tooling: a ratchet stops the next hardcoded "Aglyn" reaching user-visible copy
  • Workflows: a run history that can say what happened
  • Inbox: the Inbox shows people and says where a submission went
  • Platform: the platform brand is configuration, not a literal
  • Console: the Sites list and dashboard header match the console mockup
  • Console: the DAM asset detail matches its mockup — download, tag chips, CDN line
  • Console: a form submission can be acted on, not only read
  • Commerce: the Orders screen now looks like the one we advertise
  • Console: /v1 can create the dataset it was only ever allowed to fill

Fixed

  • Releases: the prepare guard tests the version, not the subject line
  • Console: the clickwrap opt-out spec's relative import stops failing console:lint
  • Console: the subprocessor gate stops failing on a workflow that names the key
  • CI: raise the NX CI bound to 60 minutes — 30 canceled honest runs
  • Tooling: the back book's billing statuses get the exemption the guard asks for
  • CI: heavy RTL specs stop losing the scheduler race on a 4-vCPU runner
  • Shared libraries: five test targets with no tests, and one dormant passWithNoTests
  • Console: three more create-time quota gates count inside the transaction
  • Cloud functions: the five rules specs nothing has ever run join the runner
  • Tooling: the retired-color sweep enumerates git, not the disk
  • CI: bound NX CI at 30 minutes so one stuck spec cannot starve main for six hours
  • CI: the drift and census workflows judge a push per commit too
  • CI: state NX CI's concurrency so main is per-commit and only PRs supersede
  • CI: emulator guards group by commit, so a push is never evicted while pending
  • CI: a push to main gets a commit-scoped concurrency group
  • Console: regenerate the Assist docs index for the POS shortfall section
  • Tooling: the untaxed count separates forward exposure from dead history
  • Console: the reversal-label spec's firestore mock is a stable singleton
  • Marketplace: a revoked build stops itself, not the listing
  • Commerce: a subscription's platform fee is taken on items only
  • Console: the screen cap holds at the promotion and error-slot ends too
  • Console: the assistant uses the org's brand, at no extra cached prefix
  • Console: the idempotency-claims card gets its help, and the docs section behind it
  • Console: the recorded-not-priced rollup fields get a reader
  • Marketing site: the tablet/mobile gutter gap is an unfinished frame re-cut
  • Console: the Enterprise fee claim says WHICH sales are 0% again
  • Console: the audit Archive card gets the help affordance its guard requires
  • Console: the SSO password block reads the org's brand, at no extra read
  • Console: marketplace and payout copy names the entity, not a literal
  • Commerce: the restock prompt counts units the shelf lost, not units sold
  • Commerce: local pickup is a collection choice, not a license to ship anywhere
  • Documentation: drop the ignoreDeprecations value this app's TypeScript rejects
  • Documentation: the docs typecheck can run again, and the error it hid
  • Bookings: canceling a paid booking refunds the guest
  • Bookings: refunding a paid booking reverses the seller share
  • CI: the cron workflow skips a route that is not in the deployed tree yet
  • Bookings: a paid booking pays the merchant, not Aglyn's platform account
  • Console: custom roles say what they do, and the 51st one exists
  • Console: the success-manager card carries its own help affordance
  • Console: the dataset-csv re-export does not drag a client barrel server-side
  • Console: the two new staff surfaces satisfy their own coverage guards
  • Console: a domain with no certificate is not serving, and finishes itself
  • Commerce: the cancellation writer is text again, not a binary file
  • Commerce: a stock decrement takes a lock, so two sales cannot take one unit
  • Console: /api/hosts/create is rate limited, so a name grab is bounded
  • Console: the lockdown spec's navigation mock covers what the page reaches
  • Tooling: the container-width ban gets a detector that can fail
  • Tooling: the pricing reconciler reconciles before it writes, and can fail
  • Tooling: the color ratchet reads the file through the parser, not a scanner
  • Console: the screen-cap alert names the sites that are over
  • Platform: heading anchors reach every renderer that publishes them
  • Platform: widen searchIndex before reading its length
  • Sites: a missing URL serves the site's own 404 screen, still as a 404
  • Marketplace: the install warns before a future update eats a customization
  • Console: an agency past its 50th workspace can reach the rest
  • Plugin UI: the search empty state admits every truncation, not just paging
  • Tooling: the brand ratchet reads JSX text, via the parser not a scanner
  • Marketplace: a renamed publisher handle stops breaking every existing link
  • Console: user-visible copy reads the configured brand, not "Aglyn"
  • Plugin UI: a split summary's chevron is named from the label the renderer emits
  • Console: the refund-reversal recovery queue reaches a human
  • Tooling: a skipped console half stops reading as a passing wire run
  • Billing: the webhook's GA4 revenue beacons are scheduled, not abandoned
  • Tooling: a deferred @aglyn import in a spec stops reddening another app
  • Console: three specs become modules, and Stack takes justifyContent via sx
  • Marketplace: the publish gate cites its own issue, and stops breaking lint
  • Inbox: a lead row says where it came from and who it is
  • Console: the passkey refusal a real user gets now says what to do
  • Console: a rejection withdraws the offer and the realm trust
  • Sites: the kill switch reaches remote server bundles
  • Platform: the kill-switch document is adopted, not rebuilt
  • Console: the webhook health probe counts the collection it writes
  • Tooling: the DOMPurify dismissals get a guard, and a reason that is true
  • Console: the team-seat meter counts the invites the gate counts
  • Marketing site: campaign merge tags resolve against fields that exist
  • API: a /v1 create that fills a plan band is retriable again
  • Sites: the edit-context fallback stops letting a catalog shadow a blog
  • Marketplace: a partial refund pulls the publisher's share back
  • Commerce: the zone matcher reads codes it did not write itself
  • Console: the Enterprise card ticks only what the org actually holds
  • Commerce: delete the dead flat fee constant and two stale docblock claims
  • Console: the churn report reads the free text customers typed
  • Console: a fee-percentage override is capped at 100
  • Console: the customer audit feed fetches an ordered window
  • Commerce: the tax-ledger spec models the renewal's fee re-price
  • Marketplace: takedown and privacy reach every install door
  • Marketplace: a switched-off listing is not for sale
  • Commerce: a subscription's platform fee follows the plan
  • Console: the audit log reads the scope and actorEmail it is written
  • Console: every media-picker field accepts what its own Browse writes
  • Commerce: a non-numeric cart quantity stops locking the shopper out
  • Commerce: the packing slip and POS receipt escape what they interpolate
  • Console: the SSO enforcement spec spells four spaces as {4}
  • Tooling: the brand ratchet exempts generated docs prose by PATH, not directory
  • Billing: the discount-margin model sees Assist provider spend
  • Tooling: the brand detector reads a regex as a regex, not a string
  • Marketplace: every publish door asks for the publisher agreement
  • Commerce: the digital download limit becomes a limit
  • Commerce: a hand-issued gift card counts toward cost
  • Console: the cron-wiring guard unquotes a shell word
  • Console: the white-label tab title stops reading the platform brand
  • Security rules: the inventory ledger becomes append-only
  • Commerce: the supplier callback becomes one transaction, and a GET moves nothing
  • Console: the subprocessor gate classifies AGL-2240's two guard files
  • Commerce: the register and draft orders gate on an allowlist of roles
  • Console: a JIT sign-in spends a seat only when there is one
  • Console: the signal board header reads the configured brand
  • Commerce: two console help excerpts read the configured brand
  • Commerce: an unreadable org no longer cancels a healthy merchant's subscribers
  • Commerce: a platform fee that rounds to zero is charged, not dropped
  • Commerce: annotate the fetch mock so its Stripe overrides type-check
  • Console: every dataset-record writer meets both caps
  • Console: a Free org stops being offered a budget that cannot fire
  • Console: the branding save accepts what its own media picker writes
  • Commerce: a type-less product pays the PHYSICAL fee on every door
  • Console: the template cap becomes visible, and the quota class gets a guard
  • Commerce: a canceled order's payment link is expired, not left payable
  • Platform: the host-subcollection guard annotates Dirent[], not ReturnType
  • Commerce: two spec fixtures stop modeling shapes the product cannot produce
  • JSON editor: stop holding dependencies to unagreed strictness
  • Console: the done event stops counting the message twice
  • Console: the alerts stop reaching nobody quietly
  • Workflows: the inbound webhook run meets the monthly cap
  • Security rules: the order rule becomes the allowlist its own comment describes
  • Console: a free plan's resource caps survive concurrent creates
  • Commerce: a cart no rate can price is refused, not shipped free
  • Commerce: the abandoned-cart and restock passes run, and both queues are visible
  • Email: the brand logo resolves to a fetchable URL instead of a media: ref
  • Console: the usage sweep stops silently ending at 500 orgs
  • Console: the bandwidth help tip stops breaking two usage specs
  • Commerce: a non-finite money part no longer NaNs an order's totals
  • Console: roll up the month in progress, so a usage budget can speak
  • Self-hosting: the last two staff surfaces stop naming Aglyn's own resources
  • Self-hosting: burn down the ratchet's remaining host literals
  • Plugins: presets seed the spelling the panel can edit
  • Platform: an instance override replaces the alias it overrides
  • Besigner: the styles panel reads and clears MUI's sx aliases
  • Console: the site allowance reads Unlimited, not Infinity
  • Workflows: a workflow run reaches the table built to show it
  • Self-hosting: the standalone flag reaches the stage that actually runs
  • Console: a page's help icon opens the section it is standing in front of
  • Self-hosting: each site on the operator apex resolves to its own tenant host
  • Self-hosting: the SSO-domain refusal names the platform brand
  • Self-hosting: the CSP first-party set includes the operator's hosts
  • Besigner: the picker's global Escape stands down while the author is typing
  • Besigner: the raw JSON editor's Cmd+C/V/A edit text, not canvas elements
  • Self-hosting: the editor-presence hint and the signup helper read the workspace domain
  • Self-hosting: our own addresses and services stop being compiled in
  • Self-hosting: the tenant apex comes from config on every surface
  • Console: the naming sweep exempts the report-an-issue doc's forum link
  • Console: the checkout spec sends the Idempotency-Key its client always sends
  • Console: the form-submissions spec stops mocking a closed world
  • Console: regenerate the stale Assist docs index
  • Tooling: the brand ratchet counts TRACKED files, and re-baselines onto main
  • Sites: /api/host publishes an allow-list, not the host document
  • Sites: /api/screen publishes an allow-list, not the screen document
  • Sites: the fallback 404 is navigable
  • Documentation: the enterprise story stops contradicting the product
  • Marketplace: restore closers my conflict unions swallowed
  • Console: console:test was RED on main — six closed-world mocks
  • Console: the signup clickwrap links to the operator's terms, not Aglyn's
  • Console: the docs origin becomes one value under one name
  • Sites: our favicon leaves the browser tab of every white-label customer's site
  • Console: a webhook that failed mid-dispatch keeps its idempotency claim
  • Commerce: buy-now charges what it records, and a booking cannot be crowded out
  • Console: plugin page tabs print the nav label, not the URL slug
  • Console: the unread allowed fields refuse, the no-op claim is audible, the return shows all three buckets
  • Console: domain verification stops failing open on self-host
  • Console: the funnel downsell warns what the customer will be over
  • Console: three tier-visibility defects on the plan grid
  • Build: the build id moves to the bundler-agnostic env block
  • Commerce: a paid storefront order keeps its keys, its stock and its refund route
  • Console: the seller ledger reports the real payout and a refunded buyer can re-buy
  • Cloud functions: a self-host deployment stops calling and redirecting to our infrastructure
  • Sites: a self-host container serves published sites instead of 307ing every visitor to us
  • Console: a downgrade clears a pending cancel, and a failed swap stops lying
  • Console: a downgrade schedule no longer freezes and truncates the items
  • Marketplace: the refund orphan store closes the pre-purchase window
  • Console: the wizard stops handing out Aglyn's DNS records
  • Documentation: a self-hosted docs build must not report to Aglyn
  • Tooling: the release bump writes the lockfile too, and a guard reads it
  • Platform: TENANT_APEX is configuration, not our infrastructure
  • Platform: white-label email stops reverting to Aglyn
  • Console: the quota guard's docblock stops failing lint
  • Tooling: re-baseline the color ratchet after two refactors moved colors between files
  • Platform: retire totalSiteSizeMb rather than leaving a phantom control
  • Console: the help guard counts cards, not files, and the editor gets its own
  • Console: a super-only staff control stops offering itself to support
  • Console: every icon-only button has a name, and a guard that says so
  • Console: the traffic delta follows the range you picked
  • Console: a claim-less staff token stops resolving to super
  • Platform: white-label email stops being a from-name and nothing else
  • Documentation: a self-hosted docs build stops reporting its readers to us
  • Marketing site: a scheduled campaign now actually sends
  • Platform: the tenant apex is configuration everywhere, not just in the console's links

Reverted

  • Repository: back out two files my own commit swept in from the shared index
  • drop this branch's AGL-2143, superseded on main by 6e4d7938f

Changed

  • Platform: the revocation type stops claiming nothing reads its reason

Documentation

  • Documentation: record the session — gate blind spots, shared-checkout hazards, promotion state
  • CI: nx-ci.yml is ACTIVE — correct 13 comments that said otherwise
  • Bookings: paid bookings need Stripe connected, carry the digital rate, and refund
  • Marketing site: the container invariant is stock xl, not a 1280 column
  • API: the API overview catches up with contact writes and the usage endpoint
  • Analytics: the GA4 env verdict is stale and manufactured a false finding
  • API: the datasets page stops promising unenforced record and storage quotas
  • Tooling: the SSO sweep script stops denying that a writer exists
  • What's new: the batch reaches What's New, and a docblock stops lying
  • Self-hosting: four wrong rows, a missing page, a wrong contract
  • Console: four surfaces, and two stale pages
  • Media library: three shipped screens get written down
  • Marketing site: popup frequency, the recipient count, and when a schedule fires
  • Analytics: the traffic card, the growth figure and dwell time
  • Billing: bandwidth gets a page, and the meter gets a help tip
  • Staff console: coupons and the do-not-contact list get documented
  • Self-hosting: scope the Linear key to "Create issues" on one team
  • Documentation: the Marketplace walkthrough carries its shot list
  • Documentation: the Marketplace gets the beginner half of the ladder
  • Marketplace: the switchboard is Plugins, and the docs said both

Behind the scenes

  • Platform: classify the stock-reconciliation marker the catch-all leaves open
  • Platform: the success-manager mailer takes its self-host ratchet row
  • Console: the quota sweep's negative control names its one string mention
  • Console: the photo-route spec runs the real CDN-path check
  • Console: two webhook suites get the after() double the other eight have
  • Platform: the branding guard can see the four account-scoped senders
  • Console: the staff-mention guard counts the brand, not the literal
  • Console: the password-reset spec carries the brand and the cost meter
  • Console: five brand-aware card specs mock the branding hook
  • Tooling: baseline the one row AGL-2309 added while the sweep was running
  • Platform: the branding guard covers the tab title and stops blinding itself
  • Shared libraries: pin deepmerge-ts's contract at the vendor boundary that owns it
  • Console: the lockdown sweep reads a RETURN, not an import line
  • Tooling: re-baseline the brand ratchet, three stale rows and two corrected counts
  • Console: the content-entry mock stops being a closed world
  • Console: two usage-sweep doubles learn to page
  • Assist: two guards that were satisfied by the wrong thing
  • Console: the downgrade confirm gate is driven, not just declared
  • Rendering: a published document keeps its alias spelling AND its styling
  • Console: a besigner document source may not seed an sx alias
  • Tooling: assert the demo org is several businesses, not one cloned
  • Releases: regenerate the lockfile for 1.0.0-beta.2
  • Console: the Assist specs ask for the button, not the label

Share this article

The Aglyn Team

We're building the open web platform. Follow along as we ship — and tell us what you need.

Start building on Aglyn.

Free to start — design your first page and publish in minutes.