116 Commits
Author SHA1 Message Date
cgalo5758 b7a0e15574 Record Stripe environment on mappings and verify ids under the current
key
2026-09-20 01:51:45 -05:00
cgalo5758 0caed6e905 Harvest the exploration notebooks into the docs
A survey of the twenty notebooks on disk found general facts that no
tracked page stated; the maintainer struck the weak rows and the rest
are written into their owning pages in each page's own words. The
design-system page gains the hidden-navigation figures that replaced a
dangling survey pointer, the reason the anatomy is parts and lint, the
record-table grouping and single-tint rules, and when a surface earns
row editing. The first-contact process gains a code-verification phase,
the transcript lane for models without vision, the three kinds of
honesty-audit drift and the click-path guardrail. The operator
conventions gain guards-before-writes, error state over empty state,
copy that states the real effect, toasts that report counts and the
PostForm rule. The Stripe, FedWiki, identifiers, IA, testing, model and
environment pages each gain their facts, the integration guide stops
telling authors to hand-write a page title, issues.md logs the
placeholder security contact, milestones.md records the Codeberg terms
clause and CONTRIBUTING.md notes that the module path is the forge URL.

One claimed fact was checked against the code and not written: the
mass-mutation preview does not run the commit loop in a rolled-back
transaction.
2026-09-19 19:47:33 -05:00
cgalo5758 660485d9b8 Make status/explorations a local notebook git ignores
The exploration directory held 245 tracked files, and one week's
notebook had grown to 28M of captures, per-run CSS copies and model
logs, so every change ended with an argument about what to prune. It is
now a local lab notebook: git ignores it, its tracked files are
untracked, and no tracked file cites a path under it, because another
clone does not have it.

Every live citation is rewritten so the fact stands in the sentence:
the docs pages, AGENTS.md, four main specs, one Go comment, issues.md
and milestones.md. The operator IA page gains the landed IA revisions it
used to point at, and the UX rubric moves to docs/first-contact-rubric.md
because the process requires it. Archived changes, status/archive,
status/log and design/ keep their old paths as frozen history; the
design/ ones are logged as an upstream issue. MAINTAINING.md and the
status README describe the notebook and the harvest that replaces
pruning.
2026-09-19 19:46:52 -05:00
cgalo5758 f8a3478f2a Rebuild the entitlement set Rules surface as a staged batch
The Rules section is one record table grouped by kind, Limit then
Boolean, on fixed columns, edited in place: Edit opens a row's controls
in their columns, Add rule opens a dense row above the table, and every
change is staged into a tray that lists the deltas with Undo and applies
them as one rule-change act. The reduction policy is a column of the
rule beside its limit. History shows counts only. Group rows are a quiet
heading rather than a divider, the maintainer's pick from four rounds of
outside-model ideation.

Dense rows align to the top and render each error under its control in
every form family (design D16), replacing the below-row error block; the
forms library gains the batch form (rows plus one tray) and the RowField
dense and label-hidden options. Migration 00019 records the governing
reduction policy on effect rows.

Archive staged-rule-changes with its spec updates (entitlement-set-
management, entitlement-set-history, entitlements, form-library,
form-conventions, ui-quality-gate). Screens accepted 2026-09-19.
2026-09-19 19:46:09 -05:00
cgalo5758 3727ff31d8 Add entitlement set rule change ledger and preview flow
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.
2026-09-15 03:53:28 -05:00
cgalo5758 fc6b0906ae Define entitlement set rule propagation and history 2026-09-14 18:37:06 -05:00
cgalo5758 782ca8f326 Derive Stripe mode from API key and refine disabled controls
Derive Stripe test/live mode from the API key prefix at boot, failing on
unrecognized prefixes, and drop the separate `stripe-mode` config key.

Refine disabled controls to render through the shared `disabledControl`
part with the not-allowed cursor, and add a lint rule refusing
hand-rolled disabled buttons.

Adjust plan cards to offer no purchase control on free rungs, fix bound
checkbox Bool handling, and rename "Public/Private" to "Listed/Unlisted"
with enhanced readiness verdicts.
2026-09-13 16:59:12 -05:00
cgalo5758 412b7f67d8 Improve warning text contrast and document production findings 2026-09-13 16:56:01 -05:00
cgalo5758 6091899201 Record production deployment of Slice 3 fixes 2026-09-13 16:56:01 -05:00
cgalo5758 a5f3629cf1 Record the Slice 3 walk, the cutover ledger and the resources-by-holder issue
- status/issues.md: the 2026-09-11 production walk (ten findings,
  four resolved by slice3-walk-fixes, two design explorations), the
  cutover gaps, and a new issue: the organization composite shows no
  resources and resource pages cannot be asked which belong to an
  organization.
- status/milestones.md: 10d Slice 3 deployed 2026-09-11, gates G2 to
  G8 open.
- status/explorations/launch-2026-09/: the Slice 3 runbook recovered
  from the planning session with each gate's verified state.
2026-09-12 01:16:17 -05:00
cgalo5758 3283df19b1 Move account menu into mobile rail drawer
Below lg the top bar now holds the brand and one toggler; the account
items render in the drawer as a second, labelled list from a shared
partial, so both surfaces cannot drift. Desktop unchanged.
2026-09-09 22:57:26 -05:00
cgalo5758 ea4fee18b6 Fix five findings from security audit run 2
- Rotate the session token at the OIDC callback and restore the full
  lifetime; cap pre-auth sessions at 15 minutes and write no session
  for bare anonymous requests
- Treat db-dsn as a secret: accept db-dsn-file, log only host, port,
  database and user, and never echo a malformed DSN in an error
- Guard the logout callback with a state cookie so a forged visit
  cannot end a live session
- Collapse FedWiki site actions on a foreign tenant's domain to the
  not-found answer, as for a domain that does not exist
2026-09-09 20:53:31 -05:00
cgalo5758 0b28a9dc29 Remediate security audit findings
- Replace gorilla/csrf with net/http CrossOriginProtection
- Require valkey-password and add TLS options for session store
- End session at /logout and revoke refresh tokens
- Re-derive identity and roles from provider every five minutes
- Process each Stripe webhook event in its own Temporal workflow
- Give each outbox entry its own workflow with Temporal retries
- Guard against stale Stripe events with provider timestamps
- Derive transport security from base-url scheme
2026-09-09 13:25:43 -05:00
cgalo5758 fe19ee415c Add CLA and SPDX headers, fix docs
- Pin Dockerfile to Go 1.23 to match go.mod
- Record README front-door audit findings
2026-09-07 21:32:14 -05:00
cgalo5758 074702c8bc Seed ledger demo via shared grant act helpers
Extract ExtendGrantTx, RevokeGrantTx, and ExpireGrantTx into
internal/entitlements so the operator handlers, expiry activity, and
demo seed all run the same conferral path. The seed plays a five-grant
history on Carlos's org; pin-timestamps now uses dense-rank offsets
and transition list ordering ties break by transition_id.
2026-09-07 00:51:49 -05:00
cgalo5758 fa169dca3b Add purchasability status to products list
- Refine tier changes ledger: fold supersession pairs, humanize reasons,
  carry grant notes
- Fix OAuth token expiry to use wall clock
2026-09-06 23:31:12 -05:00
cgalo5758 8c85983758 Align operator overview with page anatomy parts
Align the landing surface with the shared parts: sectionHeader for the
regions, the new readout part for every headline count, flush lists for
the System sheet, chevron-marked linked cards, and a boxed paginated
activity feed. Add the raw-section-title lint rule and classify the
remaining hand-written titles; archive the overview-consistency change.
2026-09-06 19:50:36 -05:00
cgalo5758 88db730fcc Add dual licensing and SPDX headers
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.
2026-09-06 02:29:42 -05:00
cgalo5758 bee07eb946 Update M10 status and bundle grants ordering issue
Mark 10k closed 2026-09-03 and update the M10 next steps; bundle the
Grants list ordering fix into the pending tier-changes-ledger change.
2026-09-06 01:44:08 -05:00
cgalo5758 d47c47ef0f Make control type decide dense form width
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.
2026-09-06 01:26:08 -05:00
cgalo5758 e581bf81c3 Add typed config keys and config CLI
Parse every config value through a single declared type at save, boot,
and validate, and expose the settings seam from the terminal so
operators can list, set, clear, and validate overrides without SQL.
2026-09-05 17:47:04 -05:00
cgalo5758 9ff516ba95 Introduce the forms library and migrate all forms
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.
2026-09-05 03:16:45 -05:00
cgalo5758 8608c871de Apply the acceptance fixes and archive the change (10k.4)
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.
2026-09-03 17:00:14 -05:00
cgalo5758 7dc5a8e484 Migrate frontend from htmx 2 to htmx 4
Vendor htmx 4.0.0 and complete the migration with no compat shim:
mark inherited attributes with :inherited, rename hx-disabled-elt to
hx-disable, and drop hx-disinherit. Update static scripts to the
colon-separated event names and detail.ctx shape, and move error-swap
suppression to declarative noSwap config so 422 swaps natively while
403/5xx responses leave the target unchanged.

Handlers that branch on HX-Request now declare Vary: HX-Request. Add
lint guards for htmx 2 residue: hx-disinherit, camelCase event names,
and htmx-2-compat references.
2026-08-31 20:00:43 -05:00
cgalo5758 ee23d31c97 Complete anatomy sweep across all surfaces
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.
2026-08-31 18:11:09 -05:00
cgalo5758 568383b55e Reorganize status docs and add identifier docs
Move settled investigation records into
`status/explorations/<topic>-<date>/` with README indexes,
promote durable conventions to `docs/`, and add
`docs/identifiers.md` plus upstream Doc 46 person-name
provenance documents. Update cross-references and archive
resolved issues.
2026-08-29 21:15:31 -05:00
cgalo5758 dd3962990b Adopt entity keys and add invoice numbers
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.
2026-08-29 20:12:04 -05:00
cgalo5758 8e3c68c6be Make UI surfaces honestly reflect system state
- 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
2026-08-23 01:45:52 -05:00
cgalo5758 70617c0fa6 Remove plan safety and architecture docs 2026-08-22 18:58:59 -05:00
cgalo5758 ad7a219adf Enforce schema and boot invariants
Enforce 10j's verified gaps (schema-hardening change):

- Migration 00010: partial unique indexes for one default pool and one
  primary assignment per workspace, plus CHECKs pinning
  pool/provider/subscription vocabularies and provider lifecycle
  timestamps.
- Workspace creation shares a transactional provisioning function;
  extension validates its target pool; last-tier deletion of a defaulted
  ladder is guarded; signup completes plan-less on a broken ladder.
- Boot asserts integration slug parity and validates declared config
  enums; Stripe invoice amounts are range-checked; domain cancellation
  runs a final evidence probe; rule authoring is additive-only.
2026-08-22 18:02:46 -05:00
cgalo5758 efe3f1528d Restrict member surfaces to published products
Add lifecycle_status = 'published' to the public-catalog queries
(plans and add-ons listings) and reject checkout before any Stripe
call unless the product behind the price clears the shared member
gate (published + active + public). The currently-enrolled ladder
rung stays renderable even if its product is later drafted or
retired, fetched directly so members keep seeing what they are on.

Introduce a single evaluateMemberGate definition shared by the
catalog paths and the operator readiness panel so the surfaces
cannot disagree about what is publishable for members.
2026-08-22 12:58:05 -05:00
cgalo5758 ac2760a0fe Add model catalog cards and ratify Doc 44
Write the eight domain-model cards under `docs/models/`, mark M10 10i
Done, and update the design docs to v16. Also records Doc 44, which
ratifies Decisions 129-133 as amended, and the Doc-39 conformance
check that satisfied its gate.
2026-08-22 03:11:19 -05:00
cgalo5758 706c177847 Add model cards catalog
Introduce `docs/models/` with the catalog index and its first card
(product-catalog), recording invariants, dimensions, and drift traps
per the Decision 141 documentation division. Add the model-cards
openspec change (proposal, design, spec, tasks) and sync the design
docs to v15: product kind taxonomy dissolved (Decisions 134–139),
Decisions 140–141 ratified, and product/pricing helpers updated. The
catalog is the single descriptive home for as-built models.
2026-08-21 18:47:49 -05:00
cgalo5758 494f25860c Stabilize demo operator walkthroughs
Configure the personal org-type default ladder and floor vacant pools so
the seeded dataset survives grant revocation. Let the modal mechanics
test
fall back to plan-ladder action triggers in full-suite order.
2026-08-01 18:53:28 -05:00
cgalo5758 a43a78900b Handle walkthrough element lookup errors 2026-08-01 04:40:48 -05:00
cgalo5758 d45a51d2e8 Profile-gate FedWiki and Discourse in the test stack
Put the fedwiki chain (init, render, farm, caddy) behind a fedwiki
compose profile symmetric with discourse's; the default composition is
neither, selected via COMPOSE_PROFILES in test/.env, so a default stack
no longer binds host 443.

Guard every script and walkthrough on service presence: shared
skipUnlessIntegrationEndpointReachable helper, seed-stack presence
checks (also repairing its unsourced .env and container-native render
invocation), generic root-owned testdata reclaim in teardown, discourse
coverage in verify-stack-isolation, and fedwiki's 8090 base in the port
probe.

Update stack docs and finalize status bookkeeping for all three
changes; archives the test-stack-integration-profiles change.
2026-08-01 04:14:05 -05:00
cgalo5758 eaf6e01172 Document FedWiki parity decisions
Record symmetric integration profile gating, ConfigSpec-generated init
scaffolding, and provenance for the core domains target rename.
2026-08-01 00:41:04 -05:00
cgalo5758 8e7e0dd04d Harden container, OIDC auth, and error handling
Run Docker runtime stage as non-root user app (UID 65532).

Add styled full-page 404/500 error rendering for navigation requests
while preserving plain-text responses for HTMX partials.

Reuse recent unconsumed OIDC login state to avoid state mismatch on
parallel login hits, and merge resource_access in role extraction.

Re-level template headings, add autocomplete tokens, and resolve
catalog resource display names.

Self-label test-stack secrets and document CSRF secret rotation.
2026-07-31 23:27:15 -05:00
cgalo5758 11eac0a430 Document M10 dashboard and domains progress
Record completed front door, custom domain, and operator dashboard work.
Archive resolved domain issues and add the overview metrics and mockshot
log.
2026-07-27 02:50:15 -05:00
cgalo5758 ce3668d59e Refine operator overview metrics and styling
Replace domain claims with open invoices, show monthly recurring
revenue,
count team organizations, and add more informative trend captions.

Use standard bordered cards and add a README screenshot with reversible
sample-data tooling.
2026-07-27 02:44:55 -05:00
cgalo5758 fea1afb1f1 Hide force-release for domains in use 2026-07-26 19:33:36 -05:00
cgalo5758 0affda70bd Centralize the external-claim entitlement gate in the registry
Registry.ClaimExternal now enforces the plan gate itself via an injected
domains.ExternalClaimGate (pre-lock, typed refusals), so every entry
point — and any future consumer — inherits it from the allocation API.
One constructor in internal/server builds the gate from the entitlements
querier and connect target; it is injected into the member-facing
registry constructions in server.go and fedwiki.go and drives affordance
rendering on both surfaces. The duplicated helpers and resource-key
constants in fedwiki web and member_domains are gone; fedwiki no longer
reads entitlement tables for this gate at all.

Archives the change with the domains-registry spec delta (enforcement
location is now requirement-level: registry-inherited, surfaces derive).
Closes the entitlement-gate placement debt in issues.md; files the
separately-discovered operator force-release dead-end affordance bug
that a placed claim exposed in the domains walkthrough.
2026-07-26 03:33:16 -05:00
cgalo5758 d3b222a446 Dissolve the member domains surface into point-of-use
Domains leaves the member nav everywhere; GET /domains 302s to the
dashboard and domains.html is deleted. Claims are managed where they are
used: the fedwiki sites card embeds the core claims partial, a
server-conditional dashboard notice carries pending verifications (the
durable re-entry now that the page is gone), and the member_domains
partials retarget to 'closest .domains-surface' so multiple hosts coexist
on one page. Adding an external domain starts only from the create form;
the fedwiki banner slims to verified-unplaced one-click creates, since
the notice and embedded section own the pending state.

Verified at the surface end-to-end (stack + Chrome): nav absence,
redirect, notice lifecycle through claim-cancel, and cross-host swap
isolation with two claim views open. Archives the change with spec
deltas synced (domains-registry point-of-use rewrite, fedwiki-sites and
member-dashboard additions); files the entitlement-gate placement debt
in issues.md; adds the repo verify skill.
2026-07-26 03:10:23 -05:00
cgalo5758 c4bb1ba585 Harden domain claim expiry and carving
Sweep stranded pending claims at boot and on a Temporal schedule while
preserving evidence-based abandonment semantics.

Apply occupancy and name-policy checks to carves by operator-root owners
without affecting direct operator placements.
2026-07-25 04:10:34 -05:00
cgalo5758 30b8250cf5 Pause integration schedules when disabled
Resume only app-paused schedules so operator pauses survive restarts.
Apply dormancy handling to Discourse and FedWiki.

Remove the unused pool-scoped grant route, hide internal transition
errors, and update specs and tests to use the canonical grant endpoint.
2026-07-23 01:38:45 -05:00
cgalo5758 eb438cf76c Harden operator walkthrough preconditions
Render grant extension controls only for active grant-backed provisions.
Scan for valid walkthrough subjects and skip when Discourse is
unreachable.

Add a fresh-stack target and document the supported e2e workflow.
2026-07-23 01:18:25 -05:00
cgalo5758 93bf698a56 Add ladder rank structural validation
Report malformed sequences on the validation page and topology health
strip. Normalize fulfillment and Stripe webhook fixtures to preserve
contiguous, zero-based ranks.
2026-07-23 00:52:49 -05:00
cgalo5758 259c935981 Unify operator integration management
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.
2026-07-23 00:14:21 -05:00
cgalo5758 296236a721 Add operator-managed integration settings
Persist non-secret ConfigSpec overrides in core and apply them at boot
ahead of environment values and defaults. Validate typed and enum
values,
show pending restart state, and remove Stripe's unused provider config
table.
2026-07-22 22:17:58 -05:00
cgalo5758 5fb9ba8dfe Recover from stale Discourse user links
Re-resolve members absent after batch adds by forum user ID. Update
renamed
usernames and quarantine deleted users so they cannot block healthy
group
delivery. Align the fake with Discourse's partial-batch semantics.
2026-07-22 14:02:40 -05:00