Skip to main content
Revision operations modify the lifecycle and status of existing memory records. All operations are atomic — partial revisions are never externally visible. Every operation appends to the record’s audit log, preserving a complete history of changes.
Episodic records are immutable and cannot be revised. Attempting to revise an episodic record returns a FAILED_PRECONDITION error. This is by design: episodic memory is append-only raw experience and serves as evidence for later knowledge formation.

Revision status

Semantic records carry a revision.status field in their payload that transitions through:
StatusMeaning
activeRecord is currently valid
contestedConflicting evidence exists; status unresolved
retractedRecord has been withdrawn; salience is 0

Supersede

Atomically replaces an existing record with a new version. The old record’s salience is set to 0 and its semantic status is set to retracted. The new record is stored with a supersedes relation pointing to the old record.
Both the old and new records are persisted. The old record is not deleted; it is retracted so its audit trail remains queryable.

Request fields

old_id
string
required
ID of the record to supersede. Must not be episodic.
new_record
bytes
required
JSON-encoded MemoryRecord that replaces the old one. For semantic records, the payload must include at least one evidence reference or provenance source. Maximum 10 MB.
actor
string
required
Identifier of the agent or user performing the operation.
rationale
string
required
Human-readable reason for the supersession, stored in both audit entries.

Response

record
bytes
JSON-encoded MemoryRecord — the newly created record with its assigned ID and provenance populated.

Example

Go
// Supersede a semantic record with a new version
superseded, err := m.Supersede(ctx, oldRecordID, newRec, "agent", "Go version updated")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("New record ID: %s\n", superseded.ID)

Fork

Creates a new record derived from an existing source record. Unlike Supersede, both the source and the forked record remain active. Use Fork to create conditional variants of a fact or procedure without invalidating the original. The forked record receives a derived_from relation pointing to the source, and an audit entry with action fork is appended to the source record.

Request fields

source_id
string
required
ID of the record to fork. Must not be episodic.
forked_record
bytes
required
JSON-encoded MemoryRecord representing the conditional variant. For semantic records, the payload must include at least one evidence reference or provenance source. Maximum 10 MB.
actor
string
required
Identifier of the agent or user performing the operation.
rationale
string
required
Human-readable reason stored in both audit entries.

Response

record
bytes
JSON-encoded MemoryRecord — the newly created forked record.

Example

Go
// Fork a record for conditional validity (dev vs. prod)
forked, err := m.Fork(ctx, sourceID, conditionalRec, "agent", "different for dev environment")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Forked record ID: %s\n", forked.ID)

Retract

Marks a record as retracted without deleting it. The record’s salience is set to 0. For semantic records, the revision status is set to retracted. The record remains in the store so its audit trail is preserved. Retracted records have salience 0 and are excluded from active retrieval results by default.

Request fields

id
string
required
ID of the record to retract. Must not be episodic.
actor
string
required
Identifier of the agent or user performing the retraction.
rationale
string
required
Human-readable reason stored in the audit entry.

Response

RetractResponse is empty. A successful call returns gRPC status OK.

Example

Go
// Retract a record that is no longer valid
err := m.Retract(ctx, recordID, "agent", "no longer accurate")
if err != nil {
    log.Fatal(err)
}

Merge

Atomically combines multiple source records into a single merged record. All source records are retracted (salience set to 0, semantic status set to retracted). The merged record receives derived_from relations for every source, and each source record receives an audit entry with action merge.
At least one source ID is required. All source records must be non-episodic. The entire operation runs in a single transaction.

Request fields

ids
string[]
required
IDs of the records to merge. Must contain at least one ID and no more than 10 000.
merged_record
bytes
required
JSON-encoded MemoryRecord that consolidates the source records. For semantic records, the payload must include at least one evidence reference or provenance source. Maximum 10 MB.
actor
string
required
Identifier of the agent or user performing the merge.
rationale
string
required
Human-readable reason stored in all audit entries.

Response

record
bytes
JSON-encoded MemoryRecord — the newly created merged record with derived_from relations.

Example

Go
// Merge multiple records into one consolidated record
merged, err := m.Merge(
    ctx,
    []string{id1, id2, id3},
    mergedRec,
    "agent",
    "consolidating duplicates",
)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Merged record ID: %s\n", merged.ID)

Contest

Marks a record as contested, indicating that conflicting evidence exists. The record remains active with its salience unchanged, but its semantic revision status transitions to contested. A contested_by relation is added pointing to the conflicting record. Contested records are still returned by retrieval, but their status signals to the agent that the information should be treated with caution.

Request fields

id
string
required
ID of the record to mark as contested. Must not be episodic.
contesting_ref
string
ID of the conflicting record or evidence. When provided, a contested_by relation is added.
actor
string
required
Identifier of the agent or user performing the contest.
rationale
string
required
Human-readable reason stored in the audit entry.

Response

ContestResponse is empty. A successful call returns gRPC status OK.

Example

Go
// Contest a record when conflicting evidence appears
err := m.Contest(
    ctx,
    recordID,
    conflictingRecordID,
    "agent",
    "new evidence contradicts this",
)
if err != nil {
    log.Fatal(err)
}

Reinforce

Boosts a record’s salience, signalling that it was useful. This resets the decay clock and increments the audit log with an AuditActionReinforce entry. Reinforcement count is tracked in the metrics via retrieval_usefulness.

Request fields

id
string
required
ID of the record to reinforce.
actor
string
required
Identifier of the agent or user performing the reinforcement. Maximum 100 000 characters.
rationale
string
required
Human-readable reason for the reinforcement. Maximum 100 000 characters.

Response

ReinforceResponse is empty. A successful call returns gRPC status OK.

Example

Go
// Reinforce a record after it contributed to a successful outcome
err := m.Reinforce(ctx, planRecord.ID, "planner-agent", "plan used successfully")
if err != nil {
    log.Fatal(err)
}

Penalize

Reduces a record’s salience by a specified amount. Use this to signal that a record contributed to a failed or unhelpful outcome.

Request fields

id
string
required
ID of the record to penalize.
amount
number
required
Amount by which to reduce salience. Must be non-negative and finite. Salience will not go below 0.
actor
string
required
Identifier of the agent or user performing the penalization. Maximum 100 000 characters.
rationale
string
required
Human-readable reason stored in the audit entry. Maximum 100 000 characters.

Response

PenalizeResponse is empty. A successful call returns gRPC status OK.

Example

Go
// Reduce salience of a record that led to a bad outcome
err := m.Penalize(ctx, recordID, 0.2, "build-agent", "procedure produced linker error")
if err != nil {
    log.Fatal(err)
}

Build docs developers (and LLMs) love