LangENKO

Decision Memory (ADR)

Persistent architectural memory for agents — save, search, and enforce decisions.

since v0.22
On this page

Decision Memory (ADR)

Agents forget. Every new session restarts from zero — "should we use Postgres or MySQL?", "where do we put auth middleware?", "why is this file named weirdly?" Mandu's Decision Memory is a typed, searchable log of architectural decisions so your project has a consistent voice across sessions, across contributors, and across models.

Based on RFC-001. Accessed via @mandujs/core/guard or the MCP tools mandu.decision.list / save / check / architecture.

Why

  • Stop re-litigating: an agent asking "use JWT or session cookies?" searches first, sees the prior ADR, and proceeds.
  • Enforce consistency: checkConsistency() verifies the actual code matches the declared decisions. Drift gets flagged.
  • Travel across sessions: decisions persist in .mandu/decisions/ (git-committable) — every future agent inherits them.

Saving a decision

import { saveDecision } from "@mandujs/core/guard";

await saveDecision(rootDir, {
  id: "ADR-002",
  title: "Use PostgreSQL with Drizzle",
  status: "accepted",
  context: "Need relational DB; team knows SQL; multi-tenant coming soon.",
  decision: "Postgres 16 on Neon + Drizzle ORM for schema & queries.",
  consequences: [
    "Must manage migrations (drizzle-kit)",
    "No Mongo-style schemaless fields — commit to schemas",
  ],
  tags: ["database", "orm"],
});

Status values: proposed, accepted, deprecated, superseded.

Searching

import { searchDecisions } from "@mandujs/core/guard";

const hits = await searchDecisions(rootDir, ["auth", "jwt"]);
for (const hit of hits) {
  console.log(hit.id, hit.title, hit.status);
}

Search is tag + title + context based — fast full-text across all stored ADRs. Agents should search before making architectural proposals.

Architecture snapshot

Get a compact digest of the project's current decisions and structure — useful as LLM context at the start of an agent session:

import { getCompactArchitecture } from "@mandujs/core/guard";

const arch = await getCompactArchitecture(rootDir);
// {
//   layers: [...],
//   activeDecisions: [{ id: "ADR-002", title: "..." }, ...],
//   dependencyGraph: {...},
// }

The MCP tool mandu.decision.architecture wraps this for you.

Consistency check

Verify the codebase still matches its declared decisions:

import { checkConsistency } from "@mandujs/core/guard";

const report = await checkConsistency(rootDir);
if (report.violations.length > 0) {
  console.log("Decisions don't match implementation:");
  for (const v of report.violations) console.log(`  ${v.adrId}: ${v.reason}`);
}

Drift surfaces as Guard violations. Typical cases:

  • ADR says "no direct DB access from features layer" but a feature now imports @/server/db directly.
  • ADR says "session storage is Redis" but a new file uses in-memory session.

MCP access

From an agent session:

  • mandu.decision.list — show all ADRs
  • mandu.decision.save — record a new one
  • mandu.decision.check — run consistency check
  • mandu.decision.architecture — get the compact snapshot

Workflow

Agent needs to pick a tech:
  ↓
mandu.decision.list(tags=["database"])
  ↓
Found ADR-002 accepted ("Postgres + Drizzle") → use it
  ↓
(if NOT found)
  ↓
Propose via mandu.negotiate → save via mandu.decision.save

🤖 Agent Prompt

🤖 Agent Prompt — Decision Memory (ADR)
Apply the guidance from the Mandu docs page at https://mandujs.com/docs/architect/decision-memory to my project.

Summary of the page:
Mandu Decision Memory stores ADRs (Architecture Decision Records) per project. Agents use searchDecisions() to avoid re-relitigating, saveDecision() to record choices, and checkConsistency() to verify implementation matches intent.

Then:
1. Make the change in my codebase consistent with the page.
2. Run `bun run guard` and `bun run check` to verify nothing
   in src/ or app/ breaks Mandu's invariants.
3. Show me the diff and any guard violations.

For Agents

AI hint

Mandu Decision Memory stores ADRs (Architecture Decision Records) per project. Agents use searchDecisions() to avoid re-relitigating, saveDecision() to record choices, and checkConsistency() to verify implementation matches intent.

Guard scope
architecture