Repository navigation
[1.4.0] - 2026-11-04
The admin console, and relationship templates become products.
Admin
- An audited operations console (epic #500): roles, an action log, template authoring,
relationship repair, report regeneration, billing control, support inbox, broadcast and
platform health. Every write passes oneact()path that cannot mutate without a reason,
and a PII read records itself. product.adminis a template capability — a derived product inherits the console or
turns it off, and answers 404 when off.
Relationship templates as products (#533)
- Templates carry an owner and a visibility; public listing stays admin-curated.
- Relationship lifecycle
draft → pending → published → active → complete, with void/expired. - Per-relationship membership: 14-day trial from publish, one active trial per user,
invite expires in 7 days, unlimited assessment rounds while paid, read-only for both sides
when membership lapses. - Initiator CRUD: clone or start blank, edit Aspects, publish → trial or checkout,
one-click re-publish.
Onboarding
- First-run tour (driver.js, MIT) and a three-step counterparty wizard whose auth round-trip
keeps the invite token and returns to the same step.
Brand and system
- Icon set generated from the real mark, transparent ground (
E38guards it). - Palette: graphite
#37474Faction, cyan#08ADD5accent (surface-only — contrast measured). - New checks:
E39fails a dashboard→marketing link without a new tab;E35remains the
ancestor rule.
Commits
feat(nav)— the rail is a role-constrained menu, and the admin console leads its own group (#542) (#552)feat(templates)— a public Relationship Templates catalogue, and a home band that sells it (#544)feat(flow)— counterparty onboarding — a three-step wizard, and a next on every login hop (#538)feat(relationship)— #533 phase 3 — one trial, day-14 hard stop, read-only both sides, payment reactivates (#537)feat(member)— #533 phase 2 — initiator CRUD, publish, one-click re-publish (#535)feat(relationship)— template ownership, lifecycle, trial read and rounds (#533 phase 1) (#534)feat(billing)— claim the host on a checkout and refuse another host's events (#532)feat(admin)— broadcast to news signups (#507) (#531)feat(admin)— #506 support inbox — triage, Resend replies with visible failure, bounce state, throttle visibility (#530)feat(email)— #439b Resend inbound — signed webhook, idempotent email_event, bounce suppression (#528)feat(admin)— #502b template versioning — template_version, relationships bound to a version, immutable publish (#524)feat(admin)— #505 billing control — subscription state, test-mode banner, audited comps, server-side limits (#525)feat(admin)— #504 report operations — regenerate, PII-gated read, JSON + PDF export (#523)feat(admin)— #502a template authoring — a draft editor validated by zAssessment, saved through act() (#522)feat(admin)— /admin/health — the platform-health screen, every number naming its source (#508) (#520)feat(admin)— the five #503 actions, their floors, and a reason gate proven per operation (#517)feat(admin)— #503 relationship operations (#516)feat(admin)— /admin/audit — the filtered, read-only audit screen (#501b) (#515)feat(admin)— the role ladder, admin_invite, admin_action and act() (#501) (#511)feat(admin)— product.admin — the console's capability switch (#509) (#512)feat(db-verify)— V21 — a seeded instance readscomplete, or the run names it (#499)feat(onboarding)— the first-run tour's shell — driver.js, six steps, skip a missing target (#455) (#496)feat(onboarding)— the tour's "seen" mark is one column and one guarded route (#456) (#494)feat(assessment)— the Steps render on the instance screen, and the v1 release rows retire (#478) (#493)feat(demo)— move the worked example to /assessment/demo/[type] and delete the prototype group (#478) (#492)feat(release)— --check-limits re-derives a Known limits block from the tree (#489)feat(admin)— move the console to /admin/console, behind the allowlist (#478) (#486)fix(brand)— the lockup is 2rem in every expanded-header viewport (#549 follow-up) (#553)fix(help)— a sticky category rail beside the answers, and the person band beside the form (#549)fix(brand)— the chrome draws the full lockup again, and the auth mark is a seal (#539) (#547)fix(db)— serialise db:seed on the branch with an advisory lock (#529)fix(demo)— record the #464 dataset in the demo expectations — 33 records, 172 items (#526)fix(demo)— record the #464 template catalogue in demo:verify's counts (#527)fix(admin)— #503 a revoke is terminal — a resend refuses a withdrawn invitation (#519)fix(assessment)— the locked report's continue CTA opens the sheet, not the POST-only endpoint (#488)- feat(email) — the release note: one band, plain text first, sent once per tag (#548) (#551)
- feat(dashboard) — support, help and the library live in the console (#542) (#546)
polish(v1.x)— the ten owner UI items — icon size, auth gap, Gap scale, tokens, footer band, one measure, rails (#539) (#543)copy(home)— the register pass — title, practice band and boundary body (#545)copy(home)— the hero pitches a leader's outcome, not a practitioner's practice (#541)ux(rules)— a link out of the dashboard opens a new tab; a form surface carries no shadow (#540)chore(ops)— version env-sync with the policy lists, --confirm-production and --diff (#536)test(admin)— #503 the five repairs, their rung and the rollback (#521)docs(brand)— the icon docs name the transparent ground, and parity only moves on a path (#514)test(admin)— #503 the void and force-close screens, read as markup (#518)brand— the icon set is the AS mark on transparency, and E38 fails when it is not (#510)docs(release)— a seeded instance readingansweringis stamped, never reseeded (#498)docs(db-verify)— V11's comment says why a legitimate mark can still go stale (#497)docs(release)— a V11 is repaired by clearing the mark, and a rule change is what creates one (#495)refactor(v1)— delete the 95-row customer half of /v1, and prove /v1 404s (#478) (#491)docs(registry)— the answer sheet's inbound paths name the report's CTA too (#490)docs(release)— the v1.3.0 Known limit said the answer sheet had no link — it has one (#487)- fix(shell) — the surface registry calls create and answer live, because they are (#485)
docs(v1)— disposition all 118 /v1 items into docs/V1-RETIREMENT.md (#478) (#484)docs(release)— a merge deploys production, measured during the v1.3.0 cut (#483)- Stripe is test mode only — no
sk_livepath exists in the code; checkout cannot charge - Chat has no persistence —
/chatis a mocked surface with no tables behind it. - The Doubt gap kind is not computable —
opinionkeeps one value per kind, so the report - Neon-hosted auth mail is unverified — app mail sends through Resend and is proven;
- Role-constrained menus and focused-flow chrome are not in this release (#542 phase 2).
- An invite token is shown once (hashed at rest) — a lost link needs a re-publish.
- No merge queue (#442); merges stay serial because
mainrequires an up-to-date branch.
Known limits
- Stripe is test mode only — no
sk_livepath exists in the code; checkout cannot charge
a card, and the test-mode banner stays visible on purpose. - Chat has no persistence —
/chatis a mocked surface with no tables behind it. - The Doubt gap kind is not computable —
opinionkeeps one value per kind, so the report
states it rather than printing a number. - Neon-hosted auth mail is unverified — app mail sends through Resend and is proven;
a Neon-side SMTP credential was rotated and its replacement is not yet confirmed by a reset. - Role-constrained menus and focused-flow chrome are not in this release (#542 phase 2).
- An invite token is shown once (hashed at rest) — a lost link needs a re-publish.
- No merge queue (#442); merges stay serial because
mainrequires an up-to-date branch.