attune / reckon
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
| Parameter | Required | Description |
|---|---|---|
agent | ✓ | The requesting agent's id. Used for self-filtering and role lookup. |
topic | Match entries by entry.topic. Adds full topic weight (0.60) to matching entries' scores. | |
role | Explicit role for role-match scoring. Falls back to the agent's registered role. | |
max_units | Maximum 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.
retractedandsupersededentries are never returned.
Relevance scoring
Each visible entry is scored across four components:
| Component | Max | What it measures |
|---|---|---|
topic | 0.60 | entry.topic === context.topic |
role | 0.20 | The writing agent's role matches the caller's role |
recency | 0.15 | How recently written, relative to the visible set |
intent | 0.05 | Substantiveness of the intent string |
relevance_score is a float in [0, 1]. relevance_reason breaks down each component's contribution.
Errors
| Code | When |
|---|---|
AGENT_REQUIRED | agent is missing or empty |
INVALID_QUERY | max_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:
- They share the same
entry.topic(strict equality). - They share at least one other key in
entry. - The value at that key differs, and both values are primitive (
string,number,boolean, ornull).
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
}