Akashik Protocol
Concepts

Writing with Intent

How entries work in v0.2 — plain objects, mandatory intent, and the topic convention.

Entries are plain objects

In v0.2, entries are Record<string, unknown> — any JSON-serialisable shape you want:

await field.write({
  entry: { topic: 'market-size', cagr: '23%', source: 'gartner' },
  intent: 'validate market size assumption for go-to-market strategy',
  agent: 'researcher',
})

There is no schema to conform to. The Field stores what you give it, attaches metadata, and makes it available to other agents.

The topic convention

entry.topic is not enforced by the protocol, but it matters a great deal in practice:

  • Attunement uses it. field.attune({ agent, topic }) matches entries by entry.topic and gives them full relevance weight (0.60 out of 1.0).
  • Conflict detection uses it. field.reckon() only compares entries with the same entry.topic for conflicts.

Use topic to group related entries. Think of it as the subject of the entry — what it's about, not how it's typed.

// Good — consistent, precise topics
{ topic: 'competitor-pricing', vendor: 'acme', price: '$49/mo' }
{ topic: 'competitor-pricing', vendor: 'acme', price: '$39/mo' }  // ← conflicts with above

// Less useful — topic too broad to drive useful attunement
{ topic: 'research', content: '...' }

Intent is mandatory

Every write requires an intent string explaining why this entry exists. The default minimum is 10 characters. Shorter intents are rejected with INTENT_TOO_SHORT.

// Rejected — intent too vague
await field.write({
  entry: { topic: 'pricing', price: '$49' },
  intent: 'pricing',   // ← INTENT_TOO_SHORT
  agent: 'researcher',
})

// Accepted
await field.write({
  entry: { topic: 'pricing', price: '$49' },
  intent: 'competitor pricing observed directly on their website',
  agent: 'researcher',
})

Intent is the answer to why was this written, not what is it. Any agent — including a human reviewing the field later — can read the intent and immediately understand the reasoning.

The agent field

agent is optional but strongly recommended:

  • It drives the self-filter in attune() and reckon() — agents don't see their own committed entries in results.
  • It is required for retract() — you can only retract your own entries.
  • It improves relevance scoring via role matching when the agent is registered.

What the Field auto-generates

When you call write(), the Field adds:

FieldDescription
idA ULID — globally unique, lexicographically sortable by time
timestampUnix milliseconds at write time
epochA monotonic counter scoped to this Field instance
status"committed" immediately

Status lifecycle

Every entry has a status reflecting where it is in its lifecycle:

StatusWhat it means
committedLive and visible to other agents via attune() / reckon()
draftPrivate to the author until committed (see Draft Lifecycle)
retractedWithdrawn by the author — excluded from attune() / reckon()
supersededReplaced by a newer entry — excluded from attune() / reckon()

read() returns all entries including retracted and superseded ones (with their status). Use it when you need the full history.

Next