Reference
retract / supersede
Withdraw a committed entry or replace it with a newer one.
retract()
Marks a committed entry as retracted. Retracted entries are excluded from attune() and reckon(). Only the original author can retract.
Signature
field.retract(input: RetractInput): Promise<void>
type RetractInput = {
id: string
intent: string
agent: string
}
Parameters
| Parameter | Required | Description |
|---|---|---|
id | ✓ | The id of the committed entry to retract. |
intent | ✓ | Why the entry is being retracted. Must be ≥ minIntentLength characters after trimming. |
agent | ✓ | Must match the agent on the original entry. |
Behavior
- Author-only —
agentmust match the entry's original author. - Idempotent — retracting an already-retracted entry is a no-op.
- Final — a retracted entry cannot be superseded. Use
supersede()if you want to replace rather than remove. read()still returns retracted entries withstatus: "retracted".
Errors
| Code | When |
|---|---|
ENTRY_NOT_FOUND | No entry with the given id exists |
RETRACT_NOT_AUTHORIZED | agent does not match the entry's author |
INTENT_REQUIRED | intent is missing, null, or undefined |
INTENT_TOO_SHORT | intent.trim().length < minIntentLength |
Example
await field.retract({
id: 'entry-abc123',
intent: 'data was based on a misread of the source — incorrect price figure',
agent: 'researcher',
})
supersede()
Creates a new committed entry that replaces a previous one. The predecessor is marked "superseded" and removed from attune() and reckon().
Signature
field.supersede(input: SupersedeInput): Promise<SupersedeResult>
type SupersedeInput = {
superseding_id: string // id of the entry being replaced
entry: Record<string, unknown>
intent: string
agent: string
}
type SupersedeResult = {
id: string // new entry's ULID
epoch: number
timestamp: number
}
Parameters
| Parameter | Required | Description |
|---|---|---|
superseding_id | ✓ | The id of the committed entry being replaced. |
entry | ✓ | The new entry's content. |
intent | ✓ | Why this entry supersedes the previous one. Must be ≥ minIntentLength characters. |
agent | ✓ | The agent making the replacement. Any agent may supersede any committed entry. |
Behavior
- Any agent may supersede any committed entry — not author-restricted.
- The new entry gets
status: "committed"immediately. - If the predecessor has already been superseded,
supersede()follows the chain to the latest entry and supersedes that — the chain always resolves to the newest version. - Retracted entries cannot be superseded.
read()returns both old (superseded) and new (committed) entries.
Chain example
const { id: v1 } = await field.write({ entry: { topic: 'cagr', value: '23%' }, intent: 'initial estimate', agent: 'a' })
const { id: v2 } = await field.supersede({ superseding_id: v1, entry: { topic: 'cagr', value: '19%' }, intent: 'revised after Q3 data', agent: 'b' })
// Superseding v1 when v2 already superseded it resolves to superseding v2:
const { id: v3 } = await field.supersede({ superseding_id: v1, entry: { topic: 'cagr', value: '21%' }, intent: 'corrected methodology', agent: 'c' })
// v1 → superseded, v2 → superseded, v3 → committed
Errors
| Code | When |
|---|---|
ENTRY_NOT_FOUND | No entry with superseding_id exists |
INVALID_ENTRY | entry is not a plain object |
INTENT_REQUIRED | intent is missing, null, or undefined |
INTENT_TOO_SHORT | intent.trim().length < minIntentLength |
AGENT_REQUIRED | agent is missing or empty |