forms

forms

all docs

Forms & typed documents — kinds as data on the one document spine

Historically every form class (nda, invoice, lease, …) referenced a forms.md that never

existed. This is that doc, written after the forms system converged onto the document spine.

Doc of record for the whole subsystem: [../roadmap/documents-universe/THESIS.md](../roadmap/documents-universe/THESIS.md)

(the universal law, the two axes, the phase status). This page is the concrete "how a typed

document works" reference. Sibling: [documents.md](./documents.md) (the base spine + codecs).

The one idea: a form is not a class — it is a KIND, and a kind is DATA

A "form" is a typed document: a document whose kind carries a *schema* (the named fields you

fill) and a *template* (the body those fields drop into). There is no form class and no

per-form class. A kind is one row of DATA plus two small JSON files — never code:

document/registry.jsonl one row per kind: {kind,label,category,format,icon,summary[,legal cols]}

document/kinds/<kind>/schema.json the ordered named fields (label, required, group, hint)

document/kinds/<kind>/template.json the body blocks with {{field}} placeholders

This is the reuse-first mandate made literal: 74 old parent = form classes + 46 old

parent = legaldoc kinds collapsed into ~99 registry rows (deduped by kind). Adding a new kind

is a name + two JSON files — a kind is a name, not a folder (the THESIS law). An unknown kind is

never a dead end: it falls through to a generic envelope, still fully create/edit/export-able,

and can be promoted to a typed kind later.

The lifecycle of a typed document

1. Pick a kind. /document/kinds lists every kind (from the registry); /document/home is the

picker + your instance list. A human taps a kind; an agent calls the same URL.

2. Mint an instance. document.new?kind=<k> creates a real owned instance at

__dataroot/<id>/ — object.data (class/owner/title/kind/ts/docfamily), blocks.json (the

template rendered live), and fields.json (the filled values; this replaced the old per-node

formcache singleton — values live *with* the instance now).

3. Fill it. document.fill (bulk JSON) / document.set (one field) / the field form write into

fields.json; the body re-renders with the values substituted. Unknown keys are schema-filtered.

4. See it / export it. Every face reads the one instance: scene (/<id>), markdown (/<id>/md),

or a real file. /<id>/download?fmt=pdf|docx|xlsx|pptx streams the rendered file to a browser

(correct MIME + Content-Disposition: attachment); the same bytes open device-local on a shell.

5. Own it / share it. The instance carries owner + a grant list. document/_lens_ok is

fail-closed (owner OR grantee); document/share (owner-gated) records a grant without clobbering

keys; document/shared is the "shared-with-me" index. A stranger sees nothing (no leak).

6. Sync it. On create/update the instance emits a signed twin event; it converges to the owner's

other fleet nodes (same ZeroID) via twin-DATA — "my documents" follow the person, deny-by-default

to anyone else.

The legal-lifecycle overlay (legal kinds)

The 46 legal kinds (nda, msa, lease, sha, affidavit, …) carry extra registry columns —

custodian, sign, stamp, filing, parties — and gain a lifecycle overlay on the same

instance, reusing legaldoc's proven engine (its _ledger/_profile/_party_has/_today/… helpers,

not a rewrite). A legal instance gets a per-instance append-only, sha256-pinned ledger.jsonl:

verb

records

gate

/<id>/sign

a consent signature, pinned to the exact content hash

owner or named party

/<id>/stamp

stamp duty (amount/currency)

owner

/<id>/handoff

assign the custodian / licensed professional

owner or party

/<id>/revise

a new content version (new sha256 pin)

owner

/<id>/advance · /refuse

move / reject lifecycle state

owner

/<id>/filing

a regulatory filing record

owner

/<id>/history

the versioned provenance trail (every version, across time)

owner or party (fail-closed to strangers)

The instance page links 🕓 Legal lifecycle → /<id>/history for any kind whose registry row has a

custodian (a human reaches it from where they already are; an agent uses the same URL). The old

legaldoc desk (/legaldoc, /nda, …) is now thin redirect doorways onto the spine — one desk,

not two. This retires the "two journals for one person" duplication the reuse mandate exists to kill.

Why this scales (N + M, not N × M)

Formats are codecs (one per format, reused by every kind); kinds are data (additive). The

engineering cost is one spine + ~12 codecs + M kinds-as-data; the *documents* — the trillions — are

instances (data), each owned, listed, lensed, versioned. See the THESIS for the full argument.

The honest boundary

Codecs are content-faithful (extract → edit → re-emit a clean file; layout regenerated) — this

covers invoices, contracts, resumes, reports, decks, and scanned-PDF OCR (page text recovered via a

live vision model). Layout-faithful, Acrobat-grade PDF (byte-surgical layout preservation) is the

one deliberately deferred boundary. State which bar a face meets; never imply the higher one.