Skip to main content

ADR-0021: Dual-Rail .stet — Composable, Governable Memory Graphs (KBs)

Status

Proposed / exploring. Prompted by the memory-posture discussion (2026-07-08). Extends ADR-0013 (the git/Dolt split), ADR-0015 (the .stet topology), and ADR-0017 (composable, importable, signed configs), and realizes the "the repo is the graph" claim of ADR-0019 on a queryable rail. Revisit for promotion to accepted (+ a spec) alongside the memory ADRs, after the core loop (SPEC-0001..0003) is standing.

Context and Problem Statement

ADR-0019 claims Stet's differentiator is compounding project memory because a git repo already is a versioned knowledge graph. That is true for artifacts (git-grep, diffs, PR review), but the graph over them — provenance edges (this skill ← these trajectories), outcomes (merged/reverted), votes (ADR-0014), staleness — is relational, concurrently updated, and something you want to query ("what does this project know about error handling?", "which skills are stale?", "trace this convention to its origin"). git is the wrong rail for that; Dolt (git-for-data: versioned SQL, cell-wise branch/merge/diff, embeddable, syncable as a remote — already adopted in ADR-0013) is the right one.

The question that opened this ADR: should a .stet also be a Dolt repo, so the knowledge graph rides that rail? Pursuing it surfaced two properties that make it worth more than a storage note:

  1. 1:N, not 1:1. A .stet repo/folder should reference/compose many knowledge bases (KBs), not own exactly one. Memory federates.
  2. Distribution + governance. If KBs are named, composable resources resolved across the .stet topology (ADR-0015), then a language/framework/community can publish a .stet whose KB is distilled across community trajectories, and a higher tier can govern which KB sources are allowed — the dotfiles pattern pushed to ecosystem scale, with an org-enforceable trust boundary.

Framing — two rails, one topology

Do not turn .stet git repos into Dolt repos. Keep the ADR-0013 line intact — trajectories & skills stay in git, never Dolt — and make the topology dual-rail:

RailHoldsWhy this rail
git (.stet repo/dir)reviewable artifacts: trajectories (ADR-0011), skills (ADR-0012), verbs, agent YAML (ADR-0015/0016)line-diffable, PR-ceremony-gated, human-readable, harness-portable
Dolt (KB)the queryable memory graph: provenance edges, outcomes, votes (ADR-0014), staleness, the distillation warehouserelational, cell-wise mergeable, SQL-queryable, syncable

git is the source of truth for anything reviewed as a file; a KB is a materialized, rebuildable projection over those artifacts plus the genuinely relational data that has no git form (votes, thread state, outcomes — already Dolt's job in ADR-0013). The .stet unit binds the two.

Sketch / Decisions

Dual-rail binding (git source of truth, Dolt graph)

Each .stet tier (ADR-0015) pairs its git repo/dir with zero or more KBs. The KB is derivable from the git artifacts (provenance travels in trajectory/skill metadata), so it is an index, not a second master for artifacts. Two invariants hold:

  • git stays authoritative for reviewable artifacts; the KB never becomes a side-door around file review.
  • The graduation invariant (ADR-0019/0020) is untouched. Durable artifacts land via PR into git; the KB updates as a projection of that merge (or from votes). Nothing an agent durably knows arrives through the Dolt rail unreviewed.

KBs are the fourth primitive — composable, 1:N

Decided (2026-07-08): a KB is a first-class primitive, managed exactly like Agents and Verbs (ADR-0015) — you curate a KB library the same way you manage those. The reviewable git-side binding (source/address, ref pin, signer policy) is the primitive; its payload is the Dolt memory graph. A .stet declares a set of KB bindings it composes, resolved across the topology like the other primitives (ADR-0015). Memory federates: your repo KB + your org KB + an imported language KB + a team KB, resolved with a precedence order. A KB is addressed as an importable resource (à la ADR-0017), pinned to a ref via a lockfile. Because Dolt syncs as a remote and merges cell-wise, a consumed community KB can even be forked and contributed back — the collective flywheel (ADR-0014) at ecosystem scale.

Distribution — the dotfiles pattern, extended

Because KBs are named and importable, an ecosystem project can ship a .stet whose KB is distilled across community trajectories — e.g. a language/framework publishes org/.stet carrying memory the whole community's dispatches produced. Downstream projects import it (ADR-0017) and inherit a warm, queryable memory graph on day one instead of starting cold. This generalizes ADR-0015's .github-style dotfiles convention from config to distributed, versioned memory.

Governance — override, forbid, pin, sign

KB composition rides ADR-0015's resolution and ADR-0017's trust model, so governance is native, not bolted on:

  • Precedence is a setting (soft): which KB wins when sources overlap.
  • Hard pins (ADR-0015): a higher tier can pin a KB source non-overridable — auditable provenance of what an org mandated.
  • Allow/deny sources: a tier can forbid specific KB sources (or restrict to an allowlist) — "this org's agents may not read community KB X."
  • Signed provenance (ADR-0017): a policy can require an imported KB's pinned ref be GPG-signed by an allowed signer — git-native, org-enforced, Stet-is-not-a-central-authority.

This is the property that makes distribution safe: importing memory is powerful, so the same downstream controls that gate imported config (ADR-0017) gate imported memory.

Privacy gate on the publish path

Decided (2026-07-08): a KB is projected from trajectories and can carry sensitive residue, so the ADR-0011 secret-scan + redaction gate runs at projection/publish time (when a KB is built or pushed for others to consume) — mandatory and blocking, exactly as for a committed trajectory. What a publishable KB may include is governed by a .stetignore (the same mechanism ADR-0011 uses for trajectory capture, extended to the graph): paths/entities/edges a project excludes from any KB meant to leave the repo. Local, private KBs are gated the same way at the moment they publish, not continuously.

Why it fits

  • Good, because it puts each kind of data on the rail it deserves without breaking the ADR-0013 line — artifacts stay reviewable-as-files, the graph becomes queryable.
  • Good, because 1:N + import/pin/sign makes memory composable and governable with the mechanics ADR-0015/0017 already define — no new trust primitive.
  • Good, because it turns the compounding-memory posture (ADR-0019) into something that scales past one repo: ecosystem-published KBs, federated queries, contribute-back.
  • Good, because the KB is a rebuildable projection, so it is never an un-auditable second source of truth for artifacts, and the graduation invariant still holds.

Open questions

  • Poisoned / adversarial KBs. An imported community KB can encode hostile or low-quality conventions distilled from adversarial trajectories. Bounded by allow/deny + signed-source + pin (above), but the residual — importing curated memory is importing intent — mirrors ADR-0017's residual and must be named as accepted, with efficacy/vote gating (ADR-0014) as a compensating control.
  • Identity & dedup across KBs. How a trajectory/skill referenced by multiple federated KBs is identified (content address? artifact SHA?) so provenance edges don't double-count or collide.
  • Query federation & precedence semantics. How a query spans N KBs with a precedence order, and the cost/latency of federating across local + remote Dolt DBs.
  • KB schema & versioning. The open, versioned KB schema and its migration story (Dolt schema changes as reviewable diffs), so KBs stay portable and not lock-in.
  • PII policy for publishable KBs. The secret-scan gate + .stetignore are decided (above); the remaining nuance is the default PII/entity policy for a KB intended to be published to others (opt-in vs. opt-out, per-entity granularity) beyond secrets.
  • Sync topology. Local-first vs. DoltLab vs. forge-mediated sync (ADR-0013) for multi-consumer KBs, and conflict/merge policy when many consumers contribute back.

Consequences (tentative)

  • Adds KB as a fourth first-class primitive (ADR-0015): a git-side KB binding (source/address + lockfile, import/pin/sign per ADR-0017) bound 1:N to each .stet tier over a Dolt memory-graph payload, a resolution/precedence pass (ADR-0015), and allow/deny governance controls — curated as a "KB library" like Agents/Verbs.
  • Adds a projection pipeline (git artifacts + votes → KB) with the ADR-0011 secret-scan/redaction gate and a .stetignore-governed exclusion on the publish path, and a rebuild-from-git guarantee.
  • Extends ADR-0013 (KBs are the concrete shape of its Dolt warehouse), ADR-0015 (memory joins the governed topology), and ADR-0017 (imports now include memory).
  • Introduces an accepted residual (imported memory = imported intent) tracked with ADR-0017's; efficacy/vote gating (ADR-0014) is the compensating control.

More Information

Prompted by the memory-posture discussion (2026-07-08). Realizes ADR-0019's "the repo is the graph" on the Dolt rail; the KB is where the outer loop (ADR-0012) warehouses and the inner loop (ADR-0020) graduates to, and what agentic voting (ADR-0014) feeds. Distribution + governance reuse ADR-0015 (topology, pins) and ADR-0017 (import, lockfile, allowed-signer trust). Shared theme: the project — and the ecosystem — learns over time.