Akashik Protocol
Reference

attune / reckon

Receive ranked, relevant entries from the Field — with or without conflict detection.

attune()

Surfaces what's relevant to an agent right now. Scores all visible entries, sorts highest-first, and returns scored results. The agent does not write a query — it declares who it is and what it's working on.

Signature

field.attune(context: AttuneContext): Promise<FieldEntryWithRelevance[]>

type AttuneContext = {
  agent: string
  topic?: string
  role?: string
  max_units?: number
}

Parameters

ParameterRequiredDescription
agentThe requesting agent's id. Used for self-filtering and role lookup.
topicMatch entries by entry.topic. Adds full topic weight (0.60) to matching entries' scores.
roleExplicit role for role-match scoring. Falls back to the agent's registered role.
max_unitsMaximum entries to return. Lowest-scoring entries beyond the cap are dropped. Default 100.

Visibility rules

  • The calling agent's own committed entries are never returned.
  • The calling agent's own draft entries are returned (author sees their own work).
  • Other agents' drafts are never returned.
  • retracted and superseded entries are never returned.

Relevance scoring

Each visible entry is scored across four components:

ComponentMaxWhat it measures
topic0.60entry.topic === context.topic
role0.20The writing agent's role matches the caller's role
recency0.15How recently written, relative to the visible set
intent0.05Substantiveness of the intent string

relevance_score is a float in [0, 1]. relevance_reason breaks down each component's contribution.

Errors

CodeWhen
AGENT_REQUIREDagent is missing or empty
INVALID_QUERYmax_units is negative

Example

const entries = await field.attune({ agent: 'strategist', topic: 'market-size' })

console.log(entries[0].relevance_score)   // 0.85
console.log(entries[0].relevance_reason.components)
// { topic: 0.60, role: 0.15, recency: 0.08, intent: 0.02 }
console.log(entries[0].relevance_reason.summary)
// 'topic match; same role as writer; written recently; specific intent'

reckon()

Identical visibility and scoring to attune(), plus mechanical conflict detection across the returned entries.

Signature

field.reckon(context: AttuneContext): Promise<ReckonResult>

type ReckonResult = {
  entries: FieldEntryWithRelevance[]
  conflicts: Conflict[]
}

type Conflict = {
  a: FieldEntry
  b: FieldEntry
  keys: string[]  // shared keys where values disagree, sorted alphabetically
}

Conflict detection rules

Two entries conflict when all three conditions hold:

  1. They share the same entry.topic (strict equality).
  2. They share at least one other key in entry.
  3. The value at that key differs, and both values are primitive (string, number, boolean, or null).

Object-valued keys are not compared in v0.2. Each conflicting pair appears once. The protocol surfaces the disagreement — resolution is always the caller's responsibility.

When to use reckon vs attune

Use reckon() when the calling agent needs to know about contradictions before deciding how to act. Use attune() when you want the scored surface without conflict commentary.

Example

const { entries, conflicts } = await field.reckon({
  agent: 'writer',
  topic: 'competitor-pricing',
})

if (conflicts.length > 0) {
  console.log(conflicts[0].keys)    // ['price']
  console.log(conflicts[0].a.entry) // { topic: 'competitor-pricing', price: '$49/mo' }
  console.log(conflicts[0].b.entry) // { topic: 'competitor-pricing', price: '$39/mo' }
  // The writer now decides how to proceed
}

FieldEntryWithRelevance type

type FieldEntryWithRelevance = FieldEntry & {
  relevance_score: number          // 0.0 to 1.0
  relevance_reason: RelevanceReason
}

type RelevanceReason = {
  components: {
    topic: number    // 0 to 0.60
    role: number     // 0 to 0.20
    recency: number  // 0 to 0.15
    intent: number   // 0 to 0.05
  }
  summary: string
}