Goldie Blocks

Schema Overview

The map — every stored table, what it holds, and which page owns its detail

Every stored table is defined in one file, convex/schema.ts, which governs. This page is the map — what each table is for and where its detail is written down. It is deliberately short: the shapes live on the pages it points at, and a count or a column list repeated here would only drift.

In plain terms: the index at the front of the filing system. It tells you which drawer holds what, and which page describes the cards in that drawer.

Content — the Folio tables

Two recursive tables plus pins hold every authored thing. Their detail, the write invariants and the read layer are all in Folios Schema, which governs.

TableHolds
foliosOne row per folio, versionless — the card in the drawer. Keys, pointers and lineage; its kind is the sole kind discriminator.
folioVersionsOne save point of one folio's own content. Every edit lands on the open draft; minting a version is a user act.
folioPinsA save point's schedule — which children, at which edition, that save point comprises. Pins point down; children never point up.
tagsThe shared vocabulary a folio's About card draws its tags from.
listOrdersOne person's own order for one list of cards — a Workspace's Projects, a Project's Documents, or their Libraries (listKey is the container's folio key, or libraries). Keyed by the signed-in account, else the browser's user. Only a sort hint: a key absent from order is new and draws on top; a Library's own Documents are never stored here (The Goldie Card).

There are no separate document, module and block tables. The three-tier schema and its three version tables were deleted on 2026-09-03; a card's tier is a word on the card. A page describing documents or moduleVersions as storage is out of date, and bun run preflight will not catch it — prose about a table is not a path — so say so rather than building against it.

Goldie — conversation binding

Threads and messages themselves belong to the Convex Agent component, in its own namespace. The app stores only the binding.

TableHolds
folioAgentThreadsOne Builder conversation, bound to the folio its card shows and the session that opened it — so a tool call resolves whose authority it acts under from the thread alone (One Goldie Per Folio).
folioListThreadsA list-screen row's conversation, bound to the browser client rather than a document session (Goldie on the List Screens).
proposalsOne filed, not-yet-applied change to one Working Document — Proposals Schema.

A proposal is its own row, never a folio version and never a column on the row it targets. Versions record what happened, and a declined suggestion did not happen, so a rejected proposal leaves no trace in version lineage.

Identity and access

TableHolds
authSessionsWho this browser claims to be, and which Document it is bound to — Auth Sessions. Only an authorized session opens a Document.
usersAuthenticated platform accounts — Users. Separate from party facts, which are document content.
authEventsThe append-only audit trail of authentication attempts — Auth Flow.
folioVisitsWhich folios this browser opened and when, per kind, so Recent can be listed without a session.

Ships empty

Three tables exist with typed validators and no product writer. They are not a gap to fill opportunistically — each waits on a feature.

TableWaits on
librariesThe library feature: the public singleton is minted at launch, a personal library on a user's first save-to-library (A Library Is a Shelf).
libraryPinsThe same. A pin names an exact sealed edition; listing mints no version.
documentGenerationsExport and payment — Document Generations.

Rules that hold across every table

  • Business identity is a prefixed key string, not Convex's _id. _id stays internal; a key is what crosses the wire and appears in a route.
  • Never duplicate _creationTime. There is no createdAt, no proposedAt. A folio version's created date derives from its row's _creationTime; a proposal's filing time is the same.
  • The version row is the render boundary. Re-rendering or exporting reads a named folioVersions row and the editions its pins schedule — never the mutable state of another version.
  • A field is not a row. It is an ordered entry owned by one data block's version, with its own minted identity, and it freezes with that version.
  • Parties are not a schema concept. Party facts — willmaker, executors, family — are ordinary data on a data_pool module, so cross-document reuse is the same mechanism as any other data_pool reference.
  • data_pool is a convention, not a type. Modules have no type discriminator. A module whose data blocks own document-wide facts is usually handled data_pool, and nothing in the schema grants it special status for that. Write authority belongs to the data block owning each field.
  • An identity challenge is access metadata, declared access.challenge: identity — not an auth module type.

The other schema pages

  • Status Axes — the four independent status axes, and why they are never one overloaded enum.
  • Flow Schema — flow.condition and the reference grammar a condition may use.
  • YAML and JSON Mapping — how authored YAML becomes stored JSON, and back.
  • Threads and Messages — what the Agent component owns rather than this schema.

On this page