# Field reference

Generated by `npm run docs:build` from `docs/data-model/model.mjs` — do not hand-edit.
`docs/data-model/selftest.mjs` checks this two ways: every field named here resolves in a real record, and every field a real record has is named here or listed under `omits` with a reason. A field missing from this file either does not exist yet or the map has a gap — `npm run docs:test` says which.

One field per line: `<node id> · <field path> :: <type>`, plus the note from the map if it has one.

## Capture and archive

### cap.record — Capture record (`manifests/dt=YYYY-MM-DD/captures.jsonl`)

cap.record · schema_version :: number — CAPTURE_SCHEMA_VERSION, currently 1
cap.record · capture_id :: string — cap_<utc-timestamp>_<8 hex> — sortable, and the join key downstream
cap.record · source_id :: string — the registry entry in tools/sources/*.json
cap.record · url :: string — as requested, before redirects
cap.record · final_url :: string|null — null when no redirect happened
cap.record · method :: string — 'GET'
cap.record · request_headers :: object — including the conditional headers actually sent
cap.record · fetched_at :: string — ISO 8601, UTC
cap.record · duration_ms :: number
cap.record · http_status :: number|null — null when the request never completed
cap.record · response_headers :: object|null
cap.record · redirect_chain :: array — {url, status, location} per hop
cap.record · content_sha256 :: string|null — the blob key; null for 304, 404 and errors
cap.record · content_length :: number|null
cap.record · content_type :: string|null
cap.record · etag :: string|null — fed back as If-None-Match on the next run
cap.record · last_modified :: string|null — fed back as If-Modified-Since
cap.record · tool_version :: string
cap.record · config_sha256 :: string|null — hash of the source set that produced this run
cap.record · error :: object|null — {name, message} — a network failure is an observation, not a crash

### cap.blob — Blob (`blobs/sha256/<aa>/<bb>/<sha256>.gz`)

cap.blob · <body> :: bytes — exactly what the wire delivered, gzipped. Never reformatted.

### cap.digest — Day digest (`manifests/dt=YYYY-MM-DD/digest.json`)

cap.digest · schema_version :: number
cap.digest · date :: string
cap.digest · n_captures :: number
cap.digest · n_ok :: number — 200 with a body
cap.digest · n_unchanged :: number — 304 — looked, identical
cap.digest · n_error :: number
cap.digest · merkle_root :: string
cap.digest · prev_date :: string|null
cap.digest · prev_digest_sha256 :: string|null
cap.digest · sealed_at :: string

### cap.anchor — anchor/*.json (`anchor/`)

cap.anchor · date :: string
cap.anchor · n_captures :: number
cap.anchor · n_ok :: number
cap.anchor · n_unchanged :: number
cap.anchor · n_error :: number
cap.anchor · merkle_root :: string
cap.anchor · prev_date :: string|null
cap.anchor · prev_digest_sha256 :: string|null — the link. Null on a day whose predecessor was not sealed.
cap.anchor · sealed_at :: string
cap.anchor · schema_version :: (deliberately not declared here — a real field on this file — see cap.digest, the same record read for its schema — but not part of what this node calls "the anchor": the merkle root, the hashes and the link to the prior day.)

### cap.turso — Turso (libSQL)

cap.turso · source_url :: text — planned: on every fact table, non-negotiable
cap.turso · retrieved_at :: text — planned
cap.turso · sha256 :: text — planned
cap.turso · recorded_at :: text — planned
cap.turso · valid_from :: text — planned: on every fact with a real-world validity window
cap.turso · valid_to :: text — planned: on every fact with a real-world validity window

## Derived datasets

### ds.presidential — Presidential corpus (`presidential/data/documents.json`)

ds.presidential · schema_version :: number — currently 1
ds.presidential · identity.normalizer_version :: number — change either and every doc_uid changes, so both travel with the data
ds.presidential · identity.incipit_chars :: number — change either and every doc_uid changes, so both travel with the data
ds.presidential · documents[].doc_uid :: string — pd-<sha256(incipit)[0:16]> — the document, stable across publishers and edits
ds.presidential · documents[].identity.text_sha256 :: string — the rendering. Same doc_uid, different text_sha256 = printed differently, or edited
ds.presidential · documents[].identity.head_anchor :: string — which rule found the start of the operative text; after_title and after_breadcrumb are the weak ones
ds.presidential · documents[].register_state :: string — published | undetermined_within_lag_window | absent_from_federal_register
ds.presidential · documents[].renderings[].link_method :: string — text_sha256 | incipit_sha256 | shingle_jaccard | title_jaccard — never a bare boolean
ds.presidential · documents[].renderings[].text_identical :: boolean — false with a link present means two publishers print the same document differently
ds.presidential · reconciliation.wh_to_fr_lag_days :: object — recomputed every run from content-tier links only
ds.presidential · reconciliation.rejected_weak_links :: array — title matches the dates refused
ds.presidential · unidentified :: array — documents that minted no identity, kept rather than dropped

### ds.daily.day — Day file (`daily/data/2026-08-17.json`)

ds.daily.day · schema_version :: number — currently 2
ds.daily.day · publication_date :: string — Eastern-time publication date — the primary key
ds.daily.day · built_at :: string
ds.daily.day · n_documents :: number
ds.daily.day · n_agencies :: number
ds.daily.day · counts_by_type :: object — Rule / Proposed Rule / Notice / Presidential Document
ds.daily.day · truncated :: boolean — true if the API capped the page and documents are missing
ds.daily.day · provenance.source_id :: string — fr.documents.day
ds.daily.day · provenance.url :: string — the exact request, field list and all
ds.daily.day · provenance.retrieved_at :: string
ds.daily.day · provenance.http_status :: number
ds.daily.day · provenance.content_sha256 :: string — the blob this was parsed from
ds.daily.day · provenance.capture_id :: string — joins to the capture record
ds.daily.day · provenance.day_merkle_root :: string — joins to the digest chain
ds.daily.day · obligations[].type :: string — 'comment_close' | 'effective_date'
ds.daily.day · obligations[].date :: string — a date the government printed, never a projection
ds.daily.day · obligations[].days_from_publication :: number — negative for a date already past
ds.daily.day · obligations[].certainty :: string — hard enum 'statutory'. Never a probability.
ds.daily.day · obligations[].label :: string — 'Takes effect' / 'Comments close'
ds.daily.day · obligations[].document_number :: string — joins to documents[]
ds.daily.day · obligations[].title :: string
ds.daily.day · obligations[].agencies :: array
ds.daily.day · obligations[].html_url :: string
ds.daily.day · obligations[].pdf_url :: string
ds.daily.day · documents[].document_number :: string — the Federal Register’s own id — the join key everywhere
ds.daily.day · documents[].type :: string
ds.daily.day · documents[].title :: string
ds.daily.day · documents[].abstract :: string|null
ds.daily.day · documents[].agencies :: array — names as published
ds.daily.day · documents[].agency_slugs :: array — normalised against the FR agencies vocabulary
ds.daily.day · documents[].significant :: boolean|null — the FR’s own flag, not ours
ds.daily.day · documents[].citation :: string — e.g. "91 FR 53355"
ds.daily.day · documents[].effective_on :: string|null
ds.daily.day · documents[].comments_close_on :: string|null
ds.daily.day · documents[].docket_ids :: array
ds.daily.day · documents[].regulation_id_numbers :: array — RINs
ds.daily.day · documents[].cfr_references :: array
ds.daily.day · documents[].html_url :: string — the citation targets
ds.daily.day · documents[].pdf_url :: string — the citation targets
ds.daily.day · documents[].salient :: boolean — ours, computed. See the rule below.
ds.daily.day · public_inspection.retrieved_at :: string
ds.daily.day · public_inspection.n :: number — documents on the desk at that moment

### ds.daily.index — Day index (`daily/data/index.json`)

ds.daily.index · schema_version :: number
ds.daily.index · latest :: string
ds.daily.index · days :: string[] — ascending YYYY-MM-DD
ds.daily.index · built_at :: string

### ds.daily.summaries — Agency sentences (`daily/data/summaries/2026-08-17.json`)

ds.daily.summaries · schema_version :: number
ds.daily.summaries · publication_date :: string
ds.daily.summaries · gate :: string — which gate version passed this file
ds.daily.summaries · summaries.<agency-slug>.agency :: string
ds.daily.summaries · summaries.<agency-slug>.text :: string — absent when withheld
ds.daily.summaries · summaries.<agency-slug>.withheld :: boolean
ds.daily.summaries · summaries.<agency-slug>.reasons :: array — present only when withheld
ds.daily.summaries · summaries.<agency-slug>.model :: string
ds.daily.summaries · summaries.<agency-slug>.prompt_sha256 :: string
ds.daily.summaries · summaries.<agency-slug>.evidence_sha256 :: string — hash of exactly what the model was shown
ds.daily.summaries · summaries.<agency-slug>.generated_at :: string

### ds.floor.week — Week file (`floor/data/2026-07-20.json`)

ds.floor.week · ok :: boolean — false for a week with no document — see the miss record below
ds.floor.week · week.week_of :: string — the Monday. Primary key.
ds.floor.week · week.congress :: number
ds.floor.week · week.current_status :: string — the House’s own status letter
ds.floor.week · week.created_at :: string — House-local timestamps, no zone
ds.floor.week · week.first_published_at :: string — House-local timestamps, no zone
ds.floor.week · week.last_updated_at :: string — House-local timestamps, no zone
ds.floor.week · week.revision_count :: number — 26 in the week of 2026-07-20
ds.floor.week · week.publish_dates :: string[]
ds.floor.week · week.unknown_categories :: array — anything the parser did not recognise — empty is the expected state
ds.floor.week · week.items[].item_id :: string — the House’s id
ds.floor.week · week.items[].posture :: string — 'suspension' | 'rule' | 'other'
ds.floor.week · week.items[].legis_num_raw :: string|null — as printed, e.g. "H.R. 2715"
ds.floor.week · week.items[].measure :: object|null — {measure_id, type, number, display, chamber, kind, congress}
ds.floor.week · week.items[].unnumbered :: boolean — true for a Rules Committee print with no bill number
ds.floor.week · week.items[].floor_text :: string
ds.floor.week · week.items[].added_at :: string|null|boolean
ds.floor.week · week.items[].removed_at :: string|null|boolean
ds.floor.week · week.items[].removed :: string|null|boolean
ds.floor.week · week.items[].published_at :: string|number
ds.floor.week · week.items[].sort_order :: string|number
ds.floor.week · week.items[].updates[] :: array — {updated_at, published_at, doc_modified}
ds.floor.week · week.items[].files[] :: array — {url, doc_type, added_at, published_at}
ds.floor.week · week.items[].subitems[] :: array — same shape as an item, one level deep
ds.floor.week · week.provenance.source_url :: string
ds.floor.week · week.provenance.retrieved_at :: string
ds.floor.week · week.provenance.sha256 :: string

### ds.floor.miss — Recess record (`floor/data/2026-08-17.json`)

ds.floor.miss · ok :: boolean — false
ds.floor.miss · reason :: string
ds.floor.miss · weekOf :: string
ds.floor.miss · checkedAt :: string
ds.floor.miss · httpStatus :: number — 404, with a 1,245-byte error page behind it

### ds.quotes.input — Quote input (`quotes/data/quotes.json`)

ds.quotes.input · quotes[].quote_id :: string
ds.quotes.input · quotes[].layer :: number — 1 — a fact on the record
ds.quotes.input · quotes[].text :: string — verbatim; the gate re-checks it against the archive
ds.quotes.input · quotes[].source.corpus :: string — closed — 'federal-register' | 'presidential' | 'house-floor', quotes/lib/corpora.mjs's CORPORA; absent means federal-register
ds.quotes.input · quotes[].source.date :: string — federal-register only — joins to a day file
ds.quotes.input · quotes[].source.document_number :: string — federal-register only — joins to documents[]
ds.quotes.input · quotes[].source.doc_uid :: string — presidential only — joins to presidential/data/documents.json documents[]
ds.quotes.input · quotes[].source.measure_id :: string — house-floor only — joins to floor/data/measures.json measures[]
ds.quotes.input · quotes[].source.week_of :: string — house-floor only — which listed week the quote cites; absent takes the earliest
ds.quotes.input · quotes[].source.field :: string — which field of that record the text came from — the legal set differs per corpus
ds.quotes.input · quotes[].action :: object — only ever {kind, evidence} and only for kind attend — every other action is derived from the capture, and there is nowhere here to type a deadline or a link
ds.quotes.input · quotes[].bridge :: string — one sentence stating the mechanism; required whenever basis is not names_sector
ds.quotes.input · quotes[].sectors :: string[] — closed: 'venture-capital' | 'ai' | 'big-tech'
ds.quotes.input · quotes[].basis :: string — closed enum — the honesty gate
ds.quotes.input · quotes[].so_what :: string
ds.quotes.input · quotes[].anchors :: string[] — substrings that must appear in the source
ds.quotes.input · quotes[].query :: string — how to reproduce the selection

### ds.quotes.built — Published quotes (`quotes/quotes.json`)

ds.quotes.built · schema_version :: number
ds.quotes.built · coverage[].corpus :: string — closed — 'federal-register' | 'presidential' | 'house-floor'
ds.quotes.built · coverage[].label :: string — the corpus as the page names it
ds.quotes.built · coverage[].branch :: string — which branch published it — 'executive' | 'presidential' | 'legislative'
ds.quotes.built · coverage[].branch_label :: string
ds.quotes.built · coverage[].unit_noun :: string — what a unit of coverage is here — "day" for the two dated corpora, "week" for the House floor
ds.quotes.built · coverage[].held_units[] :: string[] — every unit the archive holds
ds.quotes.built · coverage[].held_records :: number
ds.quotes.built · coverage[].read_units[] :: string[] — the units read against the sector rule by hand — a unit read in full that yielded nothing is still read
ds.quotes.built · coverage[].unread_units[] :: string[] — held minus read — the gap the page prints
ds.quotes.built · coverage[].unread_records :: number
ds.quotes.built · quotes_by_corpus.federal-register :: number — how many published quotes came from each corpus
ds.quotes.built · quotes_by_corpus.presidential :: number
ds.quotes.built · quotes_by_corpus.house-floor :: number
ds.quotes.built · source_sha256 :: string — hash of the input file this was built from
ds.quotes.built · quotes[].quote_id :: string — unique, slug-safe — quotes/schema.mjs rule 9
ds.quotes.built · quotes[].corpus :: string — which archive the quote was checked against — quotes/lib/corpora.mjs's CORPORA
ds.quotes.built · quotes[].text :: string — verbatim, after whitespace normalization only, in the exact field of the exact record the citation names — the anti-fabrication gate, quotes/schema.mjs rule 1
ds.quotes.built · quotes[].sectors :: string[] — closed list — venture-capital | ai | big-tech, quotes/lib/select.mjs's SECTORS
ds.quotes.built · quotes[].basis :: string — one of five closed values in quotes/lib/select.mjs's BASES — the honesty gate for why the sector is implicated, and branch-neutral: the same route reaches a sector from an agency rule, a proclamation or a bill
ds.quotes.built · quotes[].bridge :: string|null — one sentence stating the mechanism; required whenever basis is not names_sector, forecast and recommendation language banned, no number absent from the capture
ds.quotes.built · quotes[].so_what :: string — one sentence, who is on the hook for what — the only prose on the page that is neither quoted nor definitional, checked against anchors and against the capture for invented numbers
ds.quotes.built · quotes[].anchors :: string[] — at least 2 phrases, 6+ characters, each occurring both in so_what and in the cited document’s own captured text
ds.quotes.built · quotes[].action :: object — assembled from the capture, never typed — {kind, label, certainty, deadline, days_after_publication, evidence, docket_ids, href} — what a reader can do about it. certainty is "statutory" for a printed deadline and "scheduled" for a week the House can still revise
ds.quotes.built · quotes[].query :: string — how the quote was found — non-empty, quotes/schema.mjs rule 7
ds.quotes.built · quotes[].permalink :: string — root-relative — /quotes/q/<quote_id>.html
ds.quotes.built · quotes[].citation :: object — assembled from the capture, never typed — {corpus, branch, authority[], reference, record_id, record_label, dated, date_kind, certainty, links[], effective_on, comments_close_on, register_state, sponsorship, provenance{retrieved_at, capture_id, content_sha256, day_merkle_root, method}} — provenance.content_sha256 is what lets a reader check the quote back against the archive. register_state is presidential-only and absent_from_federal_register there is a choice, not a lapse; sponsorship is house-floor-only and null means not yet retrieved, never no sponsor. house-floor citations also carry postures[] and week_of

### ds.cards.provision — Provision cards (`cards/data/119-hr-6644.cards.json`)

ds.cards.provision · bill.bill_id :: string|number
ds.cards.provision · public_law :: string|number
ds.cards.provision · congress :: string|number
ds.cards.provision · version :: string|number
ds.cards.provision · enacted_date :: string|number
ds.cards.provision · as_of :: string|number
ds.cards.provision · cards[].card_id :: string
ds.cards.provision · cards[].type :: string — 12 types, closed list in cards/schema.mjs
ds.cards.provision · cards[].headline :: string — one citable sentence, two lines maximum
ds.cards.provision · cards[].detail :: string
ds.cards.provision · cards[].provision_id :: string — us/119-hr-6644-enr/sec1001 — the join to the statute
ds.cards.provision · cards[].provision_id_status :: string — 'confirmed' | otherwise — located against the USLM tree
ds.cards.provision · cards[].mechanism :: object — {type, threshold, …} — the machine-readable claim
ds.cards.provision · cards[].query :: string — the call that would reproduce the claim
ds.cards.provision · cards[].layer :: number — 1
ds.cards.provision · cards[].verification :: string — 'primary_source_verified' | 'secondary_source_unverified'
ds.cards.provision · cards[].citation.source :: string
ds.cards.provision · url :: string
ds.cards.provision · retrieved_at :: string

### ds.cards.deadlines — Deadline extraction (`cards/data/deadlines.json`)

ds.cards.deadlines · deadlines[].id :: string
ds.cards.deadlines · cite :: string
ds.cards.deadlines · title :: string
ds.cards.deadlines · section :: string
ds.cards.deadlines · subdivision :: string
ds.cards.deadlines · deadlines[].quoted :: boolean — true when the duty text is quoted verbatim
ds.cards.deadlines · deadlines[].amends :: string — the U.S. Code section touched, where there is one
ds.cards.deadlines · deadlines[].obligated :: string[] — who owes it — empty is a real answer
ds.cards.deadlines · deadlines[].obligated_basis :: string — why that list, e.g. "a repeal obligates nobody"
ds.cards.deadlines · deadlines[].duty :: string
ds.cards.deadlines · duty_type :: string
ds.cards.deadlines · strength :: string
ds.cards.deadlines · deadlines[].interval_text :: string
ds.cards.deadlines · text :: string
ds.cards.deadlines · deadlines[].basis :: string — e.g. 'enactment_default'
ds.cards.deadlines · deadlines[].date :: string|null
ds.cards.deadlines · deadlines[].date_status :: string — 'stated' | 'computed' | 'inferred' | 'not_determinable'
ds.cards.deadlines · deadlines[].computation :: string — the arithmetic, written out
ds.cards.deadlines · deadlines[].recurrence :: object — {recurs, …}
ds.cards.deadlines · deadlines[].provision_id :: string
ds.cards.deadlines · counts.* :: number — totals by date_status, reconcilable against the rows

### ds.cards.state — State cards (`cards/data/wa-119-hr-6644.state-cards.json`)

ds.cards.state · cards[].subject_type :: string — 'state'
ds.cards.state · cards[].points :: string[] — Who / What / Kept / Here / Penalty
ds.cards.state · cards[].note :: string
ds.cards.state · cards[].state.jurisdiction :: string
ds.cards.state · name :: string
ds.cards.state · cards[].state.reach :: string — closed enum in cards/state.mjs REACH_CLASSES
ds.cards.state · cards[].state.reach_basis :: string — why this provision reaches this state at all
ds.cards.state · cards[].state.bearers :: array — who carries the effect here
ds.cards.state · cards[].state.direction :: string

### ds.cards.site — Built card set (`cards/site/cards.json`)

ds.cards.site · source_sha256 :: string
ds.cards.site · draft :: boolean
ds.cards.site · unverified_card_ids :: string[]
ds.cards.site · layer :: number
ds.cards.site · cards[] :: array — as above

### ds.lexicon — Domain language (`lexicon/domain-language.json`)

ds.lexicon · schema_version :: number|string
ds.lexicon · as_of :: number|string
ds.lexicon · count :: number|string
ds.lexicon · categories[] :: array — {id, title}
ds.lexicon · aliases :: object — alias → entry id
ds.lexicon · entries[].id :: string
ds.lexicon · entries[].term :: string
ds.lexicon · entries[].category :: string
ds.lexicon · entries[].cite :: string — the authority, e.g. "2 U.S.C. § 641"
ds.lexicon · entries[].aliases :: string[]
ds.lexicon · entries[].short :: string
ds.lexicon · entries[].text :: string
ds.lexicon · entries[].note :: string
ds.lexicon · entries[].see_also :: string[]
ds.lexicon · entries[].url :: string

### ds.plain — Plain language (`plain/data/plain.json`)

ds.plain · schema_version :: number
ds.plain · count :: number
ds.plain · model_fingerprint :: string — the model this glossary was last checked against
ds.plain · categories[] :: array — {id, title, blurb}
ds.plain · entries[].slug :: string
ds.plain · entries[].term :: string
ds.plain · entries[].category :: string
ds.plain · entries[].plain :: string — standalone lay definition
ds.plain · entries[].more :: string|null
ds.plain · entries[].canonical :: object — {label, url, kind} — kind is statute|rule|official|ours
ds.plain · entries[].lexicon :: string|null — slug in domain-language.json
ds.plain · entries[].see_also :: string[]
ds.plain · entries[].covers :: string[] — node ids on this page that the entry explains
ds.plain · entries[].where_you_see_it :: string|null
ds.plain · entries[].url :: string — /plain/#<slug>

### ds.docmodel — The map itself (`docs/data-model/model.mjs`)

ds.docmodel · LANES[] :: array — {id, title, blurb} — the four columns
ds.docmodel · PIPELINES[] :: array — {id, label, blurb} — the filter chips
ds.docmodel · NODES[].id :: string
ds.docmodel · lane :: string
ds.docmodel · group :: string
ds.docmodel · title :: string
ds.docmodel · status :: string
ds.docmodel · NODES[].registry[] :: array — {set, source_id} — checked against tools/sources/
ds.docmodel · NODES[].fields[] :: array — {name, type, note} — checked against a real record
ds.docmodel · NODES[].sample :: object — {file} — read and trimmed at build time
ds.docmodel · NODES[].sampleWithheld :: string — checked against .vercelignore
ds.docmodel · EDGES[].from :: string
ds.docmodel · to :: string
ds.docmodel · via :: string
ds.docmodel · note :: string
ds.docmodel · status :: string

## Published surfaces

### sf.mcp — MCP server (`api/mcp.js`)

sf.mcp · data :: object — the tool’s payload
sf.mcp · meta.as_of :: string
sf.mcp · meta.snapshot_id :: string|null
sf.mcp · meta.coverage_caveats :: string[] — what is missing, stated unprompted
sf.mcp · meta.citations :: array
sf.mcp · meta.server :: string
