Akashik Protocol
Reference

write / read

Write a committed entry to the Field, or query the Field's entries directly.

write()

Writes a committed entry to the Field, visible immediately to other agents via attune() and reckon().

Signature

field.write(input: WriteInput): Promise<WriteResult>

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

type WriteResult = {
  id: string        // ULID
  timestamp: number // Unix milliseconds
}

Parameters

ParameterRequiredDescription
entryAny JSON-serialisable plain object. Keys and shape are up to you.
intentWhy this entry is being written. Must be ≥ minIntentLength characters after trimming.
agentThe writing agent's id. Strongly recommended — required for retract() and drives self-filtering in attune().

Returns

FieldDescription
idULID — unique, lexicographically sortable by creation time
timestampUnix milliseconds at write time

The written entry also gets an epoch value (monotonic counter) and status: "committed".

Errors

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

Example

const { id } = await field.write({
  entry: { topic: 'competitor-pricing', vendor: 'acme', price: '$49/mo' },
  intent: 'competitor pricing observed directly on their pricing page',
  agent: 'researcher',
})

read()

Retrieves entries matching a query. Returns entries in write order (oldest first). Unlike attune(), there is no scoring or filtering — this is a direct view of the store.

Signature

field.read(query?: ReadQuery, options?: ReadOptions): Promise<FieldEntry[]>

type ReadQuery = Record<string, unknown>

type ReadOptions = {
  caller?: string  // include the caller's own drafts in results
}

Parameters

ParameterDescription
queryOptional. Every key in query must match the corresponding key in entry (strict === for primitives). Omit to return all entries.
options.callerWhen set, the caller's own draft entries are included in results.

Behavior

  • Returns all statuses: committed, draft (if caller matches), retracted, superseded.
  • Does not apply the attunement self-filter — agents see their own committed entries.
  • Does not score or rank results.

Use read() for history, debugging, or building your own query logic. Use attune() or reckon() for context delivery to agents.

Errors

CodeWhen
INVALID_QUERYquery is provided but is not a plain object

Examples

// All committed entries
const all = await field.read()

// Entries matching a topic
const pricing = await field.read({ topic: 'competitor-pricing' })

// Include author's own drafts
const withDrafts = await field.read(
  { topic: 'competitor-pricing' },
  { caller: 'researcher' }
)

// Filter by status after retrieval
const live = all.filter(e => e.status === 'committed')

FieldEntry type

type FieldEntry = {
  id: string
  timestamp: number          // Unix milliseconds
  epoch: number              // monotonic counter, higher = written later
  agent?: string
  status: 'committed' | 'draft' | 'retracted' | 'superseded'
  entry: Record<string, unknown>
  intent: string
}