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
- A Library is a shelf, not a Folio. It never appears as a
kindinfolios. 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. - Membership is one entry row per (Library, Folio) —
libraryPins. It is the only stored truth of which Libraries hold a Folio. - 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 onfolios. - 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.
- 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. - 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.
- Inserting always copies. The copy lands as the destination's own Folio; later changes to the Library never reach it.
- Library access is its own relationship, checked at read time, never Folio sharing and never a copy per buyer.
- Rights are held by a firm-ready holder; only people are built.
- A Maker never reaches a Library. Library work is a Builder's.
Tables
| Table | Status | What one row is |
|---|---|---|
folios, folioVersions, folioPins, tags | Current, unchanged | The cards, their editions, their contents, the vocabulary |
folioUsers | Current (GB-309) | A person's role on a root Folio; an anonymous user per browser until sign-in |
libraries | Current (empty), target columns | One shelf |
libraryPins | Current (empty) | One entry: this edition is on this shelf |
libraryAccess | Current (empty) | One person allowed to use one Library |
libraryLicences | Target | One purchase or grant, with seats |
librarySearchScopes | Retired 2026-10-09 | Active Libraries lists; replaced by folioUsers.useIn (Use in) |
folioUsers — who works on a Folio
folioKey, userKey, roleWho 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 marketplaceCurrent 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 LibraryIn 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
derivedFromFolioKeyandderivedFromVersionKey; 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.kindholding contents throughfolioPins— 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
foliosbeside 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:
libraryPinsalone 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
folioUsersrows are kept for it.
Order of work
folioUsers(GB-309, Current), then sign-in and the claim step (GB-10).librarieswith the holder, owner and builder members, Save through the master, the export projection (GB-50.6).- Persisted search scope; search and insert through Goldie (GB-245).
- Tags, written by Goldie from each Library's guide (GB-341).
- 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.
- A Library Is a Shelf, Not a Folio — 2026-09-06 boundary, 2026-09-07 doors and visibility, 2026-09-09 membership amendment.
- Library Search Is a Conversation — 2026-09-12, S1–S6.
- Library Membership Is an Index Card — 2026-09-25, membership, master, holder.
- A Library Holds Documents, Not Projects — 2026-10-01, reverses "a master may be anything but a Workspace".
- The Library menu ruling, 2026-09-11, formerly in Documents, Modules and Blocks.