Akashik Protocol
Reference

draft / commit / discard

Create private entries, review them in context, then publish or remove them.

draft()

Creates a draft entry — visible only to its author via attune(), reckon(), and read({ caller }).

Signature

field.draft(input: DraftInput): Promise<{ draft_id: string }>

type DraftInput = {
  entry: Record<string, unknown>
  intent: string
  agent?: string
}

Parameters

ParameterRequiredDescription
entryAny JSON-serialisable plain object.
intentWhy this draft is being created. Must be ≥ minIntentLength characters after trimming.
agentThe drafting agent's id. Used to determine who can see and commit the draft.

Returns

FieldDescription
draft_idULID — stable through commit(). Becomes the committed entry's id.

Errors

CodeWhen
INTENT_REQUIREDintent is missing, null, or undefined
INTENT_TOO_SHORTintent.trim().length < minIntentLength
INVALID_ENTRYentry is not a plain object

commit()

Promotes a draft to a committed entry. The entry becomes visible to all agents immediately.

Signature

field.commit(input: CommitInput): Promise<CommitResult>

type CommitInput = {
  draft_id: string
}

type CommitResult = {
  id: string       // same as draft_id
  epoch: number    // updated at commit time
  timestamp: number
}

Behavior

  • The entry's id is preserved from the draft.
  • epoch and timestamp are updated to commit time, not draft creation time.
  • After commit, status changes from "draft" to "committed".

Errors

CodeWhen
DRAFT_NOT_FOUNDNo draft exists with the given draft_id

discard()

Removes a draft entirely. The entry is gone — not retracted, not superseded, just deleted.

Signature

field.discard(input: DiscardInput): Promise<void>

type DiscardInput = {
  draft_id: string
  intent: string
  agent?: string
}

Parameters

intent is required on discard — the reason for discarding is itself a meaningful act and part of the internal record.

Errors

CodeWhen
DRAFT_NOT_FOUNDNo draft exists with the given draft_id
INTENT_REQUIREDintent is missing, null, or undefined
INTENT_TOO_SHORTintent.trim().length < minIntentLength

Full example

// Stage a draft
const { draft_id } = await field.draft({
  entry: { topic: 'competitor-pricing', vendor: 'acme', price: '$39/mo' },
  intent: 'preliminary pricing — needs verification before sharing',
  agent: 'researcher',
})

// Check whether it conflicts with what's already in the field
const check = await field.reckon({ agent: 'researcher', topic: 'competitor-pricing' })
// draft is visible to the author in their reckon results

if (check.conflicts.length === 0) {
  // Safe to publish
  await field.commit({ draft_id })
} else {
  // Discard and investigate
  await field.discard({
    draft_id,
    intent: 'conflicts with existing data — need to verify source before committing',
    agent: 'researcher',
  })
}