Skip to content
indraft
Start free

Documentation

Safe writes

An agent retries. It runs twice on the same instruction, races another agent, and occasionally misreads what it already wrote. Every one of those is a normal Tuesday, so the write path is built for it rather than around it.

Every mutating call takes the same envelope

idempotencyKey A replay with the same key returns the ORIGINAL result marked as a replay, and creates nothing. Honored for 30 days. Reusing a key with materially different input is refused rather than silently applied.
expectedVersion A write whose expected version does not match the current one is refused with stale_version and the current version. Newer state is never overwritten by an agent working from an old read.
dryRun Runs the real operation and rolls it back, returning what would have happened. Not a prediction: a prediction drifts from the code it predicts, and a preview that lies is worse than no preview.
assertionKind Whether this was observed, inferred, imported, or supplied by a person. Carried through to every surface that shows the value.
overrideStanding Apply this write even when the value standing in the record was asserted more strongly than this one. Absent means no, which is the safe answer for a re-run. WITHOUT IT, a write can be accepted and change nothing: precedence is confirmed > user_supplied > observed > imported > inferred, and a weaker claim leaves the standing value in place and reports the field in `held[]` rather than failing. That is the whole of why a write can return 200 and not take. WITH it, this write wins regardless of what it is overruling, INCLUDING a value a person confirmed, so an agent that sets it by default has switched the provenance mechanism off. Set it per write, when the caller knows its claim supersedes what is there.
attributionLabel A caller-supplied label for a scope of work. It grants nothing, and every surface presents it as caller-supplied rather than as verified.

The workspace decides what the override may do

A reviewer asked whether she could stop her agent setting overrideStanding, and for a while the answer was no: it was a per-write flag, nothing gated it, and the only control was the instruction you gave your agent. That is not a control anybody can evidence. There are three settings now, and they are set by a person.

Setting What a write carrying the flag does
allowed Skips the precedence rule, including over a value somebody confirmed. The default, and what every workspace had before this existed.
confirmed_protected Overrides anything except a value a person confirmed. An agent can still correct its own earlier guess, and cannot quietly overwrite somebody's checked answer. This is what most people mean.
refused The write is refused outright, with a code that says why. Not quietly downgraded: a caller that believes it wrote is worse off than one that was told no.

Only a person can change it. No credential can, whatever scopes it holds, for the same reason no credential can confirm a value: an agent that could switch off its own restraint would leave the setting worth nothing. Any credential can READ it, so an agent refused by it can tell you why rather than retrying.

Every use of the flag is now named on its own ledger row rather than inferred from one. Before this it was derivable, by noticing that a write carrying a weaker claim had changed a field it should have been held on, which is not something anybody reconstructs while reading a page of changes. One limit worth stating: rows written before this shipped read as no override, which is true of all but the ones that used it, and those cannot be labelled after the fact.

An upsert can refuse to guess

Matching uses real identity evidence: a normalized domain for a company, a normalized email for a contact. Name similarity alone matches nothing, ever. When identity is genuinely uncertain the call returns ambiguous with candidates and commits NOTHING, and you choose. That refusal is the feature: a CRM that merges two different people who share a name has destroyed something you cannot get back.

A mutation and its ledger row commit together

Every write records the actor, the operation, the target, the request, the outcome, the access path, and the field-level diff, in the same transaction as the change itself. A partially applied mutation is not something you have to detect, because it is not something you can observe.

Undo is offered only where it works

A field change can be compensated. A record creation cannot: undoing one would mean a hard delete or an archive, and presenting an archive as an undo would be a lie. A merge is inverted by unmerge rather than compensated field by field, because a partial restoration that looks complete is worse than a refusal. Anything irreversible is marked as such BEFORE the click, never by failing after it.