From 883ce5b4f3bd3271e209475abe489b2bd2f5184a Mon Sep 17 00:00:00 2001 From: Aaron Bockelie Date: Mon, 29 Jun 2026 02:14:42 -0500 Subject: [PATCH 1/2] ADR-141: knowledge graph as evidential memory backend Architecture proposal (Draft) for integrating an external evidential knowledge graph as an optional, presence-gated memory backend. - Activation contract: ontology presence is the combined capability + opt-in gate (zero-config); ways.json flag is a veto only. - Detection is fail-safe and never blocks the session (fire-and-forget). - Outbound: copy ledger entries + auto-memory writes to the ontology ingest target (refines ADR-112 Tier 2 with an activation contract). - Inbound (staged): project the KG into the native memory surface as read-only files; documents the three blockers (Auto-Dream, write redirect, populated-mountpoint overlay). - Generalizes to: artifact-presence-gated, evidentially-curated memory; the framework routes, the backend curates; backends are substitutable. Related: ADR-112 (session ledger), ADR-128 (memory-as-repo redirect). --- docs/architecture/INDEX.md | 1 + ...edge-graph-as-evidential-memory-backend.md | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md diff --git a/docs/architecture/INDEX.md b/docs/architecture/INDEX.md index 0fa9f99e..4c8a7f05 100644 --- a/docs/architecture/INDEX.md +++ b/docs/architecture/INDEX.md @@ -61,6 +61,7 @@ _Ways architecture, matching, macros, hooks, session lifecycle_ | [ADR-138](./system/ADR-138-skills-own-the-how-ways-own-the-5w.md) | Skills own the how, ways own the 5W | Draft | | [ADR-139](./system/ADR-139-shelve-maintainer-i18n-adopter-run-localization-via-ways-localize.md) | Shelve maintainer i18n; adopter-run localization via ways-localize | Accepted | | [ADR-140](./system/ADR-140-two-install-topologies-in-place-repo-and-subdirectory-projection.md) | Two install topologies: in-place repo and subdirectory projection | Accepted | +| [ADR-141](./system/ADR-141-knowledge-graph-as-evidential-memory-backend.md) | Knowledge Graph as Evidential Memory Backend | Draft | ## Documentation _Documentation structure, tooling, coherence_ diff --git a/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md b/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md new file mode 100644 index 00000000..8cbba274 --- /dev/null +++ b/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md @@ -0,0 +1,106 @@ +--- +status: Draft +date: 2026-06-29 +deciders: + - aaronsb + - claude +related: + - ADR-112 + - ADR-128 +--- + +# ADR-141: Knowledge Graph as Evidential Memory Backend + +## Context + +Cross-session knowledge has two homes in this framework, and both are *editorial* — they keep a single current view and discard what they supersede: + +- **Native auto-memory** (ADR-128): `MEMORY.md` + topic files, loaded at session start. Its compaction cycle ("Auto-Dream") performs minimal consistent revision — when session 12 contradicts session 3, it picks one and rewrites. The *fact that understanding shifted* is destroyed. It also exposes **no programmatic integration hooks** — no `memoryWrite` intercept, no API, only the `/memory` toggle. +- **The session ledger** (ADR-112) preserves raw prose, but is a flat append-only stream. It records *what was said*, not the relationships between assertions across sessions. + +ADR-112 already anticipated a third tier: ingesting ledger entries into an external **evidential** knowledge graph (KG) — one that, per Dempster–Shafer rather than AGM, keeps contradictory assertions and *scores the balance of evidence* (AFFIRMATIVE / CONTESTED / CONTRADICTORY / INSUFFICIENT_DATA). That tier was sketched as a one-line file copy guarded by `if -d`, but left two things unspecified: + +1. **Activation and detection** — how a session decides, safely and without configuration ceremony, that a valid KG is present *and* that this project has opted in. +2. **The return path** — ADR-112 only described writing *into* the KG. It did not address consuming the KG's evidential view *back* into the session, where the contradiction-preserving signal would actually change reasoning. + +The motivating force is general: an agent operating under a shrinking context window needs a durable, *non-editorial* memory whose value compounds across sessions, and it must integrate without fighting a host memory system that offers no hooks. This ADR records how the framework attaches to such a backend. + +## Decision + +Integrate an external evidential knowledge graph as an **optional, presence-gated** memory backend, in two independently activatable directions. The framework owns *detection and activation*; the KG owns *curation*. The reference backend is a `kg`-compatible system exposing per-ontology ingestion (e.g. a FUSE mount at `${KG_KNOWLEDGE_ROOT:-$HOME/Knowledge}/ontology//ingest`, or an equivalent `POST /ingest` API). + +### 1. The activation contract: presence *is* opt-in + +A project's KG ontology is named after its slug. The **existence of that ontology** answers two questions at once: + +| Question | Established by | +|---|---| +| Is a valid KG reachable? | The ontology's ingest endpoint resolves — the backend had to answer for the ontology to exist | +| Has *this project* opted in? | The resolved ontology is named for *this* project | + +Opt-in therefore requires no separate config in the happy path: if the ontology is absent, the integration is inert at zero cost. A single `ways.json` flag exists only as an explicit veto. + +**Three states**, evaluated as `not-vetoed ∧ ontology-present`: + +- `inactive` — ontology absent → integration silently does nothing (default). +- `active` — ontology present → session knowledge flows. +- `hard-off` — `reflection.kg = false` → never flows, even if the ontology exists (per-machine / per-session veto). + +**Activation is the act of creating the ontology.** A helper exposes `activate` (create the ontology), `status` (report the state for this project), and `deactivate` (set the veto flag; never deletes data). + +### 2. Detection is fail-safe and never blocks the session + +Detection resolves the project ingest target or reports absence. It must: + +- treat an unreachable or orphaned backend as *absent*, not as an error (a dead mount stats false → `inactive`); +- never block — any copy to the backend is backgrounded and fire-and-forget, consistent with the Stop hook running `async` (ADR-112). A wedged backend must not stall a turn. + +The same contract has two transports: a live ingest directory (file copy) where a mount is present, or `GET /health` + ontology-exists + `POST /ingest` for headless/CI hosts with no mount. + +### 3. Outbound — session knowledge to the KG + +When `active`, the framework copies its existing durable artifacts to the ontology's ingest target: ledger entries (ADR-112) and auto-memory writes (ADR-128). These are already curated prose with frontmatter; no new artifact is produced. The KG deduplicates across channels. This is fire-and-forget: the source artifact exists regardless of whether ingestion succeeds. + +### 4. Inbound — the KG as a read-only memory projection (staged) + +Because native memory exposes no hooks, the only integration surface for the *return path* is the memory files themselves (ADR-128's "observe and rewrite" constraint). The framework therefore consumes the KG by **projecting it into the native memory surface as read-only files**: a generated `MEMORY.md` index of the highest-value concepts (ranked by grounding × connectivity, scoped to the project ontology, within the 25 KB session-start window) plus concept topic files served on demand. Claude reads KG concepts through the same slot it already reads memory — including `CONTESTED`/`CONTRADICTORY` entries that editorial curation would have erased. + +This direction is **staged behind the outbound bridge** because it carries three constraints that must be resolved in the implementation ADRs/PRs, not assumed away: + +- **The projection is read-only, and the editorial layer must be disabled.** Auto-Dream rewrites and prunes memory files on its own schedule and cannot be hooked; a projected surface must present as read-only and run with Auto-Dream toggled off, otherwise the curation this integration exists to escape runs against the projection. +- **Writes redirect to ingestion, not to the memory path.** With the read surface read-only, the framework's "save a memory" path must target the KG ingest channel (direction 3), closing the loop: reads come from the projection, writes go to ingestion. +- **Mounting over a populated, host-owned directory is unsolved by a pure API-backed filesystem.** Presenting the projection at the memory path requires either relocating genuine user-level memory into the KG (takeover) or union/overlay support in the backend filesystem. This is an implementation decision deferred to the inbound PR. + +### 5. The generalized principle + +Cross-session memory should be **artifact-presence-gated and evidentially curated**: the framework detects and gates an external backend by the presence of the project's own artifact (not by configuration), pushes its existing durable artifacts to it fire-and-forget, and — where the host permits — consumes the backend's evidential view back through whatever surface the host already reads. The framework never becomes the curator; it routes. Any backend satisfying the ingest/projection contract is substitutable. + +## Consequences + +### Positive + +- Sessions gain a memory whose value compounds — contradictions are preserved and scored rather than overwritten, and minor signals survive as connected low-weight nodes instead of being pruned. +- Zero-ceremony opt-in: creating the ontology activates the project; its absence is a silent, costless no-op. +- No coupling to a specific backend — the ingest/projection contract is the interface; the reference KG is replaceable. +- Outbound ships independently of inbound; each direction is separately activatable, consistent with ADR-112's tiered model. +- Works without fighting the host: outbound copies existing artifacts; inbound uses the only surface native memory exposes. + +### Negative + +- Inbound depends on disabling Auto-Dream and on resolving the populated-mountpoint problem — non-trivial, hence staged. +- Detection correctness hinges on fail-safe behavior against orphaned/wedged backends; a naive `-d` check without liveness/timeout discipline could stall a turn (a portable timeout is itself a follow-up, as stock macOS lacks `timeout`). +- A ranked projection within the 25 KB window means the session sees a *curated slice* of the graph, not all of it; ranking quality becomes load-bearing. + +### Neutral + +- This refines ADR-112's Tier 2 (gives it an activation contract and a return path) and consumes ADR-128's "redirect, don't suppress" model (the projection *is* the redirect, taken to its conclusion). +- The ledger remains the source of truth and the replay seed; the KG is a derived, regenerable view. +- Implementation spans two repos (the framework: detection, activation, hooks, write-redirect; the backend: memory-view formatter, ranked projection query, read-only/overlay mount mode) and will land as separate referencing PRs. + +## Alternatives Considered + +- **Query the KG via MCP at state transitions instead of projecting into memory.** Rejected as the *primary* return path: it requires the session to issue queries and the host to surface results, whereas the memory slot is read unconditionally at session start. MCP query remains a viable complementary retrieval mode and is not precluded. +- **Disable native memory entirely.** Rejected for the same reasons as ADR-128 — it fights the harness, breaks on updates, and removes legitimate cross-project memory. The projection coexists with the feature instead of replacing it. +- **Configuration-flag opt-in (enable per project in `ways.json`).** Rejected as the primary mechanism: it duplicates state that the ontology's existence already encodes and invites drift (flag on, ontology absent). The flag is retained only as a veto. +- **Push via a CLI/MCP call rather than a file copy.** Rejected for outbound: a guarded file copy is fire-and-forget, has no failure surface that can block a turn, and needs no tool call. The API transport is the documented fallback for hosts without a mount. +- **Full takeover vs. overlay for the inbound mount.** Deferred, not decided here — both satisfy the contract; the choice belongs to the inbound implementation ADR. From 5c240fbbc3a237922e439e22106b8137ef75bc0b Mon Sep 17 00:00:00 2001 From: Aaron Bockelie Date: Tue, 30 Jun 2026 07:01:54 -0500 Subject: [PATCH 2/2] docs(adr-141): accept KG evidential memory backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed; outbound ingest path empirically validated via the live kg-fuse demo. Inbound projection remains staged behind its three documented blockers (Auto-Dream disable, write-redirect, populated- mountpoint overlay) — accepting the decision, not the unbuilt path. --- docs/architecture/INDEX.md | 2 +- .../ADR-141-knowledge-graph-as-evidential-memory-backend.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/architecture/INDEX.md b/docs/architecture/INDEX.md index 4c8a7f05..54cd1a20 100644 --- a/docs/architecture/INDEX.md +++ b/docs/architecture/INDEX.md @@ -61,7 +61,7 @@ _Ways architecture, matching, macros, hooks, session lifecycle_ | [ADR-138](./system/ADR-138-skills-own-the-how-ways-own-the-5w.md) | Skills own the how, ways own the 5W | Draft | | [ADR-139](./system/ADR-139-shelve-maintainer-i18n-adopter-run-localization-via-ways-localize.md) | Shelve maintainer i18n; adopter-run localization via ways-localize | Accepted | | [ADR-140](./system/ADR-140-two-install-topologies-in-place-repo-and-subdirectory-projection.md) | Two install topologies: in-place repo and subdirectory projection | Accepted | -| [ADR-141](./system/ADR-141-knowledge-graph-as-evidential-memory-backend.md) | Knowledge Graph as Evidential Memory Backend | Draft | +| [ADR-141](./system/ADR-141-knowledge-graph-as-evidential-memory-backend.md) | Knowledge Graph as Evidential Memory Backend | Accepted | ## Documentation _Documentation structure, tooling, coherence_ diff --git a/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md b/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md index 8cbba274..e8ea89e7 100644 --- a/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md +++ b/docs/architecture/system/ADR-141-knowledge-graph-as-evidential-memory-backend.md @@ -1,5 +1,5 @@ --- -status: Draft +status: Accepted date: 2026-06-29 deciders: - aaronsb