Skip to content

Engram schema

This page is the full specification of the engram schema. It is generated from and stays in sync with @plur-ai/core/src/schemas/engram.ts — the Zod schema is the source of truth. If you find a discrepancy, the schema wins; please open an issue.

The schema uses .passthrough() at runtime so unknown fields are preserved during parsing — this prevents data loss when new fields are added by hand or by future versions.

If you’re new to engrams, start with the Engrams concept page. This is the deep dive.

id: ENG-2026-0518-001 # required
version: 2 # default 2
status: active # required
type: procedural # required
scope: project:my-app # required
statement: "..." # required, ≥ 1 char
# everything else optional

Five required fields. Everything else slots into one of: classification, content, lineage, activation, relations, provenance, feedback, temporal, usage, episodic, exchange, commitment, version history, retrieval hints, polarity.

FieldTypeRequiredDefaultConstraints
idstringyesRegex ^(ENG|ABS|META)-[A-Za-z0-9-]+$. ENG- for engrams, ABS- for abstractions, META- for meta-engrams.
versionintno2≥ 1. The schema version of this engram payload — not to be confused with engram_version (content revision).
statusenumyesactive · dormant · retired · candidate
consolidatedboolnofalseTrue after this engram has been merged into a META engram.
typeenumyesbehavioral · terminological · procedural · architectural
scopestringyesHierarchical namespace, e.g. global, project:myapp, group:acme/platform. See Scope conventions.
visibilityenumnoprivateprivate (scope only) · public (exportable across orgs) · template (intended for reuse via packs)
candidate → active → dormant → retired

Auto-extraction creates candidate engrams that need promotion (typically by recurring 3× or an explicit plur_promote). Activation decay can move active → dormant automatically. retired is reachable explicitly (plur_forget) or via supersession by a more recent engram. History is preserved across every transition.

FieldTypeRequiredConstraints
statementstringyes≥ 1 char. The claim. Must be self-contained. Indexed verbatim by both BM25 and the embedder.
rationalestringnoWhy this is true / what incident produced it. Indexed alongside the statement — surfaces in recall when the statement alone isn’t enough context.
contraindicationsstring[]noWhen this engram does not apply. Reduces false-positive injection.

A good statement is self-contained. Don’t write “always use it” — write “always validate user input at API boundaries.” The recall pipeline embeds the statement; ambiguous statements embed badly.

How this engram came to be — useful for audit, deduplication, and pack tracking.

FieldTypeRequiredDefault
sourcestringno
source_patternsstring[]no
derivation_countintno1
packstring | nullnonull
abstractstring | nullnonull
derived_fromstring | nullnonull
FieldTypeRequiredDefault
knowledge_type{memory_class, cognitive_level}no
domainstringno
tagsstring[]no[]
knowledge_type:
memory_class: semantic # semantic | episodic | procedural | metacognitive
cognitive_level: apply # Bloom's: remember | understand | apply | analyze | evaluate | create

Memory class follows the cognitive-science taxonomy: semantic knowledge (“X is true”), episodic (“X happened on date D”), procedural (“to do Y, run Z”), metacognitive (“when reasoning about Y, beware of bias B”). Cognitive level uses Bloom’s taxonomy as a coarse difficulty/abstraction axis.

Each engram tracks four numbers; together they drive recall priority.

activation:
retrieval_strength: 0.7 # default. 0 ≤ x ≤ 1. Decays with time-since-last-access.
storage_strength: 1.0 # default. 0 ≤ x ≤ 1. Set at creation; how durable.
frequency: 0 # increments on each successful recall.
last_accessed: 2026-05-25 # ISO date. Drives decay calculation.
FieldRangePurpose
retrieval_strength0–1Drives recall priority. Power-law decay since last_accessed.
storage_strength0–1Floor on durability. Set lower for transient context (e.g. session-local notes).
frequencyint ≥ 0Bumped on each successful recall. Used as a strengthening signal.
last_accessedISO dateTime anchor for decay. Updated on recall.

Conceptual model: Activation & decay. Formula: A(t) = ln(Σ tᵢ^-d) where tᵢ is the time since the i-th access and d is the decay rate (default 0.5).

relations:
broader: [ENG-2026-0501-007] # parent concepts
narrower: [ENG-2026-0510-022] # children / specialisation
related: [ENG-2026-0512-014] # siblings / cross-reference
conflicts: [ENG-2026-0403-009] # explicit contradiction — must reconcile

All four arrays default to []. Conflicts are picked up by tension detection — saving a new engram that contradicts an existing one produces a warning and (optionally) a forced reconciliation.

associations:
- target_type: engram # engram | document
target: ENG-2026-0515-031
strength: 0.82 # 0 ≤ x ≤ 0.95
type: semantic # semantic | temporal | causal | co_accessed
updated_at: 2026-05-16 # ISO date, optional

Constraint: strength cannot reach 1.0 — there is always some uncertainty in system-derived associations. Key distinction from relations: relations are what a human says is true; associations are what the system has observed.

Association types:

  • semantic — embedding similarity.
  • temporal — these engrams accumulate together in time.
  • causal — A is recurrently followed by B in episode history.
  • co_accessed — both retrieved together for related tasks.

Knowledge anchors — pointers to ground truth

Section titled “Knowledge anchors — pointers to ground truth”
knowledge_anchors:
- path: src/cadastre/migration.ts
relevance: primary # primary | supporting | example (default supporting)
snippet: "if (parcel.legacy) ..." # optional, ≤ 200 chars
snippet_extracted_at: 2026-05-12 # optional

Anchors let an engram refer to a specific code/document location. Recall can inline the snippet; the path lets a reader verify the engram is still accurate. Use sparingly — anchors that drift (paths that no longer exist) signal stale engrams.

dual_coding:
example: "Parcel #41/2-K.O. Beograd has a legacy split — handle via migration v3.7."
analogy: "Like a git rebase: replay the new shape onto the old data."

Schema constraint: at least one of example or analogy must be present if dual_coding is set. Use when the statement is abstract; helps both human reviewers and embedding-based retrieval.

provenance:
origin: plur_learn:gregor:2026-05-16T12:34Z
chain: [ENG-2026-0510-022] # default []
signature: "sha256:abc..." # default null
license: cc-by-sa-4.0 # default cc-by-sa-4.0

The chain walks back through engrams the current one was derived from. The signature enables tamper detection for high-integrity scopes. The default cc-by-sa-4.0 license allows transfer between scopes — override (e.g., proprietary) to mark engrams non-portable.

feedback_signals:
positive: 12 # default 0
negative: 2 # default 0
neutral: 0 # default 0

Drives ROI computation in Enterprise dashboards and pack-export valuations. Updated by plur_feedback.

temporal:
learned_at: 2026-05-16 # required if temporal is set
valid_from: 2026-01-01 # optional
valid_until: 2026-12-31 # optional
ingested_at: 2026-05-16 # optional

Two time axes: when we learned it (learned_at, ingested_at) vs when the claim is true (valid_from, valid_until). Recall can filter by valid time, so date-bound facts (“the deploy freeze runs Nov 15–Jan 5”) expire on their own.

entities:
- name: Apache AGE
type: technology # person | organization | technology | concept | project | tool | place | event | standard | other
uri: https://age.apache.org # optional, must be a valid URL

Auto-extracted from statements at ingest time. Enables graph queries (engrams that mention organization:IGEA). The type enum is closed; unknown things go in other.

usage:
injections: 47 # default 0
hits: 34 # default 0
misses: 13 # default 0
last_hit_at: 2026-05-15T18:22Z # optional

Updates automatically as the engram is injected and as feedback comes in. Drives the quality slopegraph in the admin Insights view and feeds the decay/retire pipeline.

episodic:
emotional_weight: 7 # 1-10, default 5
confidence: 9 # 1-10, default 5
trigger_context: "post-incident, after Friday rollback" # optional
journal_ref: "notes/journals/2026-05-15.md#incident-3" # optional

For experiential knowledge. High-weight, high-confidence engrams retrieve earlier in episodic-tagged recall. journal_ref lets the engram link back to its conversation/incident of origin.

exchange:
fitness_score: 0.78 # optional, 0-1
environmental_diversity: 12 # default 0. Distinct scopes that adopted it.
adoption_count: 47 # default 0. Downloads/installs via packs.
contradiction_rate: 0.04 # default 0, 0-1. Fraction of adopters that retired it.

Populated when an engram travels via a pack and is re-imported elsewhere. Drives pack-discovery ranking.

structured_data:
custom_field_1: "anything"
numeric: 42
nested:
keys: are: fine

Record<string, unknown> — domain-specific fields the schema doesn’t cover. Survives passthrough validation. Use sparingly; prefer first-class fields when the use case fits.

polarity: do # do | dont | null (default null)

Inferred classification of the statement as directive (do) or constraint (dont). Injected separately so the agent doesn’t confuse a rule with an example. Override the inferred value when needed.

commitment: decided # exploring | leaning | decided | locked
locked_at: 2026-05-25T14:32:18Z # optional
locked_reason: "Core safety rule — never log secrets" # optional
content_hash: "sha256:abc..." # optional
CommitmentMeaning
exploringTrying it out, easy to drop.
leaningProvisional preference (default for plur_learn).
decidedCommitted for the foreseeable future.
lockedMeta-rule. Pinned to context regardless of relevance; recorded reason.

content_hash is a content-addressed fingerprint of the statement (and key derived fields). Used by deduplication to detect “this engram is effectively the same as one we already have.”

engram_version: 3 # default 1. Bumps every time the content materially changes.
previous_version_ref:
event_id: evt-7c3b...
changed_at: 2026-05-12T09:14:02Z
episode_ids: [EPS-2026-0512-014, EPS-2026-0513-007] # default []
FieldPurpose
engram_versionContent revision counter. Bumped on plur_engram update.
previous_version_refPointer to the event that produced the previous content.
episode_idsSessions where this engram was created or materially updated.
summary: "Always validate input at API boundaries" # optional, ≤ 80 chars
pinned: true # optional
FieldPurpose
summaryUp to 80 chars — used in injection blocks when full statement is too long.
pinnedAlways-load. Bypasses the term-hits gate in scoreEngram. Pinned engrams are still subject to the token budget but bypass per-pack and per-domain fairness caps in fillTokenBudget. Use sparingly: meta-rules, safety conventions, core operating principles.

scope is a string. Common shapes:

ScopeMeaning
globalVisible to every authenticated user in the org.
org:igeaOrg-wide; equivalent to global for single-org deployments.
space:cadastre-RSA delivered vertical or product.
project:guardian-v3A specific codebase.
group:igea/backendA team within a space.
user:igea:alicePersonal to one user only.
command:office-hoursSurfaces only when a specific slash-command is invoked.
agent:miles-on-nightshiftAgent-specific knowledge (avoid overuse; prefer human-readable groups).

Hierarchy at recall time: a user has access to user:org:self, every group: they belong to, every space:, org:, and global — narrowest first. Permission resolution is in src/permissions/resolver.ts (Enterprise).

  • Strict schema is exported as EngramSchema — TypeScript types are derived from this.
  • Runtime validation uses EngramSchemaPassthrough — unknown fields are preserved, not rejected. This is deliberate: forward-compat with hand-edited engrams and future-version migrations.
  • The id regex is strict — invalid IDs throw at parse time. Don’t hand-craft IDs; let the engine generate them.
  • Numeric ranges (0–1, 1–10) and string max-lengths (summary ≤ 80, snippet ≤ 200) are enforced.
  • Persisted (~/.plur/engrams.yaml locally; engrams table in Enterprise Postgres): everything above, as YAML or JSONB.
  • Computed at query time: hybrid-search scores, RRF fusion, spreading-activation weights, decay-adjusted retrieval strength.

See docs/injection-formula.md in the Enterprise repo for the full retrieval algorithm.

The schema exports these types — useful for SDK consumers:

type Engram = z.infer<typeof EngramSchema>
type KnowledgeAnchor = z.infer<typeof KnowledgeAnchorSchema>
type Association = z.infer<typeof AssociationSchema>
type EntityRef = z.infer<typeof EntityRefSchema>
type Temporal = z.infer<typeof TemporalSchema>
type UsageStats = z.infer<typeof UsageStatsSchema>
type EpisodicFields = z.infer<typeof EpisodicFieldsSchema>
type ExchangeMetadata = z.infer<typeof ExchangeMetadataSchema>
type PreviousVersionRef = z.infer<typeof PreviousVersionRefSchema>

Source of truth: @plur-ai/core/src/schemas/engram.ts.