Add an append-only ledger of entitlement set rule changes with per-pool
effect rows, a preview-and-commit rule change flow, and an automatic
drain that settles deferred recomputations. Rules gain a tier reduction
policy, resource keys declare over-limit behavior, and the materializer
now lowers limits when a rule stops applying.
Add entitlement set rule change ledger and preview flow
Add an append-only ledger of entitlement set rule changes with a
preview-and-commit operator flow. Rule writes now go through an enclosed
`core.commit_rule_change` function that files an act row and one
obligation per carrying pool, with a drain workflow settling deferred
recomputations. The preview dry-runs the materializer with a rule
overlay and renders per-pool buckets, reduction-policy disclosures, and
provider over-limit consequences. Materializing transactions take a
shared advisory rendezvous that rule changes hold exclusively, enforced
by a possession assertion. Add History and Entitlement changes surfaces,
a rule-less warning on five product-selection surfaces, and a
`tier_reduction_policy` column that gates FedWiki parking.
Introduce a commercial license option alongside AGPL-3.0-only, require a
CLA for contributors, and document the terms in COMMERCIAL.md and
NOTICE. Add a script to stamp SPDX headers on Go files and apply it
across the tree.
Width becomes a one-rung step from the control's natural fraction,
and invariants bound the ladder. The grant's free text is renamed
to GrantNote, and both grant ledgers show it as a muted note line.
Every form on both surfaces is now a declared FormSpec in
internal/forms, rendered through the shared form part and parsed
by its handler through the same declaration. Create and edit
share one field list, refusals answer 422 with values carried
back, and layout, buttons and errors come from one part.
Also adds the form registry with its invariant and route-mapping
tests, the raw-form, filler-copy and Go em-dash lint rules,
declared action triggers, and the capture-coverage cross-check.
The forms-library change is archived under
openspec/changes/archive/2026-09-05-forms-library.
Six review rounds on the September walk's 40 findings, executed as the
acceptance-fixes change (design D1 to D31) and archived as
openspec/changes/archive/2026-09-03-acceptance-fixes/ with its 20
deltas synced into openspec/specs.
Shell and conventions: the location trail on every page rooted at the
surface; click-opened help popovers; buttons by role with the pressed
rule retired and tertiary openers with a rotating plus; the code chip
and white card headers; Remove versus Delete on row actions.
Operator surface: three overview tiles, one Integrations card, the
getting-started banner as the first instance setting
(core.instance_settings, migration 00015); record creation on its own
page for products, entitlement sets, and plan ladders; Visibility as
one Public checkbox; the Stripe provider page; the plan ladder
validation page retired and ranks ascending; org-types default change
with dispositions, Discard, and the settle-cloning fix; the rebuilt
composite billing card; hints instead of placeholders; the person page's
identity-provider glyph on its field labels; non-UUID ids answer 404.
Found by review and fixed: a session now ends when its person no longer
exists (the foreign-key failure on a ladder reorder after a snapshot
rebuild); the CSRF cookie lives as long as the session and its toast
says the page is out of date; htmx's settle delay is 0 app-wide.
Verification: unit suites, browser walkthroughs, the screens baseline
(31 screens, accepted), and Lighthouse at 100 on both widths, recorded
in docs/operator-a11y-baseline.md. Three stale issue entries archived.
Rebuild every operator, member, and integration template on the shared
page-anatomy parts, empty the lint allowlist, and move the confirm modal
into both shells. Replace back links with location trails and make row
identifiers the primary link. Make screen captures deterministic by
resetting the app database from a pinned demo snapshot. Send the logout
id_token_hint only while valid.
- Add shared ui_*.html parts (pageHeader, sectionHeader, statusBadge,
emptyState) parsed into every template set
- Add anatomy lint rules with a shrinking allowlist and screen-coverage
check
- Add make screens capture harness with contact sheets and baseline diff
- Compose member and FedWiki regions server-side so pages arrive
complete
- Rebuild Domains and Integrations on the parts as pilots
Extract the top bar and account menu into shell_topbar.html and the
member rail into shell_rail_member.html, backed by a single
server.Shell value. Move session controls into the account menu, add
the mirrored Operator panel/Member dashboard surface switch, and turn
the rail into an offcanvas drawer below lg with shell.js closing it on
navigation. Update docs, specs, and tests.
Unify application shell across both surfaces
Extract the top bar and member rail into shared partials and introduce
server.Shell as the single data value for page chrome. Move session
controls into an account menu, make the rail an offcanvas drawer below
lg, and add the mirrored surface switch.
Replace the entity slugs on organizations, workspaces, resource pools,
and
plan ladders with nullable `key` columns and add keys to products,
prices,
and entitlement sets. Rename `providers.slug` to `provider` and add
partial
unique indexes for system and org role names.
Assign invoice numbers per billing account from a gapless transactional
counter; Stripe's number moves to the invoice mapping as an external
reference.
Seeds, fixtures, and the operator lookup address rows by key, and the
returning-login resync no longer blanks a display name when the IdP
sends
no `name` claim.
Move sub-surfaces into their sections: billing views get a pill row,
org types a header button. Replace inline IdP handoff copy with an SVG
icon and tooltip, add help icons to dense form rows, and delete the
registry-driven sidebar nav plumbing. Update specs and tests.
- Restructure operator sidebar into a flat task list with indented
children; fold plan topology into plan ladders
- Expand member catalog non-plan section to all published non-tier
products; require recurring Stripe-mapped prices for purchase
- Add operator domains placements and terminal-claims ledger; redirect
/domains to the FedWiki Sites Domains anchor
- Apply canonical vocabulary and chrome/form conventions; migrate seeded
FedWiki Sites display name
Implement the ux-first-run change: a state-derived setup checklist on
/operator/setup with a landing region that recedes once required steps
are done, and empty states that distinguish blocked from empty across
operator and member surfaces. Also add production deployment and
environment reference docs, plus a config-key completeness test.
- Add deployment-name branding to titles, mastheads, and OG tags
- Share one grant delivery-state query with lineage across grants
surfaces
- Show pool status/usage, org owners, and config readiness
- Make billing views projection-aware with recency and sync vocabulary
- Guard FedWiki creation without domains and render route-aware 404s
List every provider kind with direct settings and admin links, move
FedWiki
under the integrations route, and add in-shell operator 404s.
Report sync health from Temporal schedule executions and clear one-shot
settings feedback parameters after display.
Render generic HTMX card shells from integration declarations. Move the
FedWiki UI into its partial, add Discourse forum status, and label
member
entitlements with provider attribution.
Deliver forum posting entitlements through managed group membership with
identity linkage, periodic reconciliation, webhook handling, and an
operator mapping surface.
Include fake and live test environments, setup documentation,
migrations,
and end-to-end coverage.