papers/<id>.json: everything about one paper except its original bytes and title. paperVersion is required; other members are optional: an omitted member is not described (a merge leaves the library's value unchanged; a new paper uses the app default). The runtime also checks detail ID uniqueness, origin-specific rules, evidence against the reading, reference resolution against the manifest, the native analysis budget (50,000 nodes, 2 MiB) and the type rule (custom needs selected generic).
Top Level
| Member | Type | Rules |
|---|---|---|
paperVersion required | 1 | |
createdAt | timestamp | |
automaticTitle | boolean | |
type | object | closed detected/suggested come from the reading (detected null means the paper was never read); selected and custom are the person's choice; agentSuggestion is an external agent's proposal awaiting review. |
details | array of detail | max items 562 |
removedSuggestions | array of removed | max items 512 |
personIds | array of id | max items 64; unique |
builtInFolder | null or one of "identity", "visas", "notices", "applications", "residency", "work-authorization", "travel-entry", "study", "home", "finance", "health", "education", "work", "family", "legal", "other" | |
reminder | null or object |
Definitions
id
string · pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
timestamp
string · min length 1; max length 19; pattern ^(0|[1-9][0-9]{0,18})$
isoDate
string · min length 10; max length 10; pattern ^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$
unit
number · min 0; max 1
kind
one of "generic", "i20", "i94", "passport", "visa", "i797", "employment-authorization", "drivers-license", "social-security", "birth-certificate", "marriage-certificate", "tax", "insurance"
fieldKey
one of "program-start-date", "program-end-date", "sevis-id", "admission-date", "admit-until", "class-of-admission", "admission-record-number", "given-name", "family-name", "date-of-birth", "country-of-birth", "country-of-citizenship", "nationality", "document-number", "passport-number", "issuing-country", "issue-date", "expiration-date", "place-of-birth", "sex", "full-name", "receipt-number", "case-type", "notice-type" … (78 values)
valueType
one of "text", "date", "duration-of-status"
label
string · min length 1; max length 80; pattern ^(?![ \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000])(?![\s\S]*[ \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]$)[^\u0000-\u001f\u007f-\u009f\ud800-\udfff]+$
region
Normalized to the rendered page (0..1). box is [left, top, right, bottom] with left <= right and top <= bottom.
evidence
One of:
evidence: variant 1
A line of this paper's reading (readings/<id>.json must exist and contain it).
| Member | Type | Rules |
|---|---|---|
page required | integer | min 0; max 199 |
block required | integer | min 0; max 1999 |
line required | integer | min 0; max 9999 |
evidence: variant 2
Text quoted from the original page by an external agent, with an optional location. Not an OCR line.
| Member | Type | Rules |
|---|---|---|
page required | integer | min 0; max 199 |
quote required | string | min length 1; max length 8192; pattern ^[^\u0000-\u0008\u000b-\u001f\u007f-\u009f\ud800-\udfff]*$ |
region required | null or region |
detail
origin reading: found by the app's on-device reading; id [a-z][a-z0-9_]{0,95}, 1-16 reading-line evidence, review required, confidence and agentId null. origin person: a custom detail the person typed; key other, label 0-80 scalars, value 0-500 scalars, valueType text, no evidence, concerns, confidence, agentId or review. origin agent: proposed by an external AI agent; id is a UUID, agentId names manifest.agents, value non-blank, label required for key other, optional confidence and 0-16 evidence items, review required (pending until confirmed). Values are limited to 4096 UTF-8 bytes.
| Member | Type | Rules |
|---|---|---|
id required | string | min length 1; max length 96; pattern ^([a-z][a-z0-9_]{0,95}|[A-Za-z][A-Za-z0-9_-]{0,95}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$ |
origin required | one of "reading", "person", "agent" | |
key required | fieldKey | |
label required | null or string | |
value required | string | min length 0; max length 4096 |
normalizedValue required | null or string | |
valueType required | valueType | |
concerns required | array of one of "invalid-date", "ambiguous-date", "conflicting-values", "read-by-ai" | max items 3; unique |
evidence required | array of evidence | max items 16 |
confidence required | null or unit | |
agentId required | null or id | |
review required | null or object |
removed
One of:
removed: reading
A reading suggestion the person removed, remembered so a re-read does not bring it back. pages ascending; sdkFieldId and sdkDocumentType are both null or both set.
| Member | Type | Rules |
|---|---|---|
origin required | "reading" | |
id required | string | min length 1; max length 96; pattern ^[a-z][a-z0-9_]{0,95}$ |
identity required | null or object |
removed: agent
An agent suggestion the person rejected, remembered so importing the same proposal again does not bring it back.