Docs / Architecture

Plugin constraints

DD is a plugin for coding-agent harnesses — Claude Code, Codex, Grok, opencode — not a service.

This is the governing constraint of the project. A design that needs a server, a database engine, a model runtime or a background worker is not a smaller version of DD: it is a different product.

Every proposal is measured against the seven limits below before its merits are discussed. A proposal that fails one of them is rejected on that basis alone. v2 rewrote several of them (no resident process, no model, no dependency); each is stated here as the code holds it today.

The seven limits

L1 — Hooks are ephemeral processes

Every hook is a new Node process, and PreToolUse runs on every tool call. Its cost is dominated by Node’s start-up, so the hot path (hooks/run.cjs, src/hooks/v2/*.cjs, src/engine/*.cjs) is CommonJS and loads lazily: a project without a compiled index loads no matching code, and a tool call where nothing fires loads only the matcher. Measure a ranking or matching change on that path, not in a microbenchmark.

L2 — No resident process

DD runs inside the hook process, in a maintenance process session start detaches at most once a day, and in the review UI a person starts with deltadictum ui. None of them is required for delivery; nothing waits for any of them.

L3 — No runtime dependency

DD needs Node.js 22.16 or later and nothing else. node:sqlite with FTS5 holds local telemetry and the similarity index, off the hot path. There is no embedding model and no vector store: memories fire by rule matching over the compiled index.

L4 — The hook contract differs per harness

Claude Code, Codex, OpenCode and Grok Build send different payloads and accept different answers. An adapter translates a harness’s events and output format into DD’s events (src/hooks/v2/events.cjs, src/hooks/v2/codex.cjs, adapters/opencode/); the matcher, ledger, checks and capture are shared. A capability one harness lacks (OpenCode has no hook that adds context before a tool runs, nor a Stop hook) is not emulated.

L5 — Failures must not block the host

A hook that fails for any reason, including a module that does not load, ends with exit 0 and no output.

L6 — Single-developer data volumes

DD sees one developer’s sessions: a handful a day, session files kept seven days, counters rolled up after that. No policy is learned online. Thresholds are counted rules (a memory unused in 20 sessions that touched its paths is retired), not statistics.

L7 — Local-first, nothing leaves the machine

Memories are files in the project’s git repository; everything derived lives in .dd/local/, git-ignored. DD makes no network request, and the review UI listens on a loopback port only.

What this rules out

  • PostgreSQL, Qdrant, any external database or vector store.
  • An inference server, a GPU requirement, a hosted or remote model.
  • Federation, multi-tenancy, RBAC, organisation-level vaults.
  • A process every project must keep running.
  • Importance scores or rankings learned online from user traffic.

Relation to the rest of the documentation

DD.md states the current behavioural contract. invariants.md lists the properties that must never break. This document states the boundary all of them operate inside.

Edit this page on GitHub