Repository navigation
fix(active-memory): keep recall errors out of prompt context - #120658
Conversation
|
Codex review: needs maintainer review before merge. Reviewed August 28, 2026, 12:01 PM ET / 16:01 UTC. ClawSweeper reviewWhat this changesThe PR prevents failed Active Memory recalls from contributing text to the main prompt, adds timeout/cleanup and Gateway regression coverage, and corrects existing operator guidance. Regression provenancePossible regression — probable (reviewed change; known regression link). No predecessor PR is attributed. Merge readinessKeep open: the branch has a coherent owner-boundary repair and no actionable introduced defect was found, but exact-head CI is still incomplete. Priority: P1 Review scores
Verification
How this fits togetherActive Memory runs an embedded recall before an interactive chat turn and conditionally injects grounded recall text into the main model prompt. The changed code carries terminal execution and cleanup facts from the recall owner to the final context-admission decision. flowchart LR
A[Interactive chat turn] --> B[Active Memory recall]
B --> C[Terminal outcome]
C --> D[Timeout and cleanup recovery]
D --> E[Context admission]
E --> F[Main model prompt]
D --> G[Session diagnostics]
Before merge
Agent review detailsSecurityNone. PR surfaceSource -13, Tests +537, Docs +1, Other +6. Total +531 across 12 files. View PR surface stats
Review metrics
Merge-risk options
Maintainer options:
Copy recommended automerge instructionTechnical reviewBest possible solution: Land this owner-level terminal-state propagation once exact-head CI completes green; retain the existing grounded partial-recovery path rather than adding a new fallback or configuration surface. Do we have a high-confidence way to reproduce the issue? Yes, source-reproducible: fetched current main concatenates error payload text before recall admission, while the PR’s owner and Gateway tests exercise the failed-terminal outcome. This read-only review did not execute the contributor branch. Is this the best way to solve the issue? Yes: recording terminal and cleanup state at the recall owner, then enforcing it in the shared admission builder, is more maintainable than filtering prompt text downstream. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 4601b0a61805. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (14 earlier review cycles; latest 8 shown)
|
|
I reproduced the commands behind all three failed jobs locally with Node 24.19.0. Each stalled before its test body in the shared stale-
None of the three reached the Active Memory code. The CI run on Could a maintainer please rerun the failed jobs for run 31272974286? Update: the failed workflow used a merge commit based on 82f6280, immediately before #120653 landed. That change fixes the E2E setup output and watchdog path, and the same three jobs passed on that PR and on main. I have now merged current main into this branch at ebcd320acd8e7f65215347aeac9a9d67d21adca6, so fresh PR CI can validate the current head. The earlier request to rerun run 31272974286 is no longer needed. Final update: exact-head CI run 31277429449 completed successfully. build-artifacts, checks-fast-bun-launcher, check-sqlite-session-flip-proof, checks-node-changed, and openclaw/ci-gate all passed. ClawSweeper reports no actionable findings and marks the proof sufficient. This PR is ready for maintainer review. |
ebcd320 to
0e21f9e
Compare
Merge current main and preserve the original recall repair while observing bounded existing Gateway status before behavioral assertions. Keep the original flow, deadlines, and assertions unchanged; actual recall integration proof is still required. Co-authored-by: soltonigiri <[email protected]>
Use the public interactive chat route, which supplies canonical turn tool authority, for the built Gateway recall regression. Preserve the real provider, memory, failed-status, prompt-isolation, and history assertions and their deadlines. Co-authored-by: soltonigiri <[email protected]>
Merge current main while retaining both built Gateway consumers, shared selector coverage, and strict complete-shard expectations. Preserve the Active Memory runtime repair and interactive recall fixture unchanged; exact-head hosted verification remains required. Co-authored-by: soltonigiri <[email protected]>
Integrate the canonical auth-refresh fixture repair and current runtime lifecycle while preserving the original recall-outcome repair and history. Declare the Gateway build scope and cover selective CLI build admission. Correct existing transcript-path and conversation-ID operator guidance. Co-authored-by: soltonigiri <[email protected]>
|
Merged via squash.
|
…w#120658) * fix(active-memory): exclude error payloads from recall context * fix(active-memory): prioritize failed recall status * test(active-memory): cover failed recall cleanup and gateway flow Co-authored-by: soltonigiri <[email protected]> * test(active-memory): diagnose cleanup rejection and gateway startup Co-authored-by: soltonigiri <[email protected]> * fix(active-memory): preserve recall failures through timeout cleanup Carry terminal and cleanup failure facts through the canonical partial-result owner so timeout recovery cannot inject earlier memory from failed recall. Preserve legitimate partial recovery, original cleanup errors and contributor payload filtering. Cover direct recovery and declare the real Gateway test's existing built-runtime prerequisite. Co-authored-by: soltonigiri <[email protected]> * fix(active-memory): finish cleanup and built Gateway verification Name the canonical cleanup operation without changing error propagation, align the strict CI prerequisite expectation, and run the real recall proof through an isolated exact-build Gateway process. Preserve all behavioral assertions and deadlines; hosted verification remains required. Co-authored-by: soltonigiri <[email protected]> * test(active-memory): exercise authorized chat recall Use the public interactive chat route, which supplies canonical turn tool authority, for the built Gateway recall regression. Preserve the real provider, memory, failed-status, prompt-isolation, and history assertions and their deadlines. Co-authored-by: soltonigiri <[email protected]> --------- Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: soltonigiri <[email protected]>
Related to #90082. This PR repairs failed-recall prompt contamination; broader issue closure remains separate.
Current repair and validation
Active Memory records terminal model status and cleanup failure at their owners, then preserves those facts through timeout recovery and rejection. Failed recall cannot become main-prompt context just because earlier grounded text survived. One private result carrier replaces duplicated fields; cleanup ordering, original errors, warnings, artifact lifetime, and legitimate partial recovery remain intact. Runtime production is net −13 lines. Thanks @soltonigiri; both original contributor commits and credit are preserved.
This refresh integrates the landed deterministic auth-refresh test repair and current main's deferred-lifecycle changes. It also aligns the existing Gateway runtime prerequisite with real CLI admission and covers selective exclusion without a copied fixture inventory. Two bounded help/documentation corrections describe already-shipped behavior: the plugin-owned transcript export path and the conversation-ID allowlist. No schema, storage, default, or authorization rules change.
Exact-head CI is green for
c126f577a4157fb07b3b7bc18e2a51061865f2cc, executing merge0e65bf44b3961fb3ca1b014ee0671204b3a5fa8fagainst main4601b0a61805d95e1d52ef9357fde8460b56449b. The fresh built-Gateway case passed in 16.5 seconds: realmemory_getcontent reached the synthetic HTTP provider, failed recall was recorded, exactly one main request stayed uncontaminated, and the final reply appeared inchat.history. This is not exhaustive clean-history or authenticated live-provider recovery proof.Current owner tests passed 426/426; the strict-plan/tooling suite passed 1,428 (2 skipped), prerequisite/tooling suite 1,467 (4 skipped), and isolated tooling 210 + 185, including real CLI build-admission/exclusion and SIGTERM checks. All required checks passed. Complete source review found no actionable findings. The latest ClawSweeper rank-up request—finish exact-head CI—is satisfied; native prepare/merge checks still apply.
The documented scope excludes generic/headless
agent-command; command/RPC participation is a separate product question. #90082 stays open: broader provider recovery, operator indicators, and optional policy requests are not claimed fixed.Original contributor report and historical diagnostic stages (superseded statuses)
The following preserves the earlier report and evidence chronology. Its old candidate, pending, and do-not-merge statements describe those historical stages, not additional current runs.
Related to #90082 (historical automatic-closure directive removed pending separate issue-scope verification).
What Problem This Solves
Fixes an issue where users with Active Memory enabled could have an embedded recall failure message added to the main session prompt when recall found usable memory but ended with an incomplete agent turn.
Why This Change Was Made
Active Memory now excludes embedded-agent payloads explicitly marked as errors before building recalled context, while preserving non-error payloads. Terminal error metadata takes precedence over retained text, so terminally failed runs are recorded as
failedand do not inject recalled context.Current main already contains the circuit-breaker default and schema changes described in the issue. This change addresses the remaining prompt-context contamination path.
User Impact
Recall failure messages no longer pollute the main session prompt. Failed recalls remain visible in Active Memory diagnostics as
failed.Evidence
Real gateway runtime with the bundled Active Memory and
memory-coreplugins, a local OpenAI-compatible mock provider, usablememory_getevidence, and an actual incomplete embedded turn:node scripts/run-vitest.mjs extensions/active-memory/index.test.ts -t "does not inject error payloads after usable harness memory evidence|does not inject retained text from a terminally failed recall"— 2 passednode scripts/run-vitest.mjs src/agents/embedded-agent-runner/run.terminal-timeout.test.ts— 5 passednode scripts/run-vitest.mjs extensions/active-memory— 394 passedgit diff --check— passed.agents/skills/autoreview/scripts/autoreview --mode local— no accepted or actionable findingsAI-assisted: Yes. I reviewed and understand the change and its validation results.
Maintainer diagnostic stage — do not merge yet
Refreshed the original two contributor commits onto current main (
871b18dff5039484e86c76d282699a8defcb1654), preserving @soltonigiri's authorship and the newer grounding and transcript-watcher behavior.This push is a diagnostic test stage, not merge-ready. It retains the three production expressions already proposed here and adds owner-boundary coverage plus a real token-authenticated Gateway flow using a local mock HTTP provider. The provider invokes the real memory tool, then exercises incomplete-turn recovery; the assertions inspect the main provider request, recorded recall outcome, and final chat history. Existing startup tracing is enabled to diagnose any setup failure.
The ordinary completion regression was previously reproduced against exact baseline
94b7d0898878a0deb1ccf0782d104c91525f0637: four intended failures and one successful control, without increasing the existing recall timeout. That historical result is not a claim of fresh-baseline or candidate success. Earlier Gateway attempts stalled during setup and do not count as bug reproduction.Four additional cases probe an unconfirmed sibling: a completed failed recall whose cleanup crosses the original deadline may lose terminal status when projected through the timeout path. They cover retained versus transient transcript artifacts and successful versus failed results, preserving a legitimate timeout-partial success control. These are controlled logical-time ordering tests using the existing cleanup seam and actual watchdog abort signal. No production change for that hypothesis has been made before observing its result.
The latest ClawSweeper rank-up request for current-main owner tests and Gateway proof is being addressed by this stage. Landing remains blocked until exact-head CI demonstrates the intended tests ran, any genuine failure is repaired at its owner, and the actual Gateway flow completes successfully. A setup timeout or dependency failure will be diagnosed as infrastructure/fixture evidence, not presented as regression RED.
Diagnostic head:
0e21f9e1d453c613e834b347a93c3aaca714a04e.Second maintainer diagnostic stage — still not merge-ready
The first refreshed diagnostic head (
0e21f9e1d453c613e834b347a93c3aaca714a04e) produced one genuine owner-boundary failure: when terminally failed recall completes but cleanup crosses the deadline, retained transcript text is still injected. The other three cleanup cases and all five ordinary-completion cases passed; the plugin lane finished with 421 passed, 1 failed. Exact CI job.This second diagnostic stage intentionally keeps production code unchanged. It adds two unexecuted cases for an adjacent supported path: exhausted cleanup retries throw from
finally, potentially replacing the computed terminal result. The cases hold the final cleanup attempt across the same deadline and verify the cleanup warning and retry exhaustion before asserting that no context was injected. Both the failed-execution row and the successful-execution control preserve the existing rule that exhausted cleanup must not return context. No timeout, retry policy, or production seam is changed.The actual Gateway job did select the fixture, but both attempts ended at the existing no-output watchdog without completing the behavior proof. Its server-start imports completed; the logs do not establish an import cycle. Later startup spans were hidden by Vitest's default silent logger. This stage enables the existing redacted console logger for that isolated fixture, keeps file logging disabled, and resets the logger afterward. The real Gateway, memory tool, mock HTTP provider, and original timeouts are unchanged. Gateway startup failure evidence.
The two observed test-only type/lint defects are corrected. The known production failure remains deliberately unfixed in this stage while the connected rejection cases are established. Landing still requires the complete owner repair, green exact-head CI, and successful actual Gateway startup, completion, and cleanup. Thanks @soltonigiri; the original contributor commits and credit remain preserved.
Second diagnostic head:
faee22f595be434347f537743b372e2e98aa7edb.Complete recall-outcome repair
The hosted diagnostic run at
faee22f595be434347f537743b372e2e98aa7edbconfirmed three failures: a terminally failed recall could recover an earlier summary when cleanup crossed the deadline, and exhausted cleanup could also recover that summary after either successful or failed model execution. Both cleanup-exhaustion cases reached all three existing attempts and recorded the cleanup warning before failing the context assertion. The other 421 tests passed. Diagnostic run.The candidate now carries the recorded terminal outcome through timeout recovery and records cleanup failure at the cleanup owner. One internal partial-result carrier replaces the duplicated error fields and projections. Model failure and cleanup failure remain distinct; original errors, warnings, retries, transcript retention, and legitimate partial recovery are preserved. The contributor's normal-completion fix remains intact. Additional direct-catch unit controls retain the successful partial-recovery case and cover both failure facts.
The real Gateway test also now declares its existing built-runtime prerequisite for focused files, directories, and both Gateway configurations. Previous attempts reached HTTP bind and system-CA setup but stalled during subsequent startup; they did not establish behavior proof. This uses the existing build-before-tests mechanism without changing the fixture's plugins, timeouts, or runtime behavior. The post-build Gateway flow still needs to pass.
Independent source review accepted the owner repair and prerequisite declaration. This publication is for exact-head hosted verification: it is not a claim that the repaired tests or Gateway flow have passed yet. Landing remains gated on those results and required CI. No storage, schema, configuration, or public API changes. Thanks to @soltonigiri for the original repair.
Candidate head:
568561a57f39631a74fdeb7a01ebb6daddb4f719.CI follow-up and remaining integration gap
The complete recall repair at
568561a57f39631a74fdeb7a01ebb6daddb4f719passed all 426 owner tests, including all three previously reproduced cleanup-contamination failures and the legitimate partial-result controls. The prerequisite-selection suite also passed (1,795 tests across 67 files).This follow-up names the existing local cleanup operation so its original error propagation no longer violates
no-unsafe-finally; cleanup order, retries, warnings, and same-error propagation are unchanged. It also updates the strict Gateway-shard expectation for the declared runtime build prerequisite. The Gateway proof now uses the existing isolated built-CLI process helper, with exact checkout/build-stamp identity checks, direct public WebSocket client, and unchanged behavior assertions. Independent source review accepted these changes; fresh hosted verification of this new head is still required. The full product-runtime diff remains net −13 lines; prerequisite test tooling is separately net +7.This PR is not ready to merge. In run 33160846020, the in-process source Gateway test still stalled after HTTP bind/system-CA startup despite a successful runtime build; both attempts ended with exit143 before provider behavior was observed. That is an integration/startup gap, not evidence that the recall behavior passed or a proven diagnosis of this fixture's exact stalled module. The replacement built-process proof has not run yet. Its provider flow, plugin selection, timeout, failed-status check, and prompt/history assertions are unchanged. The original contributor commits and @soltonigiri's credit remain preserved.
Follow-up candidate head:
b25b0513dd14696a81f1eaeb6b3389eed172d989. Structured source review: no actionable P0–P2 findings; exact-head hosted verification remains pending.Gateway recall-path diagnosis
The follow-up at
b25b0513dd14696a81f1eaeb6b3389eed172d989passed all 426 Active Memory owner tests, including the named cleanup operation and previously reproduced failures. Its strict CI-plan suite passed 1,601 tests (two unrelated skips), and prerequisite routing passed with the 1,808-test tooling suite.The built-process Gateway now passes the exact-build identity checks, starts, accepts the public agent request and completes the main turn. However, the 15.5-second scenario observed zero recall requests and no memory-tool result, so its original assertion correctly failed. This is progress in the integration harness, not proof of the failed-recall behavior. Exact Gateway job.
This diagnostic follow-up preserves the same flow, plugins, deadlines and assertions. It moves the existing read-only status inspection before the first behavior assertion and reports only bounded status/configuration facts when the test fails. It does not print configuration, credentials, provider payloads or raw child logs. The redundant default type argument reported by lint is removed without changing its inferred type. Production recall handling is unchanged. Landing remains blocked until the actual recall flow and required exact-head CI pass.
The branch also incorporates
c07b753819ebb140db95fdb090bec99b3fb5cc43, including the existing main-branch lint repair. Independent source review and the complete P2 review found no actionable findings in this integrated candidate. Those source reviews authorize diagnostic publication, not landing or a claim that the recall integration now passes.Diagnostic candidate head:
0448105a8bf461681d1c713d0e0c04112ab3580e. Hosted verification of this exact head is pending.Interactive recall proof-route correction
The diagnostic at
0448105a8bf461681d1c713d0e0c04112ab3580econfirmed that the isolated configuration enabled Active Memory, the session existed and was not model-locked, but no recall status or recall request was produced. The Gateway scenario still failed its original memory-tool assertion. The owner suite passed all 426 tests; the strict CI-plan and prerequisite suites also passed. Exact Gateway diagnostic.Source inspection explains this fixture mismatch: the command-backed
agentRPC does not provide the turn-tool fingerprint required by authorized prompt enrichment. The host therefore correctly skips that phase, including Active Memory, before the plugin can record a status. The test now uses the existing interactivechat.sendroute, whose normal reply owner supplies that fact, then waits on the returned run ID through the sameagent.waitcontract. It retains the real HTTP provider, memory tool, failed-status and uncontaminated-main-prompt assertions, final history check, deadlines, configuration, and cleanup. Independent review accepted this source correction; actual hosted proof of the new route is still required.Named follow-up: command/RPC participation in authorized prompt enrichment. This PR does not add that participation, fabricate a fingerprint, or weaken the fail-closed tool-authority boundary. Its integration proof covers the normal interactive chat route. The earlier zero-recall runs are not evidence that failed recall handling worked through
agentRPC. Landing remains blocked until the real recall scenario and required exact-head CI pass.Interactive-route candidate head:
60de2460c449cfff3cc03cd11672ecd9d86b05c5. The complete nine-path candidate passed independent source review and a fresh P2 review with no actionable findings. Hosted verification of this exact head is pending.Current-main integration refresh
The interactive-route candidate
60de2460c449cfff3cc03cd11672ecd9d86b05c5could not start pull-request CI because another landed Gateway repair touched the same test-prerequisite table. This refresh incorporatesccbbaf2e2e57f53b3a2b086b3490d21fe40a7c9d, retains both built-Gateway consumers, shares their common selector coverage, and preserves strict complete-shard assertions with an explicit runtime prerequisite for either consumer. The Active Memory runtime repair, regression cases, and interactive-chat fixture are unchanged.The current chat admission path was checked against the newly landed main changes; this ordinary chat fixture does not request a Goal operation. This is integration/source evidence, not a successful recall run. The previously recorded command/RPC-authority follow-up remains outside this repair. Landing still requires the actual interactive recall scenario and all required exact-head checks to pass.
Integrated candidate head:
5029a5956ebf0213d239b6d531096b58debf62fb. Independent review and a fresh complete nine-path P2 review found no actionable findings. Hosted verification of this exact head is pending.Prior 5029 validation checkpoint
Current repair and validation
Active Memory now keeps failed recall output out of the main prompt, including when cleanup crosses the deadline or exhausts its retries. The recall producer records terminal model status and cleanup failure separately, then carries those facts through the existing timeout and rejection paths. One private result carrier replaces duplicated error fields; cleanup ordering, warnings, original errors, transcript retention, and legitimate partial recovery are preserved. The product-runtime change is net −13 lines, with tests and build-prerequisite metadata counted separately. Thanks @soltonigiri; the original contributor commits and credit are preserved.
The exact candidate
5029a5956ebf0213d239b6d531096b58debf62fbnow has observed built-Gateway proof. The interactive chat scenario passed in 11.8 seconds using the real bundled plugins and memory tool with a synthetic HTTP provider. It verified usable memory content, a recorded failed recall, one uncontaminated main request, and the final reply present inchat.history. The fixture checks exact checkout/build identity before starting the isolated built CLI. This is not authenticated live-provider proof or an exhaustive clean-history check.The same run passed 426 owner tests, 1,966 prerequisite/tooling tests, and 1,684 strict-plan/tooling tests (three skips). Independent source review and complete P2 review found no actionable findings.
Not merge-ready yet: required CI is red on a separate auth-refresh generation test, currently under investigation. No CI bypass is being claimed.
Named follow-up: command/RPC participation in authorized prompt enrichment is a product-scope question, not a confirmed bug. Active Memory's documented scope excludes headless and generic
agent-commandpaths. This repair proves interactivechat.send; it neither fabricates authority nor changes that boundary.