Goldie Blocks

Libraries

The one consolidated statement of the Library — what a Library is, the tables behind it, how saving, searching, inserting and access work, the menu, and what is still open. The dated decision records are its history.

Partly built (GB-50.6)

Current: sign-in and Folio ownership (GB-309, GB-10); the personal Library and its Workspace, provisioned at first sign-in and opened at /app/my-library; seat-only access to that Workspace; the page header's attested Publish (Share › Library), making and republishing masters; and libraries: [...] on the export bundle and the About card; Document masters only — a Library holds Documents, and a Project, Module or Block is refused (owner rulings, 2026-10-01); Modules and Blocks are searched and inserted from inside Library Documents. Not yet: Browse, licences. Insert is Current from the search card, Goldie and a Document master's page (see Insert). Everything below is Target unless marked Current, and Proposed where the owner has not yet ruled.

This page is the authority for Library work (GB-50.6, GB-245). It consolidates the dated rulings listed under History; where a record and this page differ, this page is the later statement.

In plain terms: a Library is a precedent bank with a drawer of index cards. Saving a document to a bank files a card pointing at a frozen copy of it, and one document can have cards in several banks. Taking a precedent into a matter photocopies it into the file as the matter's own. Who may use a bank is a licence, held by a person today and drafted so a firm can hold it later.

Principles

  1. A Library is a shelf, not a Folio. It never appears as a kind in folios. A Folio has one parent and every change to its contents mints a version; a Library holds one item beside many others and in many Libraries at once, and cataloguing is not editing.
  2. Membership is one entry row per (Library, Folio) — libraryPins. It is the only stored truth of which Libraries hold a Folio.
  3. The Folio's list of Libraries is printed, not stored. Export and the About face print libraries: [...] from the Folio's active entries; no Library-ID column exists on folios.
  4. An entry names an exact sealed edition — a snapshot. Publishing never points at a live draft. Edits reach the Library only when the owner saves again, which retires the old entry and files a new one.
  5. An entry carries everything beneath it. A saved Document brings its Modules and Blocks through that edition's own folioPins; there is never one entry per descendant. A Library sits at Project level and holds Documents, not Projects (owner, 2026-10-01; reverses 2026-09-26). A Document is the highest kind saved to a Library; a Project is a client matter and is refused. Starter packs are several Library Documents inserted into a new Project. Decision.
  6. The first save makes a Library master. A separate Folio with fresh keys and recorded lineage, filed in the Library's own Workspace, which the owner edits from then on; the client Document is not touched and not linked. A master has one home but may have entries in several Libraries.
  7. Inserting always copies. The copy lands as the destination's own Folio; later changes to the Library never reach it.
  8. Library access is its own relationship, checked at read time, never Folio sharing and never a copy per buyer.
  9. Rights are held by a firm-ready holder; only people are built.
  10. A Maker never reaches a Library. Library work is a Builder's.

Tables

TableStatusWhat one row is
folios, folioVersions, folioPins, tagsCurrent, unchangedThe cards, their editions, their contents, the vocabulary
folioUsersCurrent (GB-309)A person's role on a root Folio; an anonymous user per browser until sign-in
librariesCurrent (empty), target columnsOne shelf
libraryPinsCurrent (empty)One entry: this edition is on this shelf
libraryAccessCurrent (empty)One person allowed to use one Library
libraryLicencesTargetOne purchase or grant, with seats
librarySearchScopesRetired 2026-10-09Active Libraries lists; replaced by folioUsers.useIn (Use in)

folioUsers — who works on a Folio

folioKey, userKey, role

Who may open and edit a Folio. Current: built before sign-in (owner ruling 2026-09-25, GB-309), with an anonymous user per browser holding owner on each Workspace and root Document it creates; sign-in (GB-10) claims that user and its rows come across unchanged. The contract is Folios Schema.

libraries — the shelf

key, label,
visibility: personal | shared | public,
holderType: "user",        // "firm" added later without rewriting rows
holderId,                  // users.key while holderType is "user"
homeFolioKey               // the Library's own Workspace, holding its masters
// price and tier columns arrive with the marketplace

Current since GB-50.6: type (public / personal / group) and ownerUserId gave way to visibility and the holder pair; the owner ruled the earlier rows disposable, so nothing was migrated. No organisation table, screen or admin is built.

libraryPins — the entry

libraryKey, folioKey,
folioVersionKey,           // sealed; never a live head
publishedLabel,            // the name as it was when saved; listings show it
sourceOrder?, sourceSiblingMax?,   // advisory landing position
retiredAt?                 // absent = active
guide?, tags?              // this item's guide and tag words in this Library

In plain terms: the entry carries its own summary and labels for this cabinet, written to this cabinet's note. guide and tags are per Library (Goldie Tags by Instruction, rule 5): seeded from the edition's own folioVersions.guide and tags when the item is added (a republish keeps the entry's own), then rewritten by Goldie to the Library's guide — the guide of libraries.homeFolioKey — in goldie/tagging.ts. Only Goldie's door (goldie/tagWrites.ts) writes them.

Append-only: at most one active entry per (libraryKey, folioKey), checked against by_library_and_folio. The Current internal writer already refuses a live edition and retires before appending. Library lists read by_library.

Members — folioUsers rows on the Library's home folio

Changed 2026-09-30 (owner): one folio members table. A Library's people are ordinary folio members: folioUsers rows on its home folio, with the same roles every folio uses — owner, builder (publishes into it; was contributor), reader (searches and inserts). Makers do not apply to a Library. The libraryAccess seats table is retired and empty. Paid access (licences, later) attaches to a member row the same way it was planned to attach to a seat.

libraryLicences — a purchase

libraryKey, holderType, holderId,
source: free | purchase | subscription | grant,
seats, expiresAt?

The seller sets seats and price; the holder assigns seats to named people; when the licence lapses, its seats lapse. A firm later becomes the holder without redesign (owner ruling 2026-09-25).

Search scope

Current (owner, 2026-10-09; decision): who can see a Library is its seats; where it is used is the seat's Use in, folioUsers.useIn on the person's row on the Library's home folio. Absent or { only: false } is My workspace: searched in every Project and Document. { only: true, projectKeys } is Only these projects. The ticks are kept when switched back. A Document, Module or Block uses its Project's Libraries; outside a Project only My workspace Libraries are used. A Project's Libraries modal shows the same fact from the Project's side: everywhere Libraries locked on, project-only ones ticked (setProjectTick). Reads are convex/library/useIn.ts (readSearchedLibraryKeys, which the search card and Goldie's search both read, forLibrary, forProject); writes are convex/library/useInWrites.ts (join, leave, setUseIn, setProjectTick). Scope never grants access.

In plain terms: your key opens the bank; the entry on the bank says which of your matters it is used on.

A seat still records how it was reached in origin: "joined" from Join, absent for invited or owned. Join (a free Library, stored public) gives a reader seat used in My workspace. Leave Library, in the modal's Joined tab, removes the seat; copies already inserted stay. A By approval Library (stored shared) shows Request access, disabled, "Coming soon".

Retired 2026-10-09: the Active Libraries lists, librarySearchScopes rows per Workspace or Project, set from Home and a Project card. The table stays declared until migrations:carryLibrarySearchScopes (convex/library/carryScopes.ts) has run on every deployment. Search ignored those lists until 2026-10-09, so the migration infers nothing from them: a Library seat with no Use in becomes My workspace, and any Use in already stored, including a chosen Only these projects, is left as it is, so a rerun changes nothing. library/carryScopes:reportUseInCarry is the read-only dry run; it also flags restrictions matching what the withdrawn first version would have inferred, for review, never reset automatically.

In plain terms: nobody loses a precedent bank they could search before, and nobody's own "only these matters" choice is overwritten.

How it works

Current (Documents only, owner 2026-10-01). A Module or Block is refused with "Libraries hold Documents. Publish the Document this clause belongs to." (requirePublishableKind, convex/library/publishWrites.ts; decision). The only publishing writer is the snapshot publish below.

In plain terms: there is one way into a Library — the attested publish from the page header.

Snapshot publish (page header, owner 2026-10-01; GB-333). The page header's Publish › seals the working copy as vN (an unchanged copy reuses its last sealed version and mints none), makes a master of that sealed edition with answers cleared (copySubtree's edition walk, lineage derivedFromVersionKey), and files it in each ticked Library, retiring that Library's earlier entry for the working copy. The author continues in vN+1. The server refuses a publish without the attestation flag. convex/library/snapshotWrites.ts. The card menus' Publish to Libraries › row is removed (owner, 2026-10-01): publishing lives only in the header. Removed 2026-10-01: the older tick writer setLibraryEntry, which published without the attestation or the Library-edits guard. A test proves an outside call to it is refused and writes nothing.

Save. Page header → Share → Library tab → tick Libraries, confirm sensitive content is removed, Publish. Each publish seals an edition, makes its master and files it, retiring that Library's earlier entry. Withdraw retires the entry. Delete and Remove from Library are separate: Delete is a fact on the Folio, removal retires an entry, and neither implies the other.

Update. An owner or builder opens the master in the Library's Workspace, edits its working draft and saves versions as private checkpoints. Saving a version does not publish it. Edits made in the Library are published from the Library item as that Library's next version; publishing from the working copy over them warns, and the server refuses without replaceLibraryEdits. Copies already inserted elsewhere never change. Owner and builder members carry edit rights over the Library's Workspace, so no second editor list is kept.

Export. The Folio's active entries print as libraries: [...]. Current: the export bundle (convex/folio/exportInput.ts) and the About card's YAML (libraries:, after tags:) carry the labels of the Libraries the reader holds a seat on (owner, 2026-09-29). Its parse rule: the card reader reads past the line and never writes it, so an edited list is ignored and the next print states the entries again.

Search. Take the current Folio's effective scope, keep the Libraries the user can access, read their active entries, and search each entry's sealed edition and its pinned descendants, so a clause inside a saved Document is a candidate on its own. Candidates are limited to kinds the destination may contain (FOLIO_SCHEMA_CONTAINMENT). Results use a purpose-built paginated projection. Searching, previewing and selecting write nothing.

The search card (owner, 2026-09-27; supersedes "no search box"). Every Insert door opens the search card. Under its search sits SELECT LIBRARIES TO SEARCH, the saved list as chips that filter this search only, a last + More Libraries chip opening /app/libraries, and, once a chip changes, Keep selection, which saves the chips one level up (owner, 2026-09-28; decision). Library items of the kinds the section holds join it beside the blanks (candidates, convex/library/searchScope.ts). A choice lands immediately below the block or module whose card chose it (afterFolioKey on insertLibraryEntry); from a module's foot, at the end of that module. Clauses come from inside Library Documents (owner, 2026-10-01): each Library Document is offered whole, and every Module and Block its published edition pins is offered too, its row reading "Termination — in Services Agreement (Precedents)" (inDocument on the candidate, convex/library/search.ts). Goldie's search reads the same candidates.

Tick, Insert, then keep (owner, 2026-09-28). Library items are ticked, not added one by one; an Insert N button (black, a white dotted inner line) lands every ticked item, in the order ticked, each below the last. On a Document they land staged (folios.stagedAt on the copy's top folio): in the draft but read-only, left out of a saved version, the export and the collected answers, and drawn with a striped spine and a dashed top, right and bottom edge in the card spine's own hover grey (--color-spine-hover), its marks shown at rest and inactive — Goldie's green and red stay hers. The ticked items are filed as one proposal whose steps keep the copies (convex/library/proposeWrites.ts; one proposal flow, owner 2026-09-30): each staged card carries that memo's tick and cross for its own step, the tick clears the mark, the cross removes the copy and every row it made. Blank items still land at once, unstaged.

In plain terms: precedents come in on approval. You can pull five, read them in place, and keep the two you want.

Ask Goldie (Current, not yet walked live; settled 2026-09-30; GB-245). A Builder asks Goldie for a clause. She searches the same entries by index card, never reading the clause, and lands her one best pick as a staged copy exactly as the search card does above, naming alternatives in words. A copy the conversation staged stays within her proposal reach after the tick, so "shall I reword it?" is an ordinary proposal on that block. Staging is write-structure and Builder-only; finding nothing offers to draft. The rulings, and what they supersede, are in Goldie Finds a Clause and Stages It.

Insert. One operation with two doors: from a canvas (destination known, pick the publication) or from a Library (publication known, Add to … lists the destinations the session may write to that can hold that kind). The destination always already exists (owner ruling 2026-09-26): a Document goes into an existing Project, a Module into an existing Document and a Block into an existing Module (no Project is ever in a Library, owner 2026-10-01); Insert never makes a place to hold the copy. The two doors are one rule seen from each side: from a Library item, the search offers only places of the kind that holds it; from inside a Folio, search offers only Library items of the kind it may hold — a Document sees Modules, a Module sees Blocks. A Module or Block is taken from inside a Library Document: the copy is of that clause as the Document's active entry pins it, never the master's draft (convex/library/entrySource.ts). One mutation copies the exact sealed edition:

  • fresh Folio and version keys, owned by the destination's owner;
  • lineage recorded as derivedFromFolioKey and derivedFromVersionKey; for a clause these name the clause and its pinned edition, whose parent is the Library Document;
  • containers recurse through that edition's pinned descendant editions, never their current heads, with internal references remapped;
  • collected answers cleared, authored content kept;
  • the source's access restrictions not copied;
  • never updated when the Library entry is republished.

Goldie may propose an insertion; the copy materialises only on acceptance, so a rejected proposal leaves nothing behind.

Current (GB-245). insertLibraryEntry (convex/library/insertWrites.ts) copies the active entry's edition through copySubtree's edition walk (convex/folio/duplicateWrites.ts), which Duplicate shares. It needs a signed-in owner or builder member, and a destination of the holding kind on which the caller holds an owner or Builder role (browserCanWriteFolio, never a Reader, a Maker or anything inside a Library). The lock (access) is the access restriction left behind. A Library master's Insert into… button (owner 2026-10-01) calls it and opens the copy; its destinations list (folio/home:destinations) offers only places the caller may write to. A Project master is refused.

The Library's Workspace. The back room, seen only by owners and builders. It offers no add (owner ruling 2026-09-26): nothing is made in a Library; masters arrive by saving from a working copy. Its page groups them by kind — Documents, Modules, Data Blocks, Content Blocks — with no headings: each card names its own kind, so the groups are marked by spacing alone, 24px between cards of one kind and 48px between kinds. The add card's 48px slot is kept, empty, so the first card lands where it does on every page. A Library Workspace holds Documents only (owner, 2026-10-01): its page lists Documents and its card counts Documents; a Module or Block master filed earlier is not listed. A saved Document's contents are reached by opening it, never listed again, while search still reaches them. Every other Workspace keeps FOLIO_SCHEMA_CONTAINMENT (Workspace holds Projects only). Each master shows its standing: not published, published at vN, or published at vN with a draft ahead.

Current — how access reads here (convex/library/libraryAccess.ts). Anything filed under a Library's Workspace, the Workspace itself included, answers to that Library's members alone: the signed-in account must be an owner or builder of its home folio. The rule sits in the two gates every read and write already passes — browserCanReadFolio for containers and callerMayUseRoot for Document slips — so a stale slip, another account, a signed-out browser and a reader seat are all refused, and no folioUsers row is written for a master. sessions.openForAccount mints a master's slip on the same seat. Outside a Library nothing changes. Only a Library's Workspace relaxes FOLIO_SCHEMA_CONTAINMENT (convex/folio/writes.ts), for Documents only; a Project, Module or Block is refused with a plain sentence.

Project masters split (2026-10-01). Project masters made under the 2026-09-26 rule are taken apart by the splitProjectMasters migration (convex/library/splitProjectMasters.ts): each live Document moves to the Library's Workspace and is filed at the edition the Project's entry pinned, the Project's entry is retired and the Project deleted. Run on dev 2026-10-01: one Project, five Documents.

Superseded 2026-10-01: Module and Block masters. No new one can be made; those on dev were retired. The page rule below is kept for history. A Module or Block master is its own page (owner rulings 2026-09-25 and, for Blocks, 2026-09-26). A session slip may be bound to a Document, or to a Module or Block filed directly in a Library's Workspace (mayBindSession, convex/folio/readAuthority.ts) — never to any other, which is reached through its Document. The Document page opens such a master as its root: no Document card; a Module drawn open, a Block drawn alone with no Module card round it; nothing added beside it, duplicated beside itself, or given a Document guide. Each Module and Block on a Document's page has its own Publish to Libraries › row. A Module or Block master's page leads with Use this module or Use this block (a Document master's, Use this document, listing Projects), listing the caller's Documents, or Modules as "Document › Module"; a used Module or Block lands at the end of the one chosen (owner, 2026-09-26). Export names only the Libraries the reader holds a seat on.

Knowing you are in a Library (owner request 2026-09-25). Anything filed in a Library says so: the location line above its title opens with a blue Viewing in Library stamp and the Library's name, and the work bar's trail names the Library's Workspace "Library". The server carries the fact as library on each listed item (convex/folio/homeReads.ts), so nothing is stored twice.

Browse. A Library's contents screen is the ordinary Folio list fed by entries, each card drawn at its sealed edition and therefore read-only by the existing gate; its only mutating row is Add to …. The list of Libraries is the same list screen; a Builder can create one, and a personal Library is provisioned at sign-up.

Access and sharing. Owning, being shared into, free use and buying all end in a libraryAccess seat. A bought Library is shared by seat licence: the holder assigns the licence's seats to named people.

Listing names. A listing shows publishedLabel, the name the item had when that edition was saved, so the name always matches the frozen copy. Renaming a master changes listings only when it is saved again.

Tagging. Membership is always a deliberate save from the menu; nothing joins a Library by itself. When an item is saved to a Library, Goldie guides and tags it to the Library's guide (libraryPins.guide and tags above).

The menu

The shared Folio menu has a Library section, in order: Sanitise for Publication › and Publish to Libraries › (owner ruling 2026-09-11; Search in Libraries removed 2026-09-28). Sanitisation, marketplace and payments are outside the current preview.

Search in Libraries was a menu row until 2026-09-28; it is removed. Which Libraries to search is chosen on the search card only (decision). A Workspace card's kind line carries "Searches 2 Libraries"; hovering lists them all.

Refused

  • A Library as a folio.kind holding contents through folioPins — breaks single-parent containment, versions every shelving, and forces drifting duplicates for multi-Library membership.
  • Library access through folioUsers — purchases need a source, seats and an expiry that Folio sharing does not.
  • A stored Library-ID array on folios beside the entries — two truths.
  • A search modal or tab, including the retired search-select panel. The in-place search card is not refused (owner, 2026-09-27).
  • Library-to-Project assignment until a real requirement appears.
  • A Project as a Library master (owner, 2026-10-01): a whole client matter must not be carried into a shared Library.
  • Organisation features now.
  • Membership that files itself. Saving to a Library is always a choice.
  • The manual Tag / Stash / Re-tag journey (retired 2026-09-09, GB-211).

Open

  • Automatic tagging on save — which tags, from what, and how untag works; later (GB-50.6).
  • Proposed (owner, 2026-09-26): the last Block offers two kinds. Adding after the last Block in a Document could land either in that Block's Module or as a new Module in the Document, so its add card would search both Modules and Blocks. Everywhere else one kind is offered: a Project's add card adds Documents only. To settle when search is built (GB-245).

Settled 2026-09-25 (GB-50.6)

  • A Library is a collection of Folios. No Library-item record exists beside the entry: libraryPins alone says which Folios a Library holds, and the Library's Workspace is where those Folios are seen.
  • The Library holds a copy. Publishing a client Document files a separate master; later client edits never touch the Library.
  • Master derivation: from the working draft, as Duplicate does, then sealed as the master's first version. This leaves Sealed Versions Are Immutable rule 4 undecided.
  • References a master leaves behind: making a master clears any collected field answers and otherwise takes the content as it is. It neither carries field definitions from elsewhere in the source Document nor warns.
  • The Library's Workspace answers to members only. Owner and builder seats open it; no folioUsers rows are kept for it.

Order of work

  1. folioUsers (GB-309, Current), then sign-in and the claim step (GB-10).
  2. libraries with the holder, owner and builder members, Save through the master, the export projection (GB-50.6).
  3. Persisted search scope; search and insert through Goldie (GB-245).
  4. Tags, written by Goldie from each Library's guide (GB-341).
  5. Marketplace: licences, seats, payments.

History

The dated rulings this page consolidates. They are kept as history; read them for why, read this page for what.

On this page