Releases: sdwolf4103/opencode-working-memory
v1.6.4
Rolling Weekly Reinforcement
This patch release fixes the reinforcement policy for users who work in long-lived OpenCode sessions. Reinforcement no longer treats same_session as a hard block. Instead, each memory uses a rolling 7-day elapsed window, so recurring preferences can be reinforced after meaningful weekly use even when the session stays open.
The base retention half-life remains 45 days. The max reinforcement count remains 6, but it now acts as a growth saturation point rather than a lifetime hard stop.
What Changed
- 7-day rolling window: repeated reinforcement is allowed once 7 rolling days have elapsed since the memory's last reinforcement; 7 days minus 1ms still blocks.
- Same-session as evidence:
sameSessionis recorded for diagnostics but no longer blocks reinforcement by itself. - Refresh-only saturation: memories at reinforcement count 6 can refresh
retentionClock,lastReinforcedAt, and session evidence after the weekly window without increasing count or effective half-life. - Instrumentation v3: new reinforcement evidence records elapsed-window fields,
sameSession,reinforcementMode, and legacy missing timestamp markers. - Diagnostics updated:
memory-diag commands --memoryexposes the new fields, whilememory-diag qualitykeeps historicalsame_sessionblock analysis separate from new same-session evidence.
Upgrade Notes
- No configuration changes are required.
- Existing workspace memory files and evidence logs remain compatible.
- Historical diagnostics may still show older block reasons such as
same_session,same_utc_day,min_interval, ormax_count; new instrumentation-version-3 events use the rolling elapsed-window semantics. - Consumers of
memory-diag commands --memory --jsonshould usereinforcementModeto distinguish count-increment reinforcement from refresh-only saturation.
Validation
node --test --experimental-strip-types tests/retention.test.ts— 10 tests passingnode --test --experimental-strip-types tests/workspace-memory.test.ts tests/plugin.test.ts— 181 tests passingnode --test --experimental-strip-types tests/memory-diag.test.ts tests/memory-diag-quality.test.ts— 93 tests passingnpm run typecheck—TYPECHECK_PASSnpm test— 498 tests passing,TEST_PASSnpm run build—BUILD_PASS
v1.6.3
Diagnostic Quality Review Board
This patch release focuses on safer memory diagnostics. It adds a read-only quality review board and finer reinforcement drill-downs so reviewers can inspect memory-system evidence without treating historical artifacts as current failures or turning heuristic flags into automatic cleanup decisions.
The goal is better observability before policy changes: diagnostics show facts, provenance, answerability, and review questions, while leaving judgment to the operator.
What Changed
- Quality review board:
memory-diag qualitynow reports system-mechanism facts for rejection filters, reinforcement rules, eviction/caps, identity/dedup, and active memory content review. - Version/provenance context: diagnostics distinguish current producer-instrumented events from historical or unversioned evidence where possible, and label ambiguous evidence conservatively.
- Focused reinforcement drill-down:
memory-diag commands --memory <memory-id>shows one memory's reinforcement command evidence, current status, recorded block reasons, missing details, and UTC-day evidence. - Canonical active-memory JSON surface:
memory-diag quality --jsonnow usesactiveMemoryDisplayas the single active-memory review surface instead of duplicating active memories underreviewCandidates. - Attribution-safe wording: quality and reinforcement diagnostics avoid claiming that a block is a bug, policy failure, or cause of memory loss; they present recorded evidence and review prompts instead.
Upgrade Notes
- No configuration changes are required.
- Existing workspace memory files and evidence logs remain compatible.
- If you consume
memory-diag quality --jsonfrom unreleased builds after v1.6.2, read active-memory review data fromactiveMemoryDisplay;reviewCandidatesis now reserved for system-mechanism candidates.
Useful Commands
npx --package opencode-working-memory@1.6.3 memory-diag quality
npx --package opencode-working-memory@1.6.3 memory-diag quality --json
npx --package opencode-working-memory@1.6.3 memory-diag commands --memory <memory-id>Validation
node --test --experimental-strip-types tests/memory-diag-quality.test.ts— 53 tests passingnode --test --experimental-strip-types tests/memory-diag.test.ts— 39 tests passingnpm run typecheck—TYPECHECK_PASSnpm test— 486 tests passing,TEST_PASSnpm run build—BUILD_PASSnpm run test:pack:memory-diag— packed tarball smoke test passed
v1.6.2
Published memory-diag Bin Fix
This patch release fixes the published npm package path for memory-diag. In v1.6.1 the source-tree CLI tests passed, but the installed package could fail under npx --package opencode-working-memory memory-diag because Node refuses TypeScript type stripping for files inside node_modules.
v1.6.2 compiles the diagnostics CLI during packing and makes the npm bin launch the compiled JavaScript runtime.
What Changed
- Compiled diagnostics runtime:
prepacknow buildsdist/scripts/memory-diag.jsbefore the package is packed or published. - Safer npm bin wrapper:
memory-diagno longer runs published.tsfiles through--experimental-strip-types; it launches the compiled JS artifact and reports a clear reinstall/build message if the artifact is missing. - Packaged-bin smoke test: release verification now includes a pack/npx smoke test from a temp consumer project outside the repository.
Upgrade Notes
- No config changes are required.
- Existing OpenCode server and TUI plugin entry points are unchanged.
- If you hit the v1.6.1 bin failure, upgrade and rerun:
npx --package opencode-working-memory@1.6.2 memory-diag --helpValidation
npm run build—BUILD_PASSnode ./scripts/memory-diag-bin.cjs --helpnpm run test:pack:memory-diag— packed tarball smoke test passednpm run typecheck—TYPECHECK_PASSnpm test— 421 tests passing,TEST_PASSnpm pack --dry-run— includes compileddist/diagnostics artifacts
v1.6.1
Release Notes
1.6.1 (2026-05-08)
Native TUI Memory Menu
This release adds a native OpenCode TUI memory menu so users can inspect local working memory without asking the model and without adding command output to the conversation transcript.
Open /memory in the TUI to browse memory status, current workspace memories, and help from native dialogs.
Memory should stay visible when you need it — and stay out of the transcript when you are only inspecting it.
/memory
│
├─ Status
│ local counts and memory health
│
├─ Current memories
│ searchable grouped [M#] refs
│
└─ Help
local usage notes
What Changed
- Single TUI entry point:
/memoryopens a native submenu instead of exposing multiple memory slash commands. - Searchable current memory list:
Current memoriesuses OpenCode's native select dialog for bounded scrolling, filtering, and grouping. - Transcript-free inspection: memory status, list, help, empty states, and errors render in native dialogs instead of user-style session messages.
- Server and TUI plugin exports: the package exposes
./serverand./tuientry points for OpenCode plugin loading. - User docs refreshed: README highlights the
/memoryworkflow and moves the full diagnostics CLI reference todocs/diagnostics.md.
Upgrade Notes
- Add
.opencode/tui.jsonif you want the native/memoryTUI menu. Existing server-only configuration continues to work. - Restart OpenCode after adding the TUI plugin config.
- The TUI menu is read-only and local-only. It does not call the LLM.
- Individual memory row selection is intentionally a no-op in this release; use the list for inspection and search.
Validation
npm run typecheck—TYPECHECK_PASSnpm test— 421 tests passing,TEST_PASSnpm pack --dry-run- Real OpenCode TUI smoke test for
/memorymenu, searchable current memories, and transcript-free output.
1.6.0 (2026-05-08)
Numbered Memory Refs
This release turns compaction from a one-way memory extractor into a memory maintenance loop. The model now sees numbered references for existing workspace memories and can explicitly reinforce a still-useful memory or propose a protected replacement when compaction reveals that old memory is obsolete.
The goal is not to make memory more aggressive. It is to make memory more accountable: old facts should be strengthened when they keep proving useful, replaced only when the target is safe, and diagnosable when the model tries something risky.
Good memory is selective memory.
v1.6 lets memory say “this still matters” without copying it again — and lets obsolete compaction memories fade behind a safer replacement trail.
compaction summary
│
▼
Memory candidates:
Memory ref snapshot id: <uuid>
[M1] decision · reinforced=2 · source=explicit
[M2] project · reinforced=0 · source=compaction
│
├─ REINFORCE [M1]
│ ↑ slows decay, no text mutation
│
└─ REPLACE [M2] project Updated durable fact
↑ only allowed for safe compaction targets
What Changed
- Numbered memory refs: compaction prompts now render existing workspace memories as
[M1],[M2], ... references so the model can target a known memory instead of restating it as a duplicate candidate. - REINFORCE commands:
REINFORCE [M#]increments the target memory's reinforcement count and updates its retention clock without changing its text. - Protected REPLACE commands:
REPLACE [M#] [type] textsupersedes the old memory and appends a replacement only when the target is safe: active, compaction-sourced, and not already reinforced. - Reinforce + append workflow: when a memory is mostly right but needs more context, compaction can reinforce the old memory and emit a new candidate for the new durable fact instead of mutating history.
- Compaction prompt restructure: verbose type definitions and the old “reuse existing wording exactly” instruction were replaced with shorter command rules, categorization guidance, and concrete memory-operation examples.
- Hot state removed from compaction context: active files, current errors, and pending session state remain in normal prompt context but are no longer duplicated inside the compaction prompt, saving budget and reducing accidental promotion of transient state.
- New hard quality gates: unresolved questions, transient bug/debug state, and deployment snapshots are rejected as durable memory candidates.
- Soft terse-label diagnostic: very short label-like candidates are reported for tuning without being hard-rejected in v1.6.
- Decision cap raised: rendered decision memories now have a per-type cap of 12 instead of 10, while the global rendered cap remains 28.
- Overlap guard for compaction refs: memory ref snapshots are tagged with a compaction ID when available, so overlapping same-session compactions cannot silently apply commands against the wrong numbered snapshot.
- Safer evidence semantics: rejected memory command events use a neutral
targetrelation role instead of lifecycle roles such asreinforcedorsuperseded.
Why This Helps
- Useful memories can become stronger through real reuse instead of duplicate extraction.
- Obsolete compaction-sourced memories can be replaced with an explicit evidence trail rather than left to drift.
- Manual, explicit, and already-reinforced memories are protected from automatic replacement.
- Compaction prompt budget is spent on durable memory maintenance, not on duplicated hot session state.
- Command outcomes are visible enough to tune the feature after release instead of guessing from reinforcement counts alone.
Diagnostics
Inspect command behavior with:
npx --package opencode-working-memory memory-diag commands
npx --package opencode-working-memory memory-diag commands --verbose
npx --package opencode-working-memory memory-diag commands --jsonThe command report includes:
- compactions with command evidence
- REINFORCE and REPLACE counts
- reinforced, superseded, rejected, and blocked outcomes
- invalid or malformed command counts
- same-type vs cross-type replacements
- protected REPLACE blocks, split by reinforced target and protected source
- latest command events in verbose mode
If a numbered replacement needs manual recovery, use the dry-run-first revert command:
npx --package opencode-working-memory memory-diag revert --memory <replacement-memory-id>
npx --package opencode-working-memory memory-diag revert --memory <replacement-memory-id> --applyYou can also target a replacement evidence event directly:
npx --package opencode-working-memory memory-diag revert --event <event-id>Safety Model
- REINFORCE never edits memory text.
- REPLACE is rejected for manual or explicit memories.
- REPLACE is rejected for already reinforced targets.
- REPLACE is rejected if the numbered ref no longer matches the current memory ID, status, and exact key.
- If a compaction snapshot ID is present and mismatched, all numbered commands from that summary are rejected with
missing_memory_ref_snapshot. - If the model omits the snapshot ID, v1.6 falls back to exact memory ref validation for compatibility and command effectiveness.
Upgrade Notes
- No configuration changes required.
- Existing workspace memory files remain compatible.
- Existing session state remains compatible; old sessions without compaction ref snapshots fall back safely.
- Existing evidence logs remain compatible; new command events are appended only after v1.6 runs.
memory-diagnow exposes two additional public commands:commandsandrevert.
Validation
npm run typecheck—TYPECHECK_PASSnpm test— 405 tests passing,TEST_PASS
1.5.5 (2026-05-05)
Hot State Rendering Health
This release replaces blunt prompt truncation with a section-aware greedy renderer that fits whole lines and suppresses empty sections, plus render accounting types for future diagnostics.
Good rendering is selective too. If a section doesn't fit, omit it — don't cut it in half.
What Changed
- Whole-line rendering: the hot session state prompt no longer truncates mid-line with
.slice(0, maxRenderedChars). A greedy line accumulator fits complete lines and stops when the next line would exceed the 700-char budget. - Header-only sections suppressed: a section heading is only rendered if at least one entry fits alongside it. No more orphaned
active_files:headers with no content underneath. - Render accounting:
accountHotSessionStateRender()now returnsprompt,omitted[], andmaxRenderedCharsso future v2 diagnostics can surface which items fell out and why. - Two-layer omission model: section caps (
section_cap) trim per-type overflow first, then the char budget (char_budget) trims anything that doesn't fit. Each omitted item carries its reason and section. - Backward-compatible wrapper:
renderHotSessionState()delegates to the accounting function and returns just the prompt string, preserving existing plugin behavior.
Docs Fixes
- Active-file ranking formula corrected:
docs/configuration.mdnow matches the actual implementation —ACTION_WEIGHT[action] + count * 3with weights edit 50, write 45, grep 30, read 20, tie-break bylastSeendescending. The old docs claimedcount * action_weight * recency_decaywith weights 4/3/2/1. - Injection order clarified: README now explains that workspace memory and hot state system-prompt positions depend on whether workspace memory state is available.
Not Included Yet
- Evidence events for omitted items are deferred to v2, pending a
memory-diagconsumer to avoid unused storage litter.
Upgrade Notes
- No configuration changes required.
- Existing workspace memory file...
v1.6.0
Numbered Memory Refs
This release turns compaction from a one-way memory extractor into a memory maintenance loop. The model now sees numbered references for existing workspace memories and can explicitly reinforce a still-useful memory or propose a protected replacement when compaction reveals that old memory is obsolete.
The goal is not to make memory more aggressive. It is to make memory more accountable: old facts should be strengthened when they keep proving useful, replaced only when the target is safe, and diagnosable when the model tries something risky.
Good memory is selective memory.
v1.6 lets memory say “this still matters” without copying it again — and lets obsolete compaction memories fade behind a safer replacement trail.
compaction summary
│
▼
Memory candidates:
Memory ref snapshot id: <uuid>
[M1] decision · reinforced=2 · source=explicit
[M2] project · reinforced=0 · source=compaction
│
├─ REINFORCE [M1]
│ ↑ slows decay, no text mutation
│
└─ REPLACE [M2] project Updated durable fact
↑ only allowed for safe compaction targets
What Changed
- Numbered memory refs: compaction prompts now render existing workspace memories as
[M1],[M2], ... references so the model can target a known memory instead of restating it as a duplicate candidate. - REINFORCE commands:
REINFORCE [M#]increments the target memory's reinforcement count and updates its retention clock without changing its text. - Protected REPLACE commands:
REPLACE [M#] [type] textsupersedes the old memory and appends a replacement only when the target is safe: active, compaction-sourced, and not already reinforced. - Reinforce + append workflow: when a memory is mostly right but needs more context, compaction can reinforce the old memory and emit a new candidate for the new durable fact instead of mutating history.
- Compaction prompt restructure: verbose type definitions and the old “reuse existing wording exactly” instruction were replaced with shorter command rules, categorization guidance, and concrete memory-operation examples.
- Hot state removed from compaction context: active files, current errors, and pending session state remain in normal prompt context but are no longer duplicated inside the compaction prompt, saving budget and reducing accidental promotion of transient state.
- New hard quality gates: unresolved questions, transient bug/debug state, and deployment snapshots are rejected as durable memory candidates.
- Soft terse-label diagnostic: very short label-like candidates are reported for tuning without being hard-rejected in v1.6.
- Decision cap raised: rendered decision memories now have a per-type cap of 12 instead of 10, while the global rendered cap remains 28.
- Overlap guard for compaction refs: memory ref snapshots are tagged with a compaction ID when available, so overlapping same-session compactions cannot silently apply commands against the wrong numbered snapshot.
- Safer evidence semantics: rejected memory command events use a neutral
targetrelation role instead of lifecycle roles such asreinforcedorsuperseded.
Why This Helps
- Useful memories can become stronger through real reuse instead of duplicate extraction.
- Obsolete compaction-sourced memories can be replaced with an explicit evidence trail rather than left to drift.
- Manual, explicit, and already-reinforced memories are protected from automatic replacement.
- Compaction prompt budget is spent on durable memory maintenance, not on duplicated hot session state.
- Command outcomes are visible enough to tune the feature after release instead of guessing from reinforcement counts alone.
Diagnostics
Inspect command behavior with:
npx --package opencode-working-memory memory-diag commands
npx --package opencode-working-memory memory-diag commands --verbose
npx --package opencode-working-memory memory-diag commands --jsonThe command report includes:
- compactions with command evidence
- REINFORCE and REPLACE counts
- reinforced, superseded, rejected, and blocked outcomes
- invalid or malformed command counts
- same-type vs cross-type replacements
- protected REPLACE blocks, split by reinforced target and protected source
- latest command events in verbose mode
If a numbered replacement needs manual recovery, use the dry-run-first revert command:
npx --package opencode-working-memory memory-diag revert --memory <replacement-memory-id>
npx --package opencode-working-memory memory-diag revert --memory <replacement-memory-id> --applyYou can also target a replacement evidence event directly:
npx --package opencode-working-memory memory-diag revert --event <event-id>Safety Model
- REINFORCE never edits memory text.
- REPLACE is rejected for manual or explicit memories.
- REPLACE is rejected for already reinforced targets.
- REPLACE is rejected if the numbered ref no longer matches the current memory ID, status, and exact key.
- If a compaction snapshot ID is present and mismatched, all numbered commands from that summary are rejected with
missing_memory_ref_snapshot. - If the model omits the snapshot ID, v1.6 falls back to exact memory ref validation for compatibility and command effectiveness.
Upgrade Notes
- No configuration changes required.
- Existing workspace memory files remain compatible.
- Existing session state remains compatible; old sessions without compaction ref snapshots fall back safely.
- Existing evidence logs remain compatible; new command events are appended only after v1.6 runs.
memory-diagnow exposes two additional public commands:commandsandrevert.
Validation
npm run typecheck—TYPECHECK_PASSnpm test— 405 tests passing,TEST_PASS
v1.5.5
Hot State Rendering Health
Replace blunt .slice(0, maxRenderedChars) prompt truncation with a section-aware greedy line accumulator that fits whole lines and suppresses empty sections.
Good rendering is selective too. If a section doesn't fit, omit it — don't cut it in half.
What Changed
- Whole-line rendering: hot session state prompt no longer truncates mid-line. A greedy accumulator fits complete lines and stops when the next line would exceed the 700-char budget.
- Header-only sections suppressed: a section heading is only rendered if at least one entry fits alongside it.
- Render accounting:
accountHotSessionStateRender()returns prompt, omitted items, and char budget for future v2 diagnostics. - Two-layer omission model: section caps (
section_cap) trim per-type overflow first, then char budget (char_budget) trims anything that doesn't fit. - Backward-compatible wrapper:
renderHotSessionState()delegates to the accounting function.
Docs Fixes
- Active-file ranking formula corrected in
docs/configuration.md: now matches actual implementation —ACTION_WEIGHT[action] + count * 3with weights edit 50, write 45, grep 30, read 20. - Injection order clarified in README: system-prompt positions depend on whether workspace memory state is available.
Not Included Yet
- Evidence events for omitted items deferred to v2, pending a
memory-diagconsumer.
Validation
npm run typecheck— TYPECHECK_PASSnpm test— 356 tests passing
v1.5.4
v1.5.4 — Memory-Diag CLI Surface Cleanup
What changed
- Removed legacy CLI aliases:
health,quality,rejections,disappearances, andtraceare no longer recognized. They return a plainUnknown subcommandmessage with no migration redirect, to avoid carrying compatibility debt. - Centralized command metadata: All command definitions now live in
command-metadata.tsas the single source of truth. - Official commands unchanged:
status,rejected,missing,explaincontinue to work as before. - Hidden maintainer commands preserved:
coverageandauditremain available with neutral maintainer-only notices. - Removed
cleanup:workspacesscript: The npm script is gone frompackage.json; the dev tool source file is preserved for internal use.
Test evidence
- 347 tests passing
- Typecheck clean
- All CLI smoke checks verified
- Independent phase verification: PASS (15/15 checks)
- Comprehensive code review: APPROVE
Migration
If you were using legacy aliases:
| Old alias | Use instead |
|---|---|
health |
status |
quality |
status --verbose |
rejections |
rejected |
disappearances |
missing |
trace <id> |
explain --memory <id> |
v1.5.3
Published Memory Diagnostics CLI
This release makes the read-only workspace memory diagnostics CLI available as the package binary memory-diag, with user-facing commands for checking memory health and understanding why memories are rejected, missing, shown, or hidden.
Good memory is selective memory — and diagnostics should explain the selection.
What Changed
- Published CLI bin: run diagnostics with
npx --package opencode-working-memory memory-diagormemory-diag status. - User-facing commands:
status,rejected,missing, andexplain <memory-id>are documented as the supported public workflow. - Legacy compatibility: existing maintainer and legacy commands remain accepted with deprecation notices where applicable.
- Cleaner CLI architecture: the former monolithic diagnostics script is now split into focused command, model, formatter, and utility modules.
- Faster diagnostics: evidence grouping avoids repeated per-memory evidence queries in snapshot diagnostics.
- Cleaner failures: top-level CLI error handling now reports usage and unexpected command errors without noisy stack traces.
- Docs alignment: README and configuration docs now use package-qualified
npxcommands to avoid resolving an unrelated package namedmemory-diag.
Requirements
- Node.js
>=22.6.0is now required because the published diagnostics binary runs TypeScript through Node's--experimental-strip-typessupport.
Validation
npm run typecheck—TYPECHECK_PASSnpm test— 358 tests passing,TEST_PASS
v1.5.2
Summary
- Close capacity-driven workspace-memory disappearance evidence gaps with storage-level removal events.
- Add focused memory inspection CLI surfaces: quality, coverage, disappearances, and rejection quality review.
- Harden memory quality decisions, rejection scoping, retention clock backfill, and verification sentinels.
Verification
- npm test -> TEST_PASS (290 passing)
- rtk npm run typecheck -> TYPECHECK_PASS
- CLI smoke: quality, coverage, disappearances, disappearances --explain, rejections --quality
v1.5.1
Evidence Loop and Explainability
This release adds an evidence-based audit trail for memory lifecycle events and user-facing diagnostics for understanding why memories are rendered, promoted, or rejected.
Evidence before sublimation. Every memory decision can be traced.
What Changed
- Evidence log: extraction, promotion, reinforcement, render, and storage events are now recorded in a per-workspace
events.jsonlwith 90-day retention and 5000-event cap. - User explainability:
memory-diag explainshows per-memory render status with strength, reasons, and evidence.memory-diag trace --memory <id>shows the full lifecycle history. - Machine-readable diagnostics:
memory-diag health --jsonoutputs structuredMemoryDiagJSONfor scripting. - Calendar-day reinforcement gate: reinforcement now requires distinct UTC calendar days, preventing repetitive-task gaming that could inflate a memory's strength within a single day.
- SafetyCritical deprecation complete: the
safetyCriticalfield no longer affects retention strength or type-cap bypass. All memories fade by the same rules. - Retention module extraction: retention constants and calculations moved to
src/retention.tsfor cleaner separation.
Privacy
- Evidence text previews are credential-redacted. Memory content is stored as truncated hashes, never in full.
- Diagnostics default to redacted output.
--rawis available for maintainers.
Upgrade Notes
- No configuration changes required.
- Existing workspace memory files remain compatible.
- Evidence logs are created automatically; no migration needed.
Validation
npm run typechecknpm test— 271 tests passing