Skip to main content
Changelog

What's changed in the system

Token, component, and pattern changes so contributors can keep up without spelunking through commits.

Latest v0.17
v0.17 alpha
Today

A two-agent audit of busted features and missing links, and the fixes for everything it confirmed.

Added

Concept home v2 (/v2, noindexed) — a 'warm workroom' direction synthesized from three style references (7shifts, Notion, Aboard): warm bone canvas, a single indigo pill CTA per viewport, the five module hues as a sticky-note pastel card cast replacing shadows, 84px tight-tracked editorial display type with a hand-drawn amber underline and a pill-marked word, an audience marquee ticker, a full-bleed ink band with hue-highlighted phrases and before/after pairs, tilted pastel product plates framing real FeaturePreview mockups, scenario quote cards, and 99px pill buttons throughout.

Fixed

High-severity: cross-org 'We've shared' links no longer 404 for Share items (they special-case to the Share list like the inbound list always did); resending an invitation keeps its group assignments (the RPC upsert was overwriting them with []); and an org can no longer lose its last admin — changeMemberRole blocks self-demotion and demoting the final admin, with the self controls disabled in Members and Team.

Fixed

Invitations now reach existing members: the resolver checks pending invitations before the single-org redirect (with a 'Not now' direct-to-org exit on the accept screen so it can't loop), the multi-org picker shows a pending-invitations banner, and declined/revoked invitations appear as 'Recent invitation responses' on the Members page instead of silently vanishing.

Fixed

Quiz scores are actually recorded (stored as a percentage on completion) and surfaced as a per-member 'Quiz avg' column on course Completions; broadcast acknowledgments ('Got it') now show next to the read rate via a new ack_count in broadcast_receipts; pinned broadcasts float to the top of the list like Discuss and Share.

Fixed

Global search: people link to their profile page (not the directory), and lesson titles are findable (shown as 'Lesson · {course}' in the courses group). Audit log renders labels for branding, setup-launch, and invite events instead of raw action strings. Notification mark-read rolls back with a toast on failure instead of silently reverting.

Changed

Demo parity on the product: the topbar command trigger became the demo's wide centred search field ('Search people, threads, decisions…' + shortcut hint); draft rows adopted the demo card anatomy (module icon tile on the soft hue, module pill, context line, 'edited …' meta); discussion rows show a 'with …' participant avatar stack (unique repliers, capped at 3 + overflow); and the Discuss page gained the demo-style left rail — categories and tags with counts as filters (compact chips on mobile) — with the list re-ordered by latest activity so threads with fresh replies rise (pinned still first).

Changed

Demo tree cleanup: 40 hardcoded /demo/-prefixed hrefs (module routes, sidebar, topbar, command menu, mock reminders/activity) became bare paths — they only worked via a proxy redirect safety net. The marketing feature pages' 'Try it live' CTA now uses the absolute demo-host URL like every other cross-host link. Dead createGroup/updateGroup server actions removed (saveGroup is the one write path). The design-system landing's version badge is finally live data — it reads the latest changelog entry and links here (it had said 'v0.1 alpha' since the beginning).

v0.16 alpha
Today

The admin setup assistant — a 7-step guided onboarding that maps straight onto the real access model, plus group leads.

Added

Setup assistant at /[org]/setup (admins only) — Organization → Structure → Groups → Roles & access → People → Review → Launch, rendered inside the app shell with a step rail (sequential unlock, free back-navigation), a mobile progress bar, and a sticky footer (Back / Save & exit / Continue). Everything lives in a per-org localStorage draft; nothing writes to the database until Launch, except Step 1, which edits real org fields through the same actions Settings uses. Soft-gated: a home-dashboard card (start / resume / finish-inviting states) and a Settings → General link — no forced redirects, so first login is never blocked.

Added

Structure templates compile to the real model — six structure cards (leadership, board & committees, departments, projects, chapters, partners) seed draft groups with a real group type and per-module tiers, ordered by the org type picked in Step 1. Group cards use operating presets (Managed / Collaborative / Information / Custom) that compile to view/participate/manage tiers; Custom exposes the same 4-state tier chips as the group dialog. The Everyone card is pinned, maps to the org's default group, and can't be removed.

Added

People queue + Launch — invitees are queued (role cards, draft-group chips, per-group lead stars, CSV import reusing the members-import parser, deduped against members / pending invites / the queue) and sent only at Launch through the normal invite flow, so role and groups ride along on each invitation. Launch is one re-runnable server action: groups are ensured by name (tiers updated, rosters untouched — never duplicated), a default group is guaranteed, then either the setup team (admins + leads, recommended) or everyone is invited. Un-sent people stay queued and the home card switches to 'Finish inviting your team'.

Added

Review + Preview-as — readiness warnings (single admin, module-less groups, Everyone-only people, lead-less groups) with jump-to-step fixes, the draft sliced by person and by group, and a Preview dialog that runs the same pure computeModuleTiers the app enforces with — so 'what will Jordan see?' is answered from the real access math, not a mock. The Roles step's capability matrix is likewise evaluated through can(), so it can never drift from enforcement.

Added

Group leads — the group_members role enum ('lead') is now actually written: the group dialog's roster gained a star toggle (with a 'Led by …' line on group cards), the wizard assigns leads for existing members and flags invitee-leads to confirm after they join, and saveGroup/Launch persist them. Org profile fields (type, team size, website, time zone) were added to organizations and to Settings → General.

v0.15 alpha
Today

Course sections, a local dev sign-in, and a full-app UI consistency wave driven by a visual + code audit.

Added

Course sections — an optional grouping layer between a course and its lessons (Course → Section → Lesson), backed by a course_sections table + nullable lessons.section_id. New shared CourseOutline component: collapsible per-section groups with done/total counts, continuous numbering, and a dense variant used as a left 'Course contents' sidebar on the lesson reader (mobile gets a collapsible outline above the lesson). Composer edit mode became a grouped editor: add/rename/reorder/delete sections and move lessons between them. Sections are presentation-only — completion and certificates stay lesson-based.

Added

Dev quick sign-in on /login (development builds only) — mints a magic-link token via the admin API and verifies it in place, so local testing signs in with one click and nothing round-trips through the production redirect URL. Triple-gated: stripped from prod builds, localhost-only, and requires SUPABASE_SERVICE_ROLE_KEY in .env.local.

Added

Theme toggle in the real app's account menu — dark mode was fully built (tokens, provider) but unreachable outside the demo. Also: visible Edit buttons on course + broadcast detail headers and a Completions link on the course header — primary actions no longer live only inside ⋯ menus (new convention: menus are for rare/destructive actions).

Changed

Consistency wave from the audit: EmptyState adopted on 14 list surfaces that had ad-hoc grey Cards (small inline empties get one minimal style); formatRelative now returns the complete phrase ('3w ago', absolute after a year) and the 28 call sites that appended ' ago' were cleaned ('Jun 5 ago' / 'just now ago' bugs); record-detail titles normalized to one size; eyebrow labels to one token (text-xs); rounded-xl panels aligned to the Card primitive's rounded-lg; a shared useActionRun hook replaced the copy-pasted run()/act() transition helpers where they were true duplicates (5 of 12 — the rest carry real behavioural differences to preserve); pending-state labels on network/group actions.

Fixed

Focus-visible rings on raw buttons that had none (List/Board toggles, reorder arrows, dismiss buttons, sidebar collapse, topbar); Share folder-rail menu no longer hover-only (was unreachable on touch); category tab rows wrap instead of clipping; '1 views' pluralization; lesson kind badge no longer reports 'Link' for readings that end with a reference link; dead group-role and media-URL server actions removed.

Changed

Demo parity wave: CourseOutline promoted to components/shared (per the v0.6 layering convention) and adopted by the demo — the onboarding course is sectioned, the demo course page renders the grouped outline, and the demo lesson reader gains the 'Course contents' sidebar + mobile disclosure with section-ordered prev/next. The full conventions sweep also landed on demo surfaces: 49 eyebrow labels to text-xs, 26px detail titles, rounded-lg panels, EmptyState on a dozen list surfaces, 24 focus rings, pluralization, wrapping category tabs, and a visible Edit on the demo broadcast page. Demo composer section-authoring stays deferred.

v0.14 alpha
Today

The design system caught up with the product home dashboard — checklist + building blocks.

Changed

OnboardingChecklist redesigned to match the product's SetupChecklist — a compact, dismissible card (Rocket header, n/total count, line-through on done) replacing the older progress-bar + per-step-icon + 'Start' button layout. Steps follow how an org actually gets populated: set up groups, then create content across the enabled modules (discussion → decision → broadcast → course → document), and invite the team last.

Added

Product patterns now include the home-dashboard building blocks: quick-action cards (module-hued icon tile + label + description, hover gradient + lift), the dashboard widget shell (header + list) with its compact empty-state variant, and the 'Your spaces' module card — matching what the product renders.

v0.13 alpha
Today

Insights (real cross-module analytics) and Notifications (a real inbox) ship on the production app.

Added

Insights at /app/[org]/insights (leadership) — real metrics from org data: active members, decisions decided + median time-to-decision, broadcast read rate, course completion, activity-by-module, a contributor leaderboard, and a 12-week engagement sparkline. Period selector (7d/30d/qtr/ytd) + CSV export. Shared Sparkline component.

Added

Notifications — a notifications table fed by SECURITY DEFINER triggers (reply→thread author, vote→decision author, membership→new member) and broadcast fan-out inside create_broadcast. A topbar bell with unread count + dropdown, and a /notifications inbox (All / Unread, mark read / mark all). Recipients read + mark their own; rows are system-generated only.

v0.12 alpha
Earlier

Learn polish: real completion certificates, a callout block, and authoring/quiz fixes.

Added

Completion certificates — a designed, printable certificate (recipient / course / date / serial / org) issued automatically on course completion, with a public verification page at /verify/[serial] and a 'My certificates' list. Backed by a certificates table; complete_lesson issues one, verify_certificate (anon) confirms it.

Added

Callout lesson block (info / tip / warning) — the missing content type beyond text/image/video/link/quiz/files.

Added

Learn 'In progress / Completed' library tabs, an admin per-course Completions roster, and a 'View certificate' CTA on finished courses.

Fixed

Lesson builder: the quiz answer key is now an explicit 'Mark correct' control with a highlighted correct row; uploaded images preview in the builder; and a 'Preview lesson' link. BlockQuiz onSubmit persists a pass.

v0.11 alpha
Earlier

Learn ships on the production app — a full LMS with real media, per-course audiences, and tracked progress.

Added

Learn at /app/[org]/learn — courses → lessons → 6 block types (markdown, image, video, link, quiz, files). Three formats (tutorial / drip / external) with sequential unlock; per-user enrolment, lesson progress, course completion → earned badge. Backed by courses / lessons (blocks jsonb) / enrollments / lesson_progress with create_course + complete_lesson RPCs.

Added

Per-course audience via the content-grants model (content_type gained 'course'); leadership authors. Real media on Supabase Storage: image + file uploads (signed-URL display) and embeddable YouTube/Vimeo video. Quiz blocks grade client-side and persist a pass.

Added

Authoring: course composer (basics / format / badge / audience) + lesson management, and a lesson block builder ported to the app with real uploads. BlockQuiz gained an onSubmit callback for completion persistence.

v0.10 alpha
Earlier

Cross-module Activity feed and an append-only Audit log for the production app.

Added

Activity feed at /app/[org]/activity — a single timeline synthesised from decisions, threads, replies, broadcasts, resources, and votes (read-only, RLS-scoped, limited to the viewer's effective modules), grouped by day with All / Involving me / per-module filters. ActivityRow refactored to a presentational, data-agnostic component.

Added

Audit log at /app/[org]/settings/audit (admins) — an append-only audit_events table written only by SECURITY DEFINER helpers (log_audit). Privileged RPCs (member add/role, module toggle, group create/modules) and governance server actions (role change, member removal, group archive, org settings) record events. Searchable table with severity filters and CSV export.

v0.9 alpha
Earlier

Share module ships on the production app, backed by real Supabase Storage (which also unblocks file attachments elsewhere).

Added

Share at /app/[org]/share — a searchable resource library: collections, categories, tags, leader's notes, decision links, archive, and a 'Most accessed' rail. External links are clickable; files upload to a private Supabase Storage bucket and download via short-lived signed URLs.

Added

Real Supabase Storage: private 'resources' bucket with RLS scoped by org (path {org_id}/{resource_id}/{file}). Backed by resources / collections / resource_views tables; unique view tracking powers engagement + 'Most accessed' (org_resource_view_counts RPC).

Added

FileDropzone (components/shared) — presentational click-or-drag file picker. Reusable for any Storage upload (Share today, attachments next).

v0.8 alpha
Earlier

Broadcast module ships on the production app, and the old “Announce” name is retired everywhere in favour of “Broadcast”.

Added

Broadcast module at /app/[org]/broadcast — leadership broadcasts with a defined audience (view-only AudiencePicker), categories, featured/pinned, draft + schedule (via published_at), markdown body, CTA, and links to the decision/thread behind a broadcast. Backed by broadcasts / broadcast_reads with create_broadcast / broadcast_receipts / org_broadcast_receipts RPCs.

Added

ReadReceiptBar (components/shared) — read-tracking indicator (eye + progress + read/total). Read count and rate show to everyone who can view; the 'Haven't read' list is leadership-only. (Nudge deferred until a notifications module exists.)

Changed

Renamed Announce -> Broadcast across the entire product: the module_key and content_type enum values, routes, tables (broadcasts / broadcast_reads), components, design-system tokens, the demo prototype, and the marketing site. AudiencePicker gained a showPost prop so broadcast content shows only the view axis.

v0.7 alpha
Earlier

Discuss reaches demo parity in the production app: emoji reactions, quick polls, thread archive/pin, and a participants sidebar.

Added

ReactionBar (components/shared) — presentational emoji reaction bar: tallies as pills with the viewer's own reactions highlighted, plus an add-reaction popover. Stateless; the parent owns data + toggle. Wired onto each Discuss reply, backed by a new reactions table (RLS-scoped to thread viewers).

Added

PollCard (components/shared) — presentational quick-poll: option bars with live percentages, the viewer's choice highlighted, total tally, and an optional Close control. Backed by polls / poll_options / poll_votes with create_poll / vote_poll / close_poll RPCs (private impl + public invoker wrapper).

Added

Discuss thread detail rebuilt to the demo's two-column layout: a Participants sidebar (with Invite — adds a per-user view grant via invite_thread_participant) and a Quick polls sidebar.

Added

Threads gained archive + pin: Active / Archived tabs on the list, pinned threads float to top, and a thread more-menu with Copy link, Pin/Unpin, and Archive/Restore.

v0.6 alpha
Earlier

Permission-aware audience control for the production app, backed by the groups + content-grants model.

Added

AudiencePicker (components/shared) — two-axis editor: who can VIEW and, separately, who can POST/reply. Targets Everyone, Leadership, specific groups, or specific people; compiles to content-grant rows via compileAudience (lib/grants). The design-system source of truth for the new per-content permission model; the single-axis AudienceScopePicker stays for the demo.

Changed

Convention: reusable UI lives in components/ui + components/shared (source of truth) and is documented here; components/app holds only data-wiring. New shared components must be added to the library and the gallery.

Added

AvatarColorPicker (components/shared) — curated oklch palette for profile avatars. Powers first-login onboarding (a required name/title/avatar screen) and the profile editor at /app/[org]/account; profiles gained a title column.

v0.5 alpha
Earlier

Depth pass on every composer — tags, markdown, attachments, cross-module linking, and a real lesson block builder.

Added

Markdown renderer + MarkdownEditor (toolbar with Write/Preview). Dependency-free, common-subset. Wired into thread, decision, broadcast bodies and lesson text blocks.

Added

TagInput + TagList + TagFilterBar. Tags on threads, decisions, broadcasts, courses, and resources, with autocomplete from useAllTags and filter chips on the list pages.

Added

AttachmentField — multi-file picker (metadata only) on thread, decision, and broadcast composers, plus lesson files blocks.

Added

LinkRecordsDialog — searchable multi-select for attaching decisions / resources / courses / threads, with inline record cards (ResourceCardInline, CourseCardInline, ThreadCardInline) and two-way backlinks.

Added

LessonBlockBuilder at /demo/learn/[course]/[lesson]/edit — author lessons from six block kinds (text, image, video, link, files, quiz) with add / reorder / remove and a full quiz editor.

Added

Decision "Archive to Share" exports a decided record into Share as an immutable Decision output.

Added

Light category fields where missing: thread kind, decision type, course subject.

Changed

Models gained optional fields (tags, attachments, cross-module id arrays) — additive, no store version bump. AttachmentMeta is now shared across modules.

Changed

Detail pages render markdown bodies, tag chips, attachment pills, and linked-record sections. Decision detail data hooks moved above the not-found guard (rules-of-hooks fix).

Added

Design-system gallery section: Tags, markdown & links — live examples of every new primitive.

v0.4 alpha
Earlier

End-to-end CRUD wiring across every demo surface, plus the primitives that make it consistent.

Added

FormDialog and ConfirmDialog wrappers — every short form and destructive action shares the same shell.

Added

RadioCardGroup primitive — for weighted picks like course format, role, audience kind.

Added

Select primitive (Radix-based) for short option lists.

Added

ComposerShell + ComposerSection — full-page composer layout with sticky header, sidebar, and section cards.

Added

Thread, decision, broadcast, course composers at /demo/<module>/new + /[id]/edit. Decision composer also handles supersede mode.

Added

Upload resource and New collection dialogs on Share. Search filter wired across the catalogue.

Added

Invite member dialog (bulk-paste emails) and per-user Change role dialog on Team. Pending invites sidebar with Resend / Cancel.

Added

Group form dialog (create + edit) on Admin → Groups with module gating and member picker.

Added

SSO config dialog, Change plan dialog with live monthly delta, and Update payment dialog on Admin.

Added

Audit log gets live search, severity tabs, and real CSV export.

Added

Notifications page wires mark-read, mark-all-read, and per-notification archive. Preferences page binds per-module cadence to the store.

Added

Drafts inbox gets archive / restore with Active / Archived tabs. Action items advance status when you click the icon.

Added

Design-system gallery section covering Composers & CRUD (ComposerShell, FormDialog, ConfirmDialog, RadioCardGroup, Select, Archive-vs-Delete policy).

Changed

Store grew createdThreads / createdDecisions / createdBroadcasts / createdCourses / createdResources / createdGroups, plus 20+ mutators. Bumped to v2 with a migrate that drops v1 cleanly.

Changed

Every list and detail page now reads through useThreads / useDecisions / useBroadcasts / useCourses / useResources / useGroups so user mutations show up everywhere instantly.

Changed

Archive (not delete) is the policy. Only drafts and pending invites truly remove.

v0.2 alpha
Earlier

Cross-module references, drafts, audit, mobile drawer, role expansion.

Added

Decision ↔ thread linking with “Promote to decision” action.

Added

Decision supersession with predecessor / successor banner.

Added

Drafts inbox at /drafts.

Added

Global activity timeline at /activity.

Added

Dedicated search page at /search.

Added

Member profile at /team/[id].

Added

Audit log at /admin/audit.

Added

Notification preferences with cadence per-module at /notifications/settings.

Added

Mobile drawer sidebar via Sheet primitive.

Added

Roles: moderator and viewer (in addition to exec, member).

Added

RoleBadge, DecisionCardInline, OnboardingChecklist, ActivityRow components.

Changed

Dashboard now leads with the onboarding checklist.

Changed

Broadcast page embeds the decision it broadcast.

v0.1 alpha
Initial

First cut. Tokens, primitives, AppShell, all 5 core modules and admin.

Added

OKLCH token system, light + dark, runtime-derived brand scale.

Added

shadcn-style primitives (Button, Input, Card, Dialog, Tabs, Avatar, …).

Added

AppShell with role-aware Sidebar, Topbar, ⌘K command menu.

Added

Module marketplace with enable/disable + pricing.

Added

Brand color picker with OKLCH-derived 11-step scale.

Added

5 core modules + Team + Insights + Admin + Auth + Marketing.

Added

Design system docs at /design-system.