Snapshots
A snapshot is one source’s current set of documents — all of it, or an explicitly partial part. It is the operation for “here is everything this customer gave us now”: you send the set, the Brain compares it with what the source said before and with what the Brain has accepted, and you get a plan before anything changes what a read serves.
Nothing a snapshot holds is served — by /context, /search, /query or the
document listing — until you apply its plan, and applying goes through the
Brain’s own admission policy, so a document that
disappeared from the set is retired only through a decision. The one
exception is a table’s new rows, which reads
serve as soon as they are added, marked as still being processed.
The journey:
- Open a snapshot of the source.
- Add its documents, up to 100 per request — or a table, one record per row.
- Seal it as
completeorpartial. The seal runs in the background: the call returns at once. - Poll the snapshot. It is planned, then — when the plan has nothing a person must decide first — applied by itself.
- Read the plan — what each document changes — and the findings — where the snapshot’s own documents disagree.
- Apply the plan revision you read, only when the plan waits for you.
- Review what the policy held back.
- Every read after that is receipted with the exact versions it served.
When an apply stages a review change, it opens a snapshot Proposal.
The snapshot’s application names it as review.proposalId. Inspect that Proposal to see its pinned diff and member ChangeSet,
then use the existing review lifecycle to decide what reaches main.
Open a snapshot
Section titled “Open a snapshot”curl -X POST "$API/v1/brains/tenant:acme/sources/acme-content/snapshots" \ -H "authorization: Bearer $NICIA_KEY" \ -H "idempotency-key: acme-content-2026-09-23"{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "acme-content", "status": "open", "documents": 0, "bytes": 0, "openedAt": "2026-09-23T10:06:45.984Z", "expiresAt": "2026-09-24T10:06:45.984Z" } }}The Idempotency-Key is required: a retry with the same key answers the
snapshot it already opened, with 200 instead of 201. A source has at most
one open snapshot, so opening another supersedes the first. An open snapshot
expires after 24 hours.
Add documents
Section titled “Add documents”curl -X POST "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c/documents" \ -H "authorization: Bearer $NICIA_KEY" \ -H "content-type: application/json" \ -d @documents.json{ "documents": [ { "id": "catalog", "title": "Product catalog", "text": "# Catalog\n\nAcme Widget costs $11.", "metadata": { "drive_file": "1x9Qa" } }, { "id": "gizmo", "text": "# Gizmo\n\nGizmo costs $35." } ]}{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "acme-content", "status": "open", "documents": 2, "bytes": 58, "openedAt": "2026-09-23T10:06:45.984Z", "expiresAt": "2026-09-24T10:06:45.984Z" }, "documents": [ { "id": "catalog", "status": "changed" }, { "id": "gizmo", "status": "new" } ] }}A snapshot document is a document with a required
id — your id for it within the source, which is how the next snapshot is
compared with this one. Each is acknowledged against the version the source
serves now: new, changed, or unchanged. An unchanged document stores
nothing new.
Documents are Markdown text; converting a PDF or a slide deck is your step, as
it is for POST /documents. An id may appear once per snapshot: repeating one
is 409, and nothing in that request is stored.
Add a table
Section titled “Add a table”A list you keep in a spreadsheet — leads, accounts, invoices — goes in as a table instead of documents: CSV or TSV text with a header row, and a mapping that says which declared kind the rows are and which column is which field.
curl -X POST "$API/v1/brains/tenant:acme/sources/leads/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c/tables" \ -H "authorization: Bearer $NICIA_KEY" \ -H "content-type: application/json" \ -d @leads.json{ "format": "csv", "text": "Email,Status,Deal size,Notes\nada@acme.com,new,\"1,200\",Met at the conference\nbo@zeta.io,contacted,800,", "mapping": { "kind": "lead", "identityColumn": "Email", "columns": { "Email": "email", "Status": "status", "Deal size": "deal_size_usd" } }}{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "leads", "status": "open", "documents": 2, "bytes": 122, "openedAt": "2026-09-30T10:06:45.984Z", "expiresAt": "2026-10-01T10:06:45.984Z" }, "rows": [ { "row": 2, "id": "ada-acme-com", "status": "new" }, { "row": 3, "id": "bo-zeta-io", "status": "new" } ] }}Each row becomes one document of the source, and the record it describes:
- Its id is the identity column’s value made into a slug —
ada@acme.comisada-acme-com— so the record is addressed by the value you already use. The next upload of the same list finds it by the same id. - Its text is every column, mapped or not, as
header: valuelines in header order, so nothing in the file is lost. It is the evidence a receipt pins, but it is not indexed for/searchpassages: a row reaches reads through its record. - Its row number comes back in
rows[].row(the header is row 1, as in a spreadsheet) and is stored as the document’srowmetadata. A row whose content did not change keeps the version, and the row number, it was first stored with.
Sealing reads every mapped cell into its field at once, without a model and
without waiting in extracting. A cell is read as its field’s type — 1,200 is the number 1200,
Contacted is the enum value contacted, 2026-11-02 is a date. An empty
cell states nothing. A cell the field cannot hold — a status outside the
declared values, $5k for a number, next week for a date — is kept as a
statement aimed at that field, and the rest of the row is read as usual.
The whole table is refused with 400, and nothing in it is stored, when:
- the mapping names a kind the schema does not declare, a field the kind does not declare, or a column that is not a header — or maps two columns to a field that holds one value;
- a row’s identity is empty, or has no letter or digit to make an id from;
- two rows name the same record (
ada@acme.comandAda@Acme.comare one). Row order cannot say which one is right, so neither is picked.
The message names the rows behind each reason. A snapshot holds documents or a table, never both, and every table added to one snapshot carries the same mapping; a large file can be sent in several requests of up to 5,000 rows each.
Refreshing works as it does for documents. Seal next week’s export as
complete, and a lead it no longer holds is missing: its record, if only
this source supports it, is proposed for deletion. Seal a week’s new rows as
partial, and nothing is withdrawn. A value a teammate set by hand — a lead
marked contacted that the export still calls new — plans as
contradicts on a field declared single (disagrees otherwise) and waits
in Review; the upload never overwrites it. The value stays the teammate’s
until a person changes it: if next week’s export also says contacted and
the week after says lost, that change waits in Review too.
Rows answer before the apply
Section titled “Rows answer before the apply”A table’s rows that are new to its source are answerable as soon as the
request that added them returns, while the snapshot is sealed, planned and
applied in the background. /query, /context, GET /records/{id}, and MCP search and
fetch serve each one as the record the apply will create, marked:
- the record carries
pending: { source, snapshot }, and a/contextitem also carriesstatus: "pending"; - the answer carries one
import_processingwarning per import, naming its source: “The import of source ‘leads’ is still being processed: 12 records in this answer are read from its uploaded rows and have not been applied.”; - the receipt pins each such row with item status
pendingand the snapshot, and its/nowreports, for each, whether the apply accepted it (applied, with the record’s version), it is stillpending, or the import settled without it (not_applied).
A pending row is never served over anything the Brain holds. It is served only
while no record has its id, so a record a person creates by hand, or one the
apply has already written, is served as itself. A refresh’s changed and
withdrawn rows serve their applied values until the apply decides them, and
the warning says so. A pending record’s token matches no write: a
conditional write against it is 409.
An agent’s table (a Brain key) is served this way only when the Brain’s policy
would admit that agent’s new records of the kind; on a reviewed Brain its
rows wait for the apply. A snapshot that is cancelled, superseded or expires
stops serving its rows, as does one a later snapshot of the same source
replaces.
Reconcile in the console
Section titled “Reconcile in the console”Open Sources and the snapshot’s worksheet to inspect incoming rows beside accepted values at planning time, with their support and evidence. Search and All, Changes, and Exceptions filter the displayed plan page; the whole-plan counts remain separate.
Applying can admit routine changes while a conflict with a person-set value waits in Review. Follow the resulting Review link to decide that held change. A missing row in a complete snapshot withdraws this source’s support; any resulting record deletion is separately governed. A partial snapshot withdraws nothing merely because a row is absent.
curl -X POST "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c/seal" \ -H "authorization: Bearer $NICIA_KEY" \ -H "content-type: application/json" \ -H "idempotency-key: acme-content-2026-09-23-seal" \ -d '{ "completeness": "complete" }'{ "completeness": "complete" }Sealing fixes what the snapshot is compared with — what the source serves at
that moment and the Brain’s schema — and answers 202 at once, with the
snapshot still open and processing.state queued: the seal is recorded,
and a worker runs it in the background. From that moment the snapshot accepts
no more documents. Repeating the seal with the same Idempotency-Key answers
where it stands, and retries a seal that failed. completeness is the one
decision you make here:
completesays the snapshot is the source’s whole content. A document the source serves that the snapshot leaves out is planned asmissing, and applying the plan proposes retiring it.partialsays nothing about documents the snapshot leaves out. They keep being served, exactly as they are.
apply is optional: auto (the default) lets the plan apply
itself, and manual only plans it, so you can
read the plan and decide with apply:
{ "completeness": "complete", "apply": "manual" }Wait for the plan
Section titled “Wait for the plan”curl "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c" \ -H "authorization: Bearer $NICIA_KEY"{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "acme-content", "status": "extracting", "completeness": "complete", "documents": 2, "bytes": 58, "openedAt": "2026-09-23T10:06:45.984Z", "sealedAt": "2026-09-23T10:06:46.025Z", "expiresAt": "2026-09-24T10:06:45.984Z" }, "acks": { "new": 1, "changed": 1, "unchanged": 0 }, "pendingRows": 0, "table": false }}The status read is safe to poll: it returns no content and commits no receipt.
A sealed snapshot is extracting while a model reads each added or changed
document into the fields your Brain’s schema declares,
then planned. A Brain whose kinds declare no fields beyond their identity has
nothing to extract, and plans at once — its plan compares documents only.
processing says how far the background work has got:
processing.state |
Meaning |
|---|---|
queued |
Waiting for a worker; step is seal or apply. |
sealing |
Storing the documents and fixing the base. |
planning |
Comparing them with what the source serves and the Brain holds. |
applying |
Deciding the plan. |
applied |
Done. application says what landed. |
needs_review |
Waiting for a person: contested values in Review, or a plan that does not apply itself (heldBecause). |
failed |
Stopped; error says why. Repeat the seal or the apply to retry. A table’s rows stay answerable meanwhile. |
When a plan applies itself
Section titled “When a plan applies itself”Once planned, the plan applies by itself, under the Brain’s admission policy, unless it is held for a person:
- A seal that asked for
apply: "manual"waits (heldBecause: "manual"). - On a
reviewedBrain nothing applies itself, whoever imported it (heldBecause: "reviewed_brain"). - A key’s table applies itself only when the policy would admit that key’s
new records of the kind (
heldBecause: "agent_rows_held"otherwise), the same rule that decides whether its rows answer before the apply. - A key’s documents never apply themselves (
heldBecause: "agent_documents").
A person’s import (the console, or a management key) applies itself on every
other rung. Applying never overwrites a value a person or another source
supports: those contests wait in Review as one Proposal, the snapshot reports
awaiting_review, and everything else lands. A held plan waits for
apply, and expires after 7 days if nobody applies it.
A plan that went stale before its own apply ran (something it read moved) is
planned again and checked against these rules afresh, up to 3 times, before
the apply reports failed. An apply you asked for is never replanned under
you.
Read the plan
Section titled “Read the plan”curl "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c?plan=true" \ -H "authorization: Bearer $NICIA_KEY"{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "acme-content", "status": "planned", "completeness": "complete", "documents": 2, "bytes": 58, "openedAt": "2026-09-23T10:06:45.984Z", "sealedAt": "2026-09-23T10:06:46.025Z", "plannedAt": "2026-09-23T10:06:46.068Z", "expiresAt": "2026-09-30T10:06:46.068Z" }, "acks": { "new": 1, "changed": 1, "unchanged": 0 }, "pendingRows": 0, "table": false, "plan": { "revision": 1, "counts": { "added": 1, "changed": 1, "unchanged": 0, "missing": 1 }, "observationCounts": { "new": 0, "restated": 0, "changed": 1, "contradicts": 1, "disagrees": 0, "withdrawn": 1, "unknown": 0 }, "findingCounts": { "duplicate": 0, "disagrees": 0, "contradicts": 0 }, "entries": [ { "id": "catalog", "class": "changed", "contentHash": "sha256:5b1f0c…", "baseContentHash": "sha256:9e47d2…", "observations": [ { "class": "changed", "kind": "product", "identity": "Acme Widget", "field": "price_usd", "record": { "id": "acme-widget", "version": 1 }, "value": 11, "quote": "Acme Widget costs $11.", "prior": [10], "supportedBy": [{ "kind": "source", "source": "acme-content", "keyId": "key_7f3a1c" }] } ] }, { "id": "gizmo", "class": "added", "contentHash": "sha256:c2d8a1…", "observations": [ { "class": "contradicts", "kind": "product", "identity": "Gizmo", "field": "price_usd", "record": { "id": "gizmo", "version": 1 }, "value": 35, "quote": "Gizmo costs $35.", "prior": [30], "supportedBy": [{ "kind": "human" }] } ] }, { "id": "launch", "class": "missing", "baseContentHash": "sha256:07ae3f…", "observations": [ { "class": "withdrawn", "kind": "product", "identity": "Bolt", "field": "price_usd", "record": { "id": "bolt", "version": 1 }, "prior": [50], "supportedBy": [{ "kind": "source", "source": "acme-content", "keyId": "key_7f3a1c" }], "effect": "delete_record" } ] } ], "receipt": "0198f3a2-7c41-7d3e-9a10-5b6c31c280a4" } }}?plan=true pages the plan, up to 100 documents at a time; walk the rest with
cursor=<nextCursor>. revision is what you apply. Each page is a read of
what the Brain has accepted, so it commits a receipt of kind plan and returns
its id.
Every document has one class:
| Class | Means |
|---|---|
added |
A document id the source has not sent before. |
changed |
Its content differs from the version the source serves. |
unchanged |
Same content. Nothing to do. |
missing |
Served now, absent from a complete snapshot. |
Every observation — one record field a document states — compares the
value, and the quote it was read from, with what the Brain has accepted.
supportedBy says who stands behind the accepted value: who last set it — a
person (human), an agent, or a source — and every source whose served
documents state it.
| Class | Means |
|---|---|
new |
Nothing is accepted at this record and field yet. |
restated |
Equal to the accepted value. Nothing to write. |
changed |
Replaces a value no person or other source supports, which none of this source’s documents states any more. |
contradicts |
Differs from a value a person or another source supports, on a field declared single. |
disagrees |
The same, on a field with no single declaration. The accepted value is kept. |
withdrawn |
This source no longer states a value it supported. effect says what that would do. |
unknown |
Extraction, identity, or comparison failed. The source’s earlier support is kept, and reason says what failed. |
A value a person or another source supports is never overwritten by a
snapshot, even after the source agreed with it for a while. That holds whoever sends it: a contradiction still waits in Review at every
level below L4, including one sent by a person, whether from the console or
with a management key (nsk_). Only changed writes over an accepted value, and only when no person or other
source supports it and this source has stopped stating it in every one of its
documents. A value an agent set gives way when the source says something new,
not when it restates what it said before the agent wrote. A document whose extraction failed makes its entries unknown,
never withdrawn.
Three rules keep a plan from choosing for you:
- A source that disagrees with itself picks nothing. When the source’s own
documents — this snapshot’s, and those a
partialsnapshot leaves out — state different values for onesinglefield, every document is listed ascontradictswith its own value and quote andreason: "intra_source". No value is written; the entries wait for review until the documents agree again, or a person sets the field. - A contradiction is listed under every document that states it, and those documents wait for review together — no fewer, no more.
- A decided contradiction is not asked again. Once a reviewer has decided a
contradiction, a later snapshot restating the same value is
disagreeswithreason: "already_decided", and nothing waits for it. A different value asks again.
Read the findings
Section titled “Read the findings”curl "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c?findings=true" \ -H "authorization: Bearer $NICIA_KEY"?findings=true pages what the snapshot’s own documents say about each
other, grouped by record and field: duplicate (documents restate one
value), disagrees (they state different values), and contradicts (they do,
on a field declared single). Each finding lists every document, value and
quote behind it. Like a plan page, a findings page commits a plan receipt.
The first complete snapshot of a source into a Brain that holds nothing from
it yet is an onboarding scan: every document is added, every observation
new — except where the documents contradict each other on a single field,
which is contradicts and lands nothing — and the findings are the
substance: the places a customer’s own material disagrees with itself before
any agent reads it.
curl -X POST "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c/apply" \ -H "authorization: Bearer $NICIA_KEY" \ -H "content-type: application/json" \ -d '{ "planRevision": 1 }'{ "planRevision": 1 }{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "acme-content", "status": "planned", "completeness": "complete", "documents": 2, "bytes": 58, "openedAt": "2026-09-23T10:06:45.984Z", "sealedAt": "2026-09-23T10:06:46.025Z", "plannedAt": "2026-09-23T10:06:46.068Z", "expiresAt": "2026-09-30T10:06:46.068Z", "processing": { "state": "queued", "step": "apply" } } }}Apply is for a plan that waits for you. It
answers 202 at once and a worker decides the plan in the background; poll the
snapshot until processing.state is applied or needs_review, and read
what was decided from its application:
{ "data": { "snapshot": { "id": "01a0cdbb-66e1-75be-a056-c758c4b3ee4c", "source": "acme-content", "status": "awaiting_review", "completeness": "complete", "documents": 2, "bytes": 58, "openedAt": "2026-09-23T10:06:45.984Z", "sealedAt": "2026-09-23T10:06:46.025Z", "plannedAt": "2026-09-23T10:06:46.068Z", "expiresAt": "2026-09-30T10:06:46.068Z", "appliedPlanRevision": 1, "appliedAt": "2026-09-23T10:06:46.099Z", "reviewChangeId": "47b38dd1-48d1-88b1-82c7-1d73ab8fc25a", "processing": { "state": "needs_review" } }, "acks": { "new": 1, "changed": 1, "unchanged": 0 }, "application": { "planRevision": 1, "admitted": { "changeIds": ["brn_9c2a1f:6:1:0", "brn_9c2a1f:6:1:1"] }, "review": { "changeId": "47b38dd1-48d1-88b1-82c7-1d73ab8fc25a", "proposalId": "a5e24e48-3829-4b25-a138-70c9d46422e0" }, "rejected": [], "counts": { "admitted": 1, "review": 2, "rejected": 0 } }, "pendingRows": 0, "table": false }}An apply decides the revision, document by document, under the Brain’s
write policy. A document and every field and statement
read from it share one outcome, and so does every write to one record, so no
passage is served while part of what was read from it waits for review.
counts are documents:
- Admitted documents are served at once and their records written.
- Review documents wait in one review change,
review.changeId. Until a reviewer publishes it, the source keeps serving what it served before. - Rejected documents are listed with the policy’s reasons and never staged.
At the default rung of the write policy a routine
update is admitted, and these wait for a person: a contradicts entry, a
withdrawn entry, a missing document, and an unknown entry — and a
substantive change to a field declared consequence: review (review
declarations). A
contradiction is staged as a statement recording what the source said and a
separate proposed value, so the reviewer can keep the accepted value and record
the disagreement, or adopt the new one. A record is published as one write, so when the same snapshot also changes another field of that record the proposed value is its own operation, listed beside the record’s routine change and naming the contested fields. Approving the change, or selecting everything but that operation, keeps the accepted value and the statement still records what the source said; selecting it publishes the record with the new value. A contested value left unselected is declined, not deferred. When the source contradicts itself, each
candidate is staged as a statement and no value is proposed: the record is
created or kept without the contested field, and the documents stating the
candidates wait with them.
Extraction reads declared fields only. Prose no declared field captures is
not interpreted and produces no statement: the document is served and indexed
as it is, so nothing it says is lost, and a search or /context read finds it
there. A statement quoting a document exists only when something cites it, such
as a standing answer resting on a section of it. The
statements a snapshot does write are typed: a candidate a declared field cannot
hold, a disagreement with accepted state, or an extra value of a multiple
field. Once no document the source serves states such a value any more — every
document that did is missing, or changed and no longer says it — apply
retracts the statement with those documents, in the same outcome: a retired
document’s statements wait in its review. A retracted statement stays readable
with status: "retracted"; /context no longer serves it.
Applying the same revision again answers its application once it is
decided, and retries an apply that failed. An apply that fails with an
error starting snapshot_plan_stale found that something the plan read has
moved since — what the source serves, a record it compared with, a record it
expected to create, or the Brain’s schema. Nothing was applied: seal again
(with a new Idempotency-Key) and read the new revision. Documents already
read are not read again. A plan that applies itself replans on its own first
(see When a plan applies itself).
Review what waits
Section titled “Review what waits”The snapshot reports awaiting_review with the reviewChangeId it waits on.
The change is in the review queue, GET /v1/brains/{handle}/changes?status=staged,
with the records it writes and the documents it serves or retires
({ source, id, action }, action being serve or retire). Inspect it with GET /v1/brains/{handle}/changes/{changeId}/lifecycle: every
operation names the document ({ source, id }) it serves or retires, or the
record ({ kind, id }) it writes, and the operations it depends on. A record
read from a document depends on the operation that serves that document.
Approve and publish the whole change, reject it, or select part of
it — for a contradiction, the statement alone keeps the
accepted value and records the disagreement, and the statement with the value
adopts it, along with the record’s other field changes. Once the change is decided, the snapshot settles applied the next
time it is read.
Applying a later snapshot of the same source recomputes, in an earlier one’s
still-pending review, whatever the later snapshot covers: a complete one
covers every document, a partial one the documents it holds.
Cancel
Section titled “Cancel”curl -X POST "$API/v1/brains/tenant:acme/sources/acme-content/snapshots/01a0cdbb-66e1-75be-a056-c758c4b3ee4c/cancel" \ -H "authorization: Bearer $NICIA_KEY"Cancelling ends a snapshot that has not been applied. Its documents are never served.
Receipts after a refresh
Section titled “Receipts after a refresh”Every /context, /search and /query receipt pins the exact version of each
document it served, named by the source and your id, and the receipt’s
snapshot carries an evidenceSetDigest that changes whenever the set of served
documents does. After a refresh, /receipts/{receiptId}/now reports which
cited documents changed or were retired, and the text a receipt
pinned is still readable —
including a retired document’s — by the key that made the read.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Documents per add request | 100 |
| Documents per snapshot | 2,000 |
| Rows per table request | 5,000 |
| Bytes per table request | 10 MB |
| Columns per table | 200 |
| Rows per snapshot | 20,000 |
| Same-apply statement targets | 500 |
| Bytes per snapshot | 50 MB |
| Plan or findings page | 100 |
| Typed values per document | 200 |
| Statements per document | 100 |
| An open snapshot expires after | 24 hours |
| A planned snapshot expires | 7 days after it is planned |
A document whose extraction exceeds either per-document cap fails as a whole:
its entries are unknown, with a reason naming the cap, and nothing from it
is truncated into the plan. Split a long document, and send tabular data (one
record per row) as a table rather than as a document.
An apply of any size runs in the background, in bounded steps. One that
writes more than 400 records commits them first in batches of at most that
many, each its own write, and then serves the documents in a last write. A
large one is decided once over the whole plan, then written a few batches at a
step, with processing.progress counting the batches: each row’s record is
readable as soon as its batch lands, and every other row stays readable,
marked pending, until it does. A retry after an interruption resumes from
what committed, and a worker that stops part-way is retried by itself. The only plan refused for size is one holding more than 500
statements about records it is creating in the same apply.
What a snapshot does not do
Section titled “What a snapshot does not do”- It does not convert files. Documents are Markdown text, and a table is
CSV or TSV text; export a spreadsheet (
.xlsx) as CSV first. - It does not read perfectly. A model reads documents into your declared
fields, and it can miss or misread a value. The plan shows the quote behind
every value so a person can check it, and a failed read is
unknown, never a withdrawal. - It compares values, not units. A field compared as
contradictsneeds asingledeclaration; a difference the schema cannot describe — a unit, a currency, a qualifier — is at mostdisagreesorunknown. - It does not merge two sources. A source is one per name in a Brain; any key that may write continues it, and two names are two sources.