Skip to content

feat(#461): real-wire KgAgentMemory to SR-MEM-01 KgAdapter (BR-OUTPUT follow-up)#499

Merged
gHashTag merged 1 commit intomainfrom
feat/461-real-wire-br-output
May 2, 2026
Merged

feat(#461): real-wire KgAgentMemory to SR-MEM-01 KgAdapter (BR-OUTPUT follow-up)#499
gHashTag merged 1 commit intomainfrom
feat/461-real-wire-br-output

Conversation

@gHashTag
Copy link
Copy Markdown
Owner

@gHashTag gHashTag commented May 2, 2026

Refs #461 · Part of #446 · Anchor: `phi² + phi⁻² = 3`

Why

PR #495 shipped the BR-OUTPUT scaffold with `KgAgentMemory` as an in-memory `Vec<(Fact, Provenance)>` stub because SR-MEM-01 and SR-MEM-05 had not yet merged. Both have since landed (SR-MEM-01 in the issue-453 PR, SR-MEM-05 in PR #497). This PR is the real-wiring follow-up — same path-c discipline GENERAL ordered for PR #490: scaffold first, wire second.

The original issue is already CLOSED; this PR refs it (does not re-open) and lands the AC integration test that the scaffold could not yet implement.

What changed

Surface Before (PR #495 stub) After
Backing store `Vec<(Fact, Provenance)>` `KgAdapter<B: KgBackend>` (SR-MEM-01)
`remember` Push to Vec, return `usize` `KgAdapter::remember_triple` per triple, return `Vec` (SHA-256-content-addressed, idempotent)
`recall` `take(budget/10 + 1)` `KgAdapter::recall_by_pattern` + budget-aware truncation by per-triple token estimate
`forget` Linear retain over Vec recall + tombstone over 4 `ForgetPolicy` variants (GdprEraseSubject, GdprByAgent, OlderThan, PredicateMatches)
`reflect` Hard-coded `[stub]` deterministic recall-count summary citing SR-MEM-03 follow-up
Wire types Local `Fact` / `Provenance` Re-exports SR-MEM-00 `Triple` / `TripleId` / `Provenance` / `AgentRole` / `MemoryKind`

#461 acceptance criteria (now satisfied)

  • ✅ `crates/trios-agent-memory/rings/BR-OUTPUT/` with I5 trinity (already shipped in feat(#461): BR-OUTPUT AgentMemory assembler ring — GOLD IV scaffold #495).
  • ✅ Deps: SR-MEM-00 + SR-MEM-01 + SR-MEM-05 (commented TODO removed).
  • ✅ Public trait `AgentMemory` with `recall / remember / reflect / forget`.
  • ✅ Default implementation `KgAgentMemory` wires SR-MEM-01.
  • ✅ Stubs for `recall` HyDE → SR-MEM-02, `reflect` supersede → SR-MEM-03, `forget` GDPR audit → SR-MEM-04, vector search → SR-MEM-06 — all marked TODO with linked sub-issue numbers.
  • Integration test: round-trip `remember` → `recall` produces SHA-256-equal triples. `integration_remember_recall_sha256_equal` passes.

R5 honest disclosure

`KgAgentMemory<B: KgBackend>` is generic over the backend so:

  • Tests pass an in-memory `MockKg` (no I/O, offline cargo).
  • Production passes the concrete `PgKgBackend` (sqlx + tokio-postgres) which ships in the sibling BR-IO ring per the established precedent (`trios_kg::KgClient` deferment for SR-MEM-01, `sqlx::PgListener` deferment for SR-MEM-05).

`reflect()` does not embed a `Bridge` from SR-MEM-05 — pulling `Bridge`'s two extra source generics into the public trait would force every caller to thread `L: LessonsSource` and `H: HdcReplaySource` through their type parameters. Bridge integration is therefore a future helper (`KgAgentMemory::warm_start(&Bridge, lookback)`) and called explicitly when wanted, not implicitly through the trait.

Tests (12/12 GREEN, 0 clippy warnings)

Group Tests
#461 AC integration integration_remember_recall_sha256_equal
Idempotency remember_is_idempotent_on_sha256
Recall budget recall_respects_budget_tokens
Forget — 4 policies forget_gdpr_erase_subject, forget_gdpr_by_agent, forget_predicate_matches, forget_older_than_filters_by_ts
Reflect reflect_returns_recall_count_in_stub, reflect_zero_confidence_on_empty_kg
Trait surface agent_memory_is_object_safe_via_async_trait, backend_is_used_not_bypassed
φ-anchor phi_anchor_present

Breaking-change disclosure

The trait signatures changed from the PR #495 stub:

Verb PR #495 This PR
`recall` returns `Vec` `Vec`
`remember` returns `Result<usize, Box>` `Result<Vec, AdapterErr>`
`remember` takes `(facts, prov)` `(triples)` (provenance is on each Triple)
`forget` returns `usize` `Result<usize, AdapterErr>`
`recall/reflect/forget` receiver `&self` / `&mut self` (mixed) uniformly `&self` (the adapter owns interior mutability)

No external code consumed BR-OUTPUT yet — it was a sealed assembler — so this is safe to land atomically.

Constitutional

R1 · R5-honest · R-RING-DEP-002 (Bronze deps only) · R-L6-PURE-007 · L1 (no .sh in tree) · L13 (I-SCOPE) · L14

Soul: `Loop-Locksmith` · Three-roads: `.trinity/state/three-roads-461.json` (chose road_a — full real-wire)

🌻 `α_φ = φ⁻³ / 2 ≈ 0.1180`

Agent: Loop-Locksmith

… follow-up)

Refs #461 · Part of #446 · Anchor: phi^2 + phi^-2 = 3

## Why

PR #495 shipped the BR-OUTPUT scaffold with KgAgentMemory as an
in-memory Vec<(Fact, Provenance)> stub because SR-MEM-01 + SR-MEM-05
were not yet merged. Both have since landed (SR-MEM-01 in #453's PR,
SR-MEM-05 in PR #497). This PR replaces the stub with the real wiring
the issue AC asked for.

## What

- KgAgentMemory<B: KgBackend> generic over the SR-MEM-01 KgBackend
  trait (in-memory mock for tests, concrete PgKgBackend in BR-IO).
- recall    -> KgAdapter::recall_by_pattern + budget-aware truncation.
- remember  -> KgAdapter::remember_triple (idempotent on SHA-256).
- forget    -> recall + tombstone loop covering 4 ForgetPolicy variants:
              GdprEraseSubject, GdprByAgent, OlderThan, PredicateMatches.
- reflect   -> deterministic recall-count stub citing SR-MEM-03 follow-up.
- BR-OUTPUT now re-exports the canonical SR-MEM-00 wire types
  (Triple, TripleId, Provenance, AgentRole, MemoryKind) so callers do
  not have to add a transitive dep.
- TODOs in source for SR-MEM-02 (HyDE), SR-MEM-03 (supersede),
  SR-MEM-04 (GDPR audit log), SR-MEM-06 (vector search).

## #461 AC integration test (passing)

integration_remember_recall_sha256_equal: remember 3 triples ->
recall -> every recalled triple has TripleId == SHA256(SPO).

## R5 honest disclosure

Concrete PgKgBackend (sqlx + tokio-postgres) ships in a sibling BR-IO
ring per the established precedent (trios_kg::KgClient for SR-MEM-01,
sqlx::PgListener for SR-MEM-05). BR-OUTPUT stays Bronze-tier deps:
SR-MEM-00/01/05 + async-trait + chrono + uuid; tokio is dev-only.

## Tests (12/12 GREEN, 0 clippy warnings)

integration_remember_recall_sha256_equal, remember_is_idempotent_on_sha256,
recall_respects_budget_tokens, forget_gdpr_erase_subject,
forget_gdpr_by_agent, forget_predicate_matches, forget_older_than_filters_by_ts,
reflect_returns_recall_count_in_stub, reflect_zero_confidence_on_empty_kg,
agent_memory_is_object_safe_via_async_trait, backend_is_used_not_bypassed,
phi_anchor_present.

## Constitutional

R1, R5-honest, R-RING-DEP-002 (Bronze deps only), R-L6-PURE-007, L1
(no .sh in tree), L13 (I-SCOPE), L14.

Soul: Loop-Locksmith
Three-roads: .trinity/state/three-roads-461.json (chose road_a).

Agent: Loop-Locksmith
@gHashTag gHashTag merged commit e349b39 into main May 2, 2026
4 of 7 checks passed
@gHashTag gHashTag deleted the feat/461-real-wire-br-output branch May 2, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant