Skip to content

fix: route reflection mapped rows through admission control and ground the distiller prompt#931

Open
gorkem2020 wants to merge 3 commits into
CortexReach:masterfrom
gorkem2020:fix/reflection-mapped-rows-admission
Open

fix: route reflection mapped rows through admission control and ground the distiller prompt#931
gorkem2020 wants to merge 3 commits into
CortexReach:masterfrom
gorkem2020:fix/reflection-mapped-rows-admission

Conversation

@gorkem2020

Copy link
Copy Markdown
Contributor

Problem

Reflection mapped rows bypass admission control entirely. On /reset, the distiller's markdown sections (User model deltas, Agent model deltas, Lessons and pitfalls, Decisions) are mapped to ordinary user-memory rows (preference, fact, decision) and written via bulkStore with no gate, while extraction candidates from the same conversation go through the full admission pipeline. Anything the distiller writes into those sections becomes durable user memory unconditionally, and generic semantic recall serves it back as fact.

Live demonstration: a roleplay session's fictional canon ("favorite drink is plasma coffee") passed through the reflection door into bare preference rows and was asserted back to the user as fact on the next session, while the extraction door correctly suppressed the identical content.

Fix

Two layers:

  1. Distiller prompt rule: content from in-fiction, roleplay, or test frames may be summarized in the Context or Open loops sections but must never be written into the sections that become durable rows.
  2. Admission routing: when admission control is enabled, each mapped row is evaluated by the same AdmissionController instance the extractor uses before storage (new reflection-mapped-admission module; the controller is exposed via an accessor on the extractor). Rejected rows are skipped with the reason logged; admitted rows persist the full admission audit in metadata with provenance: "memory-reflection-mapped". For scoring, mapped categories are resolved to the smart registers the type priors expect (model deltas as preferences, lessons as cases, decisions as events). Behavior is unchanged when admission control is disabled, and infrastructure errors fail open so a transient failure cannot suppress reflection persistence.

A known limitation is documented in code and in docs/notes/reflection-write-path-findings.md: with smart extraction disabled there is no controller instance to borrow, so that configuration keeps the legacy ungated write. The notes file also records adjacent findings for discussion (the caller-less mapped-rows reader, cross-writer double-store of durable decision bullets, and the memory_layer labeling asymmetry between subsystems).

Tests

8 cases: admitted and denied mapped-row paths, admission-disabled passthrough, error fail-open, and prompt-content assertions for the new distiller rule.

Verification on a live gateway

Deployed and exercised end-to-end: a reset over a session containing a genuine lesson produced a mapped fact row carrying a complete admission audit in its metadata (decision pass_to_dedup, score 0.685, five feature scores, compared-row ids, provenance tag), and a reset over a fiction-framed session produced empty durable sections with the fiction confined to Context.

The distiller's four mapped headings (User model deltas, Agent model
deltas, Lessons & pitfalls, Decisions) become ordinary durable memory
rows via bulkStore with no admission gate, no gating knob, and no audit
trail; reflectionStoreToLanceDB gates only the document writer. A
contaminated or hallucinated distillate line therefore landed directly
as a confirmed memory.

Gate each mapped row through the same AdmissionController instance the
smart extractor uses (new SmartExtractor accessors), scoring legacy
mapped categories under the smart registers admission priors are keyed
by: user/agent model deltas as preferences, lessons as cases, decisions
as events. Rejected rows are skipped with the audit reason logged;
admitted rows persist the audit (tagged provenance
memory-reflection-mapped) in their metadata when auditMetadata is on.
Behavior is unchanged when admission control is disabled, and the gate
fails open on infra errors so a transient store or LLM failure cannot
suppress reflection persistence.

Also add a grounding rule to the distiller prompt (in-fiction or
test-frame claims must never appear under the four mapped headings),
export buildReflectionPrompt for prompt-content tests, and mark the
caller-less mapped-rows reader in reflection-store with a comment. Wire
the new regression suite into the local npm test chain and the
core-regression CI group.
Dead reader, cross-writer double-store, memory_layer parity question,
and the auto-capture watermark pointer, kept as PR discussion material.
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