Skip to content

feat(memory): replace legacy file-based memory system with native MuninnDB integration#218

Closed
Aperrix wants to merge 16 commits into
swt-labs:mainfrom
Aperrix:feat/muninndb-integration
Closed

feat(memory): replace legacy file-based memory system with native MuninnDB integration#218
Aperrix wants to merge 16 commits into
swt-labs:mainfrom
Aperrix:feat/muninndb-integration

Conversation

@Aperrix

@Aperrix Aperrix commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Linked Issue

Fixes #219

What

Remove the legacy file-based memory system and make MuninnDB the native, unconditional memory infrastructure for all VBW agents. This eliminates dual code paths, removes silent bypass risks, and establishes a single contract: agents always use MuninnDB, and every failure is explicitly reported.

Why

VBW's cross-phase memory was historically handled by compile-rolling-summary.sh, which concatenated all SUMMARY.md files into a single ROLLING-CONTEXT.md file, then injected its content verbatim into agent context at compile time. This approach has structural limitations:

  • No relevance filtering. Agents receive the entire concatenated history regardless of what is relevant to their current task. Context budget is spent on noise.
  • Linear scaling. The injected payload grows with every phase. A 6-phase project injects 6 summaries, most of which are irrelevant to the current task.
  • No semantic retrieval. There is no concept of similarity or scoring — the agent must parse the concatenated text and decide what matters.

MuninnDB replaces this with muninn_activate(vault, context), which performs semantic search and returns only relevant memories ranked by similarity score. The agent gets what it needs, at the moment it needs it, without reading a growing file.

The integration up to now was hybrid: MuninnDB was added alongside the old system with feature flags (muninndb: true, rolling_summary: false), conditional guards (if muninn_activate is in your available tools), and silent fallbacks (if the tool call fails: proceed normally). This created three concrete problems:

  1. Dual maintenance. Both compile-rolling-summary.sh and MuninnDB memory calls had to be kept in sync. Changes to cross-phase memory required updates in two systems.
  2. Silent bypass. Conditional guards meant agents could skip memory with no trace. If MuninnDB was down, agents simply proceeded without recalling prior decisions — no error, no log, no notification.
  3. Redundant config. Two boolean flags (rolling_summary, muninndb) existed to gate the same capability. The brownfield migration system had to handle both, adding complexity to migrate-config.sh.

How

Architecture change: compile-time injection → runtime retrieval

The fundamental shift is when and how agents access cross-phase memory.

Before: compile-context.sh read ROLLING-CONTEXT.md and injected its content into .context-{role}.md files for each of the 6 compiled roles (lead, dev, qa, scout, debugger, architect). Each agent received the full concatenated history as a static text block in its context window.

After: compile-context.sh emits a "### Cross-Phase Memory" hint via a new emit_muninn_memory_hint() function, instructing the agent to call muninn_guide(vault) then muninn_activate(vault, context) at runtime. The agent performs the retrieval itself, scoped to its current task, and receives only semantically relevant results.

This moves memory access from a static compile-time operation to a dynamic runtime operation, which is both more relevant and more token-efficient.

Agent contract: unconditional calls with role-specific failure severity

All conditional MuninnDB language has been removed from the 7 agent files. There is no if available, no if NOT available: skip, no proceed normally fallback. Agents call MuninnDB tools unconditionally.

Each role has an explicit, differentiated failure behavior:

Role On MuninnDB failure Rationale
Lead STOP planning Prior phase decisions may constrain or invalidate plan structure
Architect STOP scoping Prior architectural decisions may invalidate the design
Dev Send blocker_report to Lead Past decisions may contradict the default implementation approach
QA Report warning in verification output Contradiction check is supplementary but must be visible to reviewers
Scout Report warning in findings Prior research may already cover this topic
Docs Report warning in output Prior naming conventions may conflict with new documentation
Debugger Report warning in diagnostic A similar bug may have been resolved in a prior phase

The severity distinction is intentional: Lead and Architect produce planning artifacts that downstream agents depend on — memory gaps here propagate. Dev, QA, Scout, Docs, and Debugger produce task-level output where a memory gap is visible but not structurally propagating.

Recall guardrails

Semantic retrieval is probabilistic — if the context string doesn't match well, critical prior decisions can be silently omitted. Multiple guardrails address this:

1. Phase-aware 0-result warning. All 6 agents that call muninn_activate now have standardized handling:

  • Results with score > 0.5: state [concept] — [how it informs approach]
  • 0 results in Phase 2+: emit ⚠ Memory recall returned 0 results despite prior phases — verify context parameter or check vault health
  • 0 results in Phase 1: state Memory: no prior context (first phase)

The context compiler (compile-context.sh) also emits a phase-aware warning via emit_muninn_memory_hint($PHASE, $ROLE) when phase > 1, with role-specific guidance (QA→contradictions, Debugger→bug context, Scout→prior research, Lead/Architect→contradictions).

2. Memory audit trail. A memory_recalled frontmatter field with concept names and relevance scores records what was consulted:

  • SUMMARY.md (Dev, Docs): populated with "concept-name (score: 0.8)"
  • PLAN.md (Lead): populated with concepts that informed decomposition
  • VERIFICATION.md (QA): populated with concepts from contradiction checks
  • If no results: ["none"]. If MuninnDB unavailable: ["unavailable"]
  • QA verifies the field is present and flags ["none"] in Phase 2+ as a warning

3. Deterministic hook enforcement. Two hooks provide deterministic (not prose-based) guardrails:

  • muninn-vault-gate.sh (SubagentStart): Blocks Lead and Architect from spawning when vault is unconfigured (exit 2). Advisory warning for other roles.
  • validate-summary.sh (PostToolUse): Warns when SUMMARY.md is missing the memory_recalled frontmatter field.

4. Contradiction detection. Lead (Phase 2+) and Architect (non-first milestone) call muninn_contradictions(vault) before decomposing/scoping to catch conflicting prior decisions pre-planning.

muninn_guide as mandatory first call

All 7 agents now call muninn_guide(vault) before any other MuninnDB tool. This retrieves vault-specific instructions, ensuring agents use the correct vault interface. The call is integrated at three levels:

  • Agent files: Part of the Memory Protocol section.
  • Context compiler: Included in the emit_muninn_memory_hint() output.
  • Init flow: Called in Step 0.6 after vault creation.
  • Compaction recovery: All agent roles include muninn_guide in compaction instructions.

Engram lifecycle management

Storage: Agents store engrams after work:

  • Dev: decisions (muninn_decide), bugs (Issue), patterns (Observation)
  • Lead: decisions, Scout engram consolidation post-research
  • Architect: requirements (Task), decisions
  • Scout: research findings (Observation)
  • QA: contradictions (Issue), verification patterns (Observation), pre-existing failures
  • Docs: documentation decisions (Decision)
  • Debugger: bugs with non-obvious causes (Issue)

Phase-end: Orchestrator stores a phase-level outcome engram (muninn_remember with type: Decision, tags: [phase:{N}, outcome]) before consolidation, ensuring downstream phases can recall what was delivered.

Consolidation: Phase-end and milestone-ship consolidation via muninn_consolidate with scoped muninn_activate (score > 0.3) to collect relevant engram IDs.

Archival: At milestone ship, engrams are tagged [milestone:{SLUG}, archived] via a milestone-level bookmark engram.

Session-start health check

Session start checks both MCP (port from muninndb_port_mcp, default 8750) and REST API (port from muninndb_port_rest, default 8475) with --max-time 1. When vault is configured, it verifies the vault exists on the server. Status messages:

  • MuninnDB: active (vault: {name}) — both ports healthy, vault exists
  • ⚠ vault '{name}' not found — server running but vault missing
  • MuninnDB: MCP active (vault: {name}, REST API not responding) — partial
  • ⚠ MuninnDB: NOT RUNNING — both ports unreachable

Multi-project vault isolation

muninn-setup.sh detects vault name collisions when two projects share a MuninnDB instance. If a vault with the derived name already exists and belongs to a different working directory, a hash-based disambiguator is appended to prevent cross-project memory pollution.

Memory observability

collect-metrics.sh supports MuninnDB-specific events: muninn_recall, muninn_recall_empty, muninn_store, muninn_unavailable, muninn_consolidate, muninn_contradictions. These enable answering "Is MuninnDB actually being used effectively?" via /vbw:status --metrics.

MuninnDB in /vbw:verify

Standalone verification mode now:

  • Recalls prior UAT patterns and known issues via muninn_activate before generating test scenarios
  • Stores UAT issues and discovered issues in MuninnDB after verification completes

MuninnDB in /vbw:discuss

Discussion mode now:

  • Recalls prior discussions and milestone decisions via muninn_activate (Step 1.5) before Orient phase
  • Stores each captured decision via muninn_decide in Step 4 Capture

Documentation

  • README.md: Full MuninnDB section with setup, agent usage, guardrails, and health check reference
  • docs/muninndb-troubleshooting.md: Common failure scenarios and fixes (server not running, vault missing, 0 results, port conflicts, multi-project collision)
  • references/muninn-types.md: Engram type documentation (Issue, Observation, Decision, Task) and full configuration parameter table
  • /vbw:doctor check 16: Updated to read ports from config, check both MCP and REST

Test coverage

79 tests in tests/muninn-integration.bats covering:

  • Config defaults and port keys
  • Context compiler hint emission for all 7 roles (lead, dev, qa, scout, debugger, architect, docs)
  • Phase-aware warning (present for phase > 1, absent for phase 1)
  • Empty vault warning in compiled context
  • Bootstrap and persist-state Memory section handling
  • All agents reference muninn_guide, muninn tools, empty vault guard, and failure behavior
  • Hook enforcement: vault gate (pass/block lead/block architect/advisory dev), hooks.json registration
  • Validate-summary: warns on missing memory_recalled, passes when present, ignores non-SUMMARY files
  • QA stores findings, Debugger stores bugs
  • Consolidation scoping (execute-protocol, vibe archive, lead scout consolidation)
  • Discussion engine recall and storage
  • Failure modes: no project dir, missing config, missing vault key, empty vault, nonexistent SUMMARY
  • Session-start: dual port check, max-time 1, vault existence verification
  • Doctor check 16: config-driven ports, MCP+REST checks
  • Metrics: MuninnDB event documentation
  • Multi-project vault isolation
  • Engram lifecycle: archive tagging at ship-time
  • memory_recalled enrichment: scores in template, PLAN.md (Lead), VERIFICATION.md (QA)
  • README MuninnDB section, troubleshooting guide existence

Cross-reference: agent MuninnDB call matrix

guide activate remember decide contradictions consolidate Stores after work memory_recalled Failure behavior
Dev yes yes (limit:10) yes (Issue, Observation) yes no no yes SUMMARY.md warn + blocker_report
Lead yes yes (limit:10) no yes yes (Phase 2+) yes (Scout engrams) yes (decisions) PLAN.md STOP
Architect yes yes (limit:10) yes (Task) yes yes (non-first milestone) no yes ROADMAP.md STOP
Scout yes yes (limit:5) yes (Observation) no no no yes warn
Debugger yes yes (limit:5) yes (Issue) no no no yes warn
Docs yes yes (limit:5) yes (Decision) no no no yes SUMMARY.md warn
QA yes no yes (Issue, Observation) no yes no yes VERIFICATION.md warn

Commits

Hash Description
0709482 Initial recall guardrails (phase-aware warnings, memory_recalled, QA verification)
b1e7ce5 P0 fixes: Debugger write-back, compaction muninn_guide, empty vault guard
8d6728c Deterministic hook enforcement (vault gate, validate-summary)
3461143 P1: QA storage, docs context, engram type docs
29f8dda P1: Consolidation scoping, discuss mode integration
9cb799a P1-6: MuninnDB failure mode tests
5ca20ba P1-1: Centralise MuninnDB config, document defaults
5ae923f P2: Contradictions, role-specific hints, phase outcome engrams
b50a7c0 P2: Lifecycle, observability, docs, session hardening, vault isolation

Files changed

Category Files
Agents vbw-dev.md, vbw-lead.md, vbw-qa.md, vbw-scout.md, vbw-debugger.md, vbw-architect.md, vbw-docs.md
Commands verify.md, vibe.md, doctor.md
Scripts compile-context.sh, session-start.sh, compaction-instructions.sh, muninn-setup.sh, collect-metrics.sh, muninn-vault-gate.sh (new), validate-summary.sh
References execute-protocol.md, discussion-engine.md, muninn-types.md (new)
Config defaults.json, hooks.json
Templates SUMMARY.md
Tests muninn-integration.bats (79 tests), test_helper.bash
Docs README.md, docs/muninndb-troubleshooting.md (new)

Notes

  • muninn_contradictions in QA is non-blocking by design (supplementary check), but explicitly reports failure instead of silently skipping.
  • The 1 pre-existing test failure in two-phase-completion.bats (artifact-registry: register creates entry) is unrelated to this PR.
  • ShellCheck is not installed locally — CI runs it on Ubuntu.

@Aperrix Aperrix changed the title feat(memory): native MuninnDB integration feat(memory): native MuninnDB integration — remove legacy memory system Mar 7, 2026
@Aperrix
Aperrix force-pushed the feat/muninndb-integration branch 5 times, most recently from 80ec0c3 to 53c7cd9 Compare March 7, 2026 13:56
Aperrix added 4 commits March 7, 2026 15:12
MuninnDB replaces the file-based rolling summary as the cross-phase
memory system. Remove all traces:

- Delete compile-rolling-summary.sh and its tests
- Remove rolling_summary config flag from defaults and rollout stages
- Clean compile-context.sh: remove ROLLING_CONTEXT injection and
  Activity Log blocks from all 6 role templates
- Clean cache-context.sh: remove rolling context fingerprint from
  cache key computation
- Clean bootstrap-state.sh and persist-state-after-ship.sh: remove
  Activity Log generation and extraction
- Clean templates/STATE.md: remove Activity Log section
- Clean vibe.md: remove deprecated rolling summary compilation step
- Clean execute-protocol.md: replace REQ-03 rolling summary block
  with MuninnDB consolidation reference
- Clean compaction-instructions.sh and post-compact.sh: replace
  rolling context re-read instructions with MuninnDB recall
- Remove rolling_summary references from all test files
Add MuninnDB as native memory infrastructure for VBW:

- Add muninn-setup.sh: vault creation with REST API retry (3x with
  backoff), MCP config detection, API token resolution
- Extend init.md Step 0.6: vault setup with muninn_guide call,
  hard failure on REST API or vault creation errors
- Add doctor.md check swt-labs#16: MuninnDB binary, health, and vault
  verification
- Add status.md MuninnDB section: vault name and health indicator
- Add session-start.sh warning when MuninnDB is not running
- Add muninndb_vault to config.md settings reference and README
- Add muninndb_vault to bootstrap-claude.sh env export
MuninnDB is now native infrastructure, not an optional addon. Remove
all conditional language ("if muninn_activate is available") and add
explicit failure handling per role:

- Lead/Architect: STOP on MuninnDB failure (planning depends on
  prior decisions)
- Dev: send blocker_report to Lead on failure
- QA: report "⚠ unavailable" in verification output
- Scout/Docs/Debugger: report "⚠" in output section

Also:
- Add muninn_guide call to compile-context.sh cross-phase memory hint
- Make muninn_consolidate MANDATORY at phase end in execute-protocol
- Keep V2 envelope reference in execute-protocol message send section
New test files:
- muninn-setup.bats: 10 tests covering vault creation, REST API
  retry logic, MCP config detection, error handling
- muninn-integration.bats: 18 tests verifying MuninnDB is referenced
  unconditionally across all agents, compile-context, init, and
  session-start

Updated tests:
- role-isolation.bats: verify V2 Role Isolation heading in all agents,
  lease in V2 gate sequence reference
- Rename muninn-v2-integration.bats → muninn-integration.bats
- Minor test description updates for consistency
@Aperrix
Aperrix force-pushed the feat/muninndb-integration branch from 53c7cd9 to 57a3c7b Compare March 7, 2026 14:13
Aperrix added 3 commits March 7, 2026 15:27
- Fix duplicate/misplaced comment block in compile-context.sh: the codebase
  mapping hint helper comment was stranded above emit_muninn_memory_hint()
  instead of above emit_codebase_mapping_hint() where it belongs
- Fix missing blank line before ## Output Format heading in doctor.md
- Make agent MuninnDB reference tests fail explicitly per-agent instead
  of silently skipping missing files (muninn-integration.bats)
- Remove no-op assertion in muninn-setup --check test: `|| true` made
  the exit status check always pass regardless of actual result
- Remove stale "Activity Log" reference from vibe.md archive step: Activity
  Log was removed from STATE.md in this PR but the description still listed it
  as a milestone-specific section
- Add "Memory" to the list of project-level sections preserved across milestones
@Aperrix Aperrix changed the title feat(memory): native MuninnDB integration — remove legacy memory system feat(memory): replace legacy file-based memory system with native MuninnDB integration Mar 7, 2026
Aperrix added 9 commits March 7, 2026 16:34
Phase-aware warnings when muninn_activate returns 0 results in Phase 2+
(expected in Phase 1, suspicious later). Standardize explicit results
handling across all 6 agents. Add memory_recalled field to SUMMARY.md
template for audit trail. Instruct Dev/Docs to populate it and QA to
verify it.
P0-1: Debugger now stores bug resolutions and patterns back to MuninnDB
via muninn_remember after diagnosing/fixing.

P0-2: All 7 compaction instruction roles and post-compact.sh now include
muninn_guide call before muninn_activate, matching agent file requirements.
Also adds missing codebase re-read for docs agent compaction.

P0-3: All 7 agents and compile-context.sh now guard against empty
muninndb_vault — report warning and continue without memory instead of
passing empty string to MuninnDB calls.
SubagentStart hook (muninn-vault-gate.sh) blocks Lead/Architect spawn
when vault is unconfigured. PostToolUse hook (validate-summary.sh)
checks memory_recalled field in SUMMARY.md frontmatter.
P1-3: QA agent now stores contradictions, useful verification patterns,
and pre-existing failure classifications to MuninnDB after verification.

P1-4: Added docs role to compile-context.sh — Docs agents now receive
the same phase context (goal, criteria, conventions, MuninnDB hint,
codebase mapping) as all other roles.

P1-7: Created references/muninn-types.md documenting canonical engram
types (Issue, Observation, Decision, Task) and their usage by each agent.
P1-2: Phase-end consolidation now collects engram IDs via
muninn_activate before calling muninn_consolidate, matching
the ship-time pattern. Prevents unscoped vault-wide consolidation.

P1-5: Discussion engine now recalls prior decisions via
muninn_activate before generating gray areas, and stores
decisions via muninn_decide after capture.
Tests for: vault gate with no project dir, missing config, missing
vault key, compile-context with empty/missing config, validate-summary
edge cases, agent failure behavior specs, session-start health check.
Added muninndb_port_mcp and muninndb_port_rest to defaults.json.
Updated session-start.sh and muninn-setup.sh to read ports from config
instead of hardcoding. Expanded references/muninn-types.md into a full
MuninnDB reference documenting all config parameters, recall limits
(10 for planning agents, 5 for task agents), and score thresholds.
…ngrams

P2-1: Lead and Architect now call muninn_contradictions pre-planning
to catch conflicting prior decisions before decomposing, preventing
rework discovered during QA.

P2-7: compile-context.sh emits role-specific memory hints — QA gets
contradictions reminder, Debugger gets bug-focused context guidance,
Scout gets prior research check, Lead/Architect get contradictions.

P2-8: Compaction wildcard fallback now includes MuninnDB recovery
instructions for inline orchestrator sessions.

P2-9: Phase-level outcome engram stored before consolidation at phase
end, ensuring downstream phases can recall what was delivered even
after individual task engrams are consolidated.
P2-2: Memory observability metrics (muninn_recall/store/unavailable events)
P2-3: memory_recalled enrichment with scores, extend to PLAN.md and VERIFICATION.md
P2-4: Engram lifecycle management — archived tagging at milestone ship
P2-5: Scout post-research consolidation in Lead agent
P2-6: Session-start hardening — REST API check, vault existence verification
P2-10: MuninnDB recall/storage in /vbw:verify
P2-11: Tests for consolidation calls across protocol/vibe/lead
P2-12: Tests for session-start dual-port health check
P2-13: Tests for doctor check 16 config-driven ports
P2-14: Session-start health check latency reduced (2s → 1s)
P2-15: README MuninnDB section with setup, usage, and guardrails
P2-16: Troubleshooting guide at docs/muninndb-troubleshooting.md
P2-17: Vault isolation with multi-project collision detection
@dpearson2699 dpearson2699 added enhancement New feature or request labels Mar 10, 2026
@dpearson2699

Copy link
Copy Markdown
Member

Closing as Muninn's license isn't permissible in an MIT project so it wouldn't be compatible with VBW.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: native MuninnDB integration — remove legacy memory system

2 participants