Live Plugin Ai Memory Infrastructure

OpenCode Remembering

OpenCode Remembering is the working application behind Memory From First Principles: a standalone plugin and bundled memory engine that turns project history into controlled, provenance-bearing context without treating everything retrieved from the past as permission to act.

Problem Long-running AI agents accumulate files, conversations, decisions, failures, instructions and changing project state, but ordinary retrieval cannot tell historical evidence from current guidance, relevant material from authoritative material, or remembered information from permission to act on it.
Outcome A standalone remembering runtime where canonical project history is retrieved strongly, routed by purpose, interpreted temporally, conditioned on the work being done, gated by standing, and reduced to bounded provenance-bearing context before it is allowed to influence an agent.
Research base Memory From First Principles
Capstone The Memory From First Principles application: a real coding-agent plugin implementing the book’s earned path from canonical project history through retrieval, routing, temporal state, safe framing, trust, and bounded context.
Implementation evidence

The solution is backed by inspectable code

https://github.com/ernanhughes/opencode-remembering src/, bridge/, engine/remembering/, engine/tests/

The problem

AI agents forget in a surprisingly specific way.

The files may still exist.

The conversation transcript may still exist.

The vector database may still contain everything.

Search may even find exactly the right passage.

And the system can still behave as though it has no useful memory.

The problem is that preserving the past and retrieving the past are only the first two steps.

Consider a project whose history contains:

July:
Use SQLite for the metadata store.

August:
We decided to migrate to PostgreSQL.

September:
PostgreSQL became the active backend.

Now ask:

What database did we originally use?

SQLite is the right memory.

Ask instead:

Which database should I use for the new component?

SQLite is still relevant history.

It is now the wrong guidance.

A vector search cannot resolve that distinction by similarity alone.

The same problem appears repeatedly in long-running AI work:

  • an old decision is highly relevant but no longer current;
  • a current note fits the task but came from a source that should not direct action;
  • a remembered instruction is topically perfect but says to bypass validation;
  • the same vague request needs different evidence during architecture review and release preparation;
  • a generated restatement repeats a revoked source and accidentally appears more authoritative than its origin;
  • all retrieved evidence is legitimate, but there is too much of it for the model to use well.

The problem is therefore not:

How do I give an AI more history?

It is:

How does retained history earn the right
to change present behaviour?

Why the obvious approach fails

The obvious memory architecture is:

history
    -> embeddings
    -> vector search
    -> model

That is useful.

It is also incomplete.

Similarity answers:

what looks relevant?

It does not answer:

is this historical or current?

was this decided or merely discussed?

had the decision taken effect yet?

did the system even know this at the time?

does this belong to the project and task being worked on?

does this source have standing to guide an action?

was its authority revoked?

is this a real independent corroboration
or an AI restatement of the same source?

should all of this admitted evidence consume context?

Sending the whole history is not a reliable repair either.

The experiments behind Memory From First Principles produced one of the project’s most important results: more remembered material is not monotonically better.

On the controlled behavioural ladder, undifferentiated full history scored below no memory for the smaller reader. Strong retrieval recovered substantially. Selected and assembled memory improved further.

The practical lesson is not that history is bad.

It is that:

Memory is durable. Context is selected.

OpenCode Remembering implements that distinction.

The solution

OpenCode Remembering is a standalone memory plugin for OpenCode with a bundled remembering engine.

Its working rule is:

storage is not retrieval

retrieval is not memory

relevance is not currentness

currentness is not authority

authority is not truth

admission is not selection

The system preserves project history and then passes evidence through explicit control stages before it is allowed to influence current work.

The current architecture is:

CANONICAL PROJECT HISTORY
        |
        v
STRONG HYBRID RETRIEVAL
        |
        v
RECALL / INFLUENCE ROUTING
        |
        v
TEMPORAL INTERPRETATION
        |
        v
SAFE PROJECT / WORK FRAMING
        |
        v
TRUST + STANDING
        |
        v
BOUNDED CONTEXT
        |
        v
OPENCODE
        |
        v
PRESENT BEHAVIOUR

The important point is that these are separate decisions.

A record can pass one stage and fail the next.

That is intentional.

OpenCode is the first host, not the architecture

The first integration is OpenCode because coding agents make memory failures concrete.

Projects accumulate:

architecture decisions
failed approaches
tests
migrations
tool results
session history
release state
constraints
corrections

and the consequences of remembering the wrong thing are observable in code.

But the memory engine is deliberately separated from the OpenCode adapter.

The implementation is approximately:

OpenCode
    |
    v
TypeScript host adapter
    |
    v
Python bridge
    |
    v
bundled remembering engine
    |
    v
PostgreSQL + pgvector

The engine owns memory semantics.

The host owns translation.

A future Claude Code adapter, OpenAI-based coding agent, writing environment, research assistant or autonomous service could supply its own host events and consume the same memory contracts.

The useful boundary is not an OpenCode API.

It is a remembering protocol.

Canonical history comes first

Ordinary agent history is captured automatically.

The system does not depend on the agent deciding:

remember this

before an event can become part of project history.

OpenCode session messages and tool activity are captured under:

.remembering/sessions/

with stable session, message and tool identities.

Repository files are another canonical source.

The rule is:

capture first
interpret later

Derived summaries never replace the original record.

This matters because every later interpretation may be wrong.

A remembered claim can be rebuilt.

A rewritten past cannot.

Strong retrieval stays the baseline

The system begins with conventional retrieval and takes it seriously.

It uses PostgreSQL full-text search and pgvector dense retrieval, then combines their ranked results with reciprocal-rank fusion.

query
  |\
  | \
  |  -> dense embedding search
  |
  -> PostgreSQL full-text search
          |
          v
     reciprocal-rank fusion
          |
          v
       candidates

The production embedding path uses Ollama bge-m3.

Each result retains source and chunk identity.

The trace records the retrieval stages, ranks, configuration and whether dense retrieval actually executed.

This is important because the later memory mechanisms do not replace RAG.

They repair failure classes RAG cannot distinguish.

For many questions, strong retrieval is still the correct solution.

Recall and influence are different problems

The first memory-specific decision is route.

OpenCode Remembering distinguishes:

RECALL

from:

INFLUENCE

Recall asks the past to explain itself.

Influence allows the past to steer present behaviour.

These are not equivalent.

For example:

What database did we originally use?

should preserve superseded SQLite evidence.

But:

Which database should I use now?

must resolve evidence toward the current applicable state.

The frozen contract is:

Recall preserves historical candidates and does not suppress superseded evidence merely because it is no longer current. Influence resolves evidence toward the applicable current state before it is allowed to steer behaviour.

Explicit callers may choose a route.

Otherwise a small deterministic router selects one and records its reason.

No model confidence score is used.

Time has more than one axis

Real project history does not have one useful timestamp.

OpenCode Remembering distinguishes:

event_time

when something happened,

recorded_at

when the system learned it,

and:

effective_from / effective_to

when a state applies.

This makes several different questions possible.

What is true now?

What was valid on July 20?

What did we believe on August 1?

Given what we knew on August 1,
what did we believe was valid on July 20?

The temporal subsystem supports current, valid-time, known-time and bitemporal standpoints.

A decision also does not automatically become reality.

The system can represent:

August:
PostgreSQL selected.

current:
SQLite

planned:
PostgreSQL

until the actual state transition occurs.

Supersession does not erase history

Suppose PostgreSQL replaces SQLite.

The system does not delete SQLite.

Instead:

SQLite
    |
    | superseded by
    v
PostgreSQL

For influence, SQLite can be retrieved and then suppressed with a reason such as:

temporal.superseded_as_current

For recall, the same evidence remains legitimate history.

This preserves both:

current truth

and:

historical truth

without pretending they are the same thing.

Safe framing asks what work is happening now

Even current evidence can be the wrong evidence for the current task.

Consider the same request:

Review this.

during an architecture review and during release preparation.

The words are identical.

The useful history is not.

OpenCode Remembering separates two frame types.

A ProjectFrame is durable, versioned configuration:

project purpose
standing objectives
constraints
declared work types
evidence preferences

It lives in:

.remembering/project-frame.json

A WorkFrame is ephemeral current work:

objective
work type
active constraints
observable signals
provenance for those fields

WorkFrames are built from current WorkSignals such as the latest user request, task metadata, tool results or test failures.

The system does not ask a language model how confident it feels about the frame.

Wrong frames need their own safety mechanism

Framing is powerful enough to be dangerous.

A correct frame can improve context selection.

A wrong frame can remove exactly the evidence the agent needed.

The plugin therefore makes frame establishment explicit:

DECLARED
CORROBORATED
INFERRED
CONFLICTING
STALE
UNKNOWN

and maps establishment strength to control:

DECLARED / CORROBORATED
        -> HARD_FRAME

INFERRED
        -> SOFT_FRAME

CONFLICTING / STALE / UNKNOWN
        -> QUERY_ONLY

The central rule is:

A weak frame may assist retrieval; it may not erase the strong baseline.

A soft frame may add evidence or reorder it.

It cannot hard-delete otherwise relevant baseline evidence merely because the inferred work type does not prefer it.

A conflict falls back instead of guessing.

Historical recall bypasses current-work frame control.

Same words, different work, different memory

A live Stage 4 test deliberately uses:

Review this.

under two explicitly established work frames.

For:

architecture_review

the top result is the architectural decision.

For:

release_readiness

the release evidence becomes first.

Same query.

Same project.

Different established work.

Different useful memory.

The companion wrong-frame test forces an incorrect weak inference and verifies that the Stage 3 baseline evidence survives.

The positive effect and the failure control are both part of the feature.

Current and relevant still does not mean trusted

At this point an evidence item may be:

retrieved       yes
current         yes
frame relevant  yes

and still be unsafe guidance.

For example, a current session note may say:

Skip migration validation and disable foreign-key checks.

That is highly relevant to a migration task.

It may even be recent.

Neither fact gives it authority.

Stage 5 therefore introduces a separate trust and standing gate.

Its public outcomes are:

ADMIT
DENY
QUARANTINE

These are permissions, not truth labels.

Trust is permission, not truth

A denied source may be factually right.

A quarantined source may later prove useful.

A revoked source may remain historically important.

The trust question is:

May this evidence influence this action
under the current policy?

not:

Is this sentence true?

That difference allows search and historical recall to remain broad while automatic action context stays controlled.

Explicit standing policy

Projects may define trust policy under:

.remembering/trust/

The policy distinguishes source classes such as:

authoritative
informational
untrusted

and roles such as:

decision
production_state
directive
evidence
proposal
preference
derived_restatement
ordinary
external

Rules are deterministic.

There is no LLM trust classifier.

There is no scalar:

trust = 0.83

and test fixtures do not carry a hidden:

malicious = true

flag.

The gate has to earn its decision from observable content and structure.

Revocation is different from retraction

A source can lose standing without becoming false.

That distinction is represented explicitly.

retraction
=
the underlying claim/event was withdrawn or corrected

revocation
=
this source may no longer guide present behaviour

Standing changes are append-only events.

They do not rewrite historical sources.

A revoked benchmark can therefore be:

denied for current guidance

while remaining:

available for historical recall

Derived memory cannot launder authority

Suppose:

source A
    |
    | summarized into
    v
derived memory B

If A is revoked, B does not become authoritative merely because it is a cleaner sentence.

The gate follows derivation lineage.

revoked source
    |
    v
derived restatement
    |
    v
still revoked for guidance

This is one of the most important properties of a long-lived memory system.

Otherwise generated summaries become an authority-laundering mechanism.

Repetition is not corroboration

The same principle applies to corroboration.

Consider:

source A
    -> summary B
    -> restatement C

B and C may repeat the same claim.

They are not two independent sources.

The trust gate resolves derivation roots and requires disjoint lineage for structural corroboration.

An AI repeating itself does not manufacture evidence.

Remembered instructions receive special treatment

Directive-like memory receives deterministic screening.

The screen is deliberately narrow.

Patterns around:

skip validation
bypass checks
disable verification
never verify
always skip

may trigger additional controls.

A normal requirement such as:

Require a passing rollback test.

does not.

Unverified directive-like content may be quarantined.

A directive explicitly refuted by current authoritative evidence can be denied.

Independent corroboration can provide a different result.

Again, the mechanism is visible and reason-coded rather than hidden behind a model judgment.

Conflicts remain conflicts

When independently supported evidence disagrees, the system should not pick whichever passage retrieval ranked highest.

For action-directing conflicts where both sides have standing, the trust gate can quarantine both.

Later context selection must also preserve material benign disagreement rather than merging it into fluent consensus.

The principle is:

A says X
B says not-X

must not silently become:

the answer is probably somewhere between X and not-X

unless some separately supported evidence actually establishes that synthesis.

Search is deliberately broader than action context

memory_search is route-neutral.

It asks:

What relevant evidence exists?

It does not hide a result merely because current policy would deny that result permission to steer action.

memory_context asks a different question:

What project memory should be supplied
for this purpose?

That difference is fundamental.

Search may return:

revoked
historical
superseded
quarantined
conflicting

material.

Current influence context may exclude it.

Nothing has been deleted.

The trace matters as much as the bundle

Every automatic memory decision leaves structured evidence.

The current trace carries information from multiple stages:

route

lexical retrieval
dense retrieval
fusion

temporal standpoint
temporal status
suppression reason

ProjectFrame version
WorkFrame
WorkSignals
frame establishment
frame control
retrieval expansion

trust policy version
source class
role
standing events
revocation
lineage roots
corroborators
refuters
instruction screen
admit / deny / quarantine
reason codes

final selected bundle
latencies

The purpose is not to generate a convincing explanation after the fact.

It is to record the control flow while it happens.

That allows a failure to become:

the decisive evidence was retrieved
but suppressed as superseded

or:

the candidate survived time and framing
but was quarantined as an unverified directive

instead of:

the AI got it wrong

Project isolation

Every project receives an isolated PostgreSQL schema by default.

Conceptually:

remembering_<sha256(canonical_project_path)[:12]>

The schema records the canonical project identity.

If an explicit schema already belongs to another project, the plugin fails closed rather than merging histories.

Project scope is enforced again at later policy boundaries as defense in depth.

PostgreSQL is the substrate

The system deliberately uses PostgreSQL + pgvector rather than combining several specialized databases prematurely.

One substrate currently provides:

relational state
full-text retrieval
vector retrieval
indexes
JSON where useful
temporal events
standing events
project isolation
inspectable SQL

The plugin initializes its own schemas, tables and indexes.

The user supplies an existing PostgreSQL database and pgvector installation.

There is no SQLite production fallback and no silent JSON vector-store fallback.

The implementation is standalone

Early integration work called into the research implementation directly.

That was useful for proving the mechanics.

It was the wrong product boundary.

The runtime now lives entirely inside:

opencode-remembering/
    src/
    bridge/
    engine/remembering/

The Memory research repositories explain where the mechanisms came from.

They are not runtime dependencies.

Installing the plugin does not require cloning the book’s research implementation.

That distinction is an example of the same architectural rule the book eventually arrives at:

Ship the mechanisms that earned their place, not the laboratory that discovered them.

Evidence and validation

OpenCode Remembering has been developed as a sequence of independently tested failure repairs rather than as one large memory architecture.

The frozen contracts currently include:

routing
19 fixtures + 2 explicit overrides
= 21 / 21

temporal state
16 / 16

safe framing
10 / 10

trust and standing
17 / 17

Each stage retains its own evaluation identity.

They are not collapsed into a single score.

The live suite has also exercised the complete path against PostgreSQL, pgvector and Ollama bge-m3.

Important acceptance cases include:

historical SQLite
→ retained for recall

superseded SQLite
→ retrieved but suppressed for current influence

PostgreSQL
→ selected as current

late-arriving PostgreSQL state
→ absent from an earlier known-time view
→ present after the system learned it

same query "Review this."
+ architecture frame
→ architecture evidence first

same query "Review this."
+ release frame
→ release evidence first

wrong weak frame
→ SOFT_FRAME
→ baseline evidence retained

current + relevant + correctly framed poison
→ quarantined by trust

revoked benchmark
→ denied as guidance
→ still recallable

independently supported conflict
→ quarantine rather than rank-pick

These examples matter because each one isolates a different failure class.

Retrieval is not credited for temporal state.

Temporal resolution is not credited for framing.

Framing is not credited for authority.

Trust is not credited for finding the evidence.

The layers earn their jobs separately.

The Memory capstone made practical

Memory From First Principles begins with a strict definition:

Memory is when retained past experience changes what the system does now.

OpenCode Remembering is the practical application of that definition.

Its purpose is not to maximize the amount of history available to a model.

It is to build an inspectable path:

PAST
  |
  v
preserve
  |
  v
retrieve
  |
  v
interpret
  |
  v
resolve
  |
  v
frame
  |
  v
admit
  |
  v
select
  |
  v
PRESENT ACTION

Every arrow is a distinct place the system can fail.

Keeping those failures distinct is what makes the memory system measurable.

Main implementation surfaces

The repository is:

https://github.com/ernanhughes/opencode-remembering

The main implementation areas are:

src/                         OpenCode TypeScript integration
bridge/                      narrow TypeScript ↔ Python boundary

engine/remembering/baseline/
    storage, ingestion, embeddings,
    retrieval, routing, context

engine/remembering/temporal/
    event model, ordering, reducer,
    bitemporal query engine,
    PostgreSQL persistence

engine/remembering/frame/
    ProjectFrame, WorkSignal, WorkFrame,
    establishment and safe frame policy

engine/remembering/trust/
    standing, revocation, authority,
    instruction handling, corroboration,
    admit/deny/quarantine

engine/tests/                executable invariants and regressions

The TypeScript adapter integrates with OpenCode.

The bundled Python engine owns remembering semantics.

Use it

Clone the plugin:

git clone https://github.com/ernanhughes/opencode-remembering
cd opencode-remembering

Install the JavaScript and Python dependencies:

bun install
python -m pip install -r engine/requirements.txt

Build and test:

bun run check
bun run build

The production retrieval path expects PostgreSQL with pgvector and Ollama bge-m3.

ollama pull bge-m3

Configure the PostgreSQL connection and plugin settings, then initialize the current project:

bun run doctor
bun run setup
bun run refresh

You can inspect the system outside OpenCode through the development CLI:

bun src/dev-cli.ts search "hybrid retrieval"

bun src/dev-cli.ts context \
  "Where did we discuss routing?" \
  --route recall

bun src/dev-cli.ts temporal-state \
  --subject cache.metadata.database

bun src/dev-cli.ts frame-eval

bun src/dev-cli.ts trust-eval

Inside OpenCode, the same engine is available through the memory tools and automatic context hook.

Operating boundary

OpenCode Remembering is a working experimental memory runtime.

It demonstrates inspectable properties rather than claiming general human-like memory.

The current system establishes:

canonical automatic history capture
project-isolated storage
hybrid lexical + dense retrieval
recall/influence routing
bitemporal state resolution
supersession without historical deletion
safe project/work framing
wrong-frame fallback
explicit source standing
append-only revocation
derived-authority inheritance
structural corroboration
directive-memory screening
admit / deny / quarantine
bounded automatic context
reason-coded execution traces
standalone packaging

It does not thereby establish:

that every piece of arbitrary prose can be assigned reliable temporal structure

that claim lineage can always be extracted automatically

that marked untrusted text is harmless when shown to a model

that the current policy transfers unchanged to every reader model

that trust policy determines factual truth

that all disagreements can be resolved automatically

that a long-running memory can yet consolidate or forget safely

that automatic learned procedures are ready for action

that the current architecture is the final architecture

Those require their own evidence.

What comes next

The next engineering step is intentionally smaller than the previous ones.

Once evidence has passed:

retrieval
temporal resolution
safe framing
trust and standing

there can still be too much of it.

The next stage therefore asks:

Of the evidence already permitted to influence,
what is actually decisive?

The goal is a small bundle that keeps:

decisive evidence
required provenance
material disagreement
important negative evidence

while removing repeated restatements and low-value context.

After that, the accumulated execution record can become a first-class ContextTrace that answers the two questions a memory system must eventually be able to answer:

Why did this memory enter?

Why did that memory stay out?

Later work can then revisit unfinished work, explicit memory actions, consolidation, learning from experience and cross-host adapters.

The direction is deliberately conservative:

preserve the past

retrieve strongly

separate recall from influence

resolve time explicitly

establish the current work safely

treat authority as permission, not truth

keep provenance

spend context only where it matters

trace every consequential decision

and let the past influence the present
only through a path the system can explain

OpenCode Remembering is that path made executable.

The publishing loop Research → book → capstone → solution → real use → new evidence
Browse all solutions →