fix: stabilize context engine prompt cache touches#67767
Conversation
🔒 Aisle Security AnalysisWe found 2 potential security issue(s) in this PR:
1. 🟡 Sensitive runtime metadata/PII exposed to pluggable ContextEngine via loop-hook runtimeContext
Description
If a
Vulnerable code: await contextEngine.afterTurn({
// ...
messages: sourceMessages,
prePromptMessageCount,
tokenBudget,
runtimeContext: params.getRuntimeContext?.({
messages: sourceMessages,
prePromptMessageCount,
}),
});RecommendationTreat
Example (only expose prompt cache info): getRuntimeContext: ({ messages, prePromptMessageCount }) => ({
promptCache: buildLoopPromptCacheInfo({
messagesSnapshot: messages,
prePromptMessageCount,
retention: effectivePromptCacheRetention,
fallbackLastCacheTouchAt,
}),
})Additionally, document that 2. 🟡 Untrusted usage metrics can influence prompt-cache TTL touch timestamp decisions
Description
If an attacker can inject/spoof assistant messages (or their
Downstream, Vulnerable logic: const hasCacheUsage =
typeof params.lastCallUsage?.cacheRead === "number" ||
typeof params.lastCallUsage?.cacheWrite === "number";
if (!hasCacheUsage) {
return params.fallbackLastCacheTouchAt ?? null;
}
return (
parsePromptCacheTouchTimestamp(params.assistantTimestamp) ??
params.fallbackLastCacheTouchAt ??
null
);RecommendationTreat Suggested hardening (pick one or combine):
const cacheRead = params.lastCallUsage?.cacheRead;
const cacheWrite = params.lastCallUsage?.cacheWrite;
const hasCacheUsage =
(typeof cacheRead === "number" && Number.isFinite(cacheRead) && cacheRead > 0) ||
(typeof cacheWrite === "number" && Number.isFinite(cacheWrite) && cacheWrite > 0);
Analyzed PR: #67767 at commit Last updated on: 2026-04-16T18:48:17Z |
Greptile SummaryThis PR fixes two gaps in the embedded runner's context-engine prompt-cache metadata flow: the loop-hook Confidence Score: 5/5Safe to merge — focused fix with full branch coverage for both corrected code paths. All changes are additive and backward-compatible. The helper logic is straightforward and guarded against bad inputs ( No files require special attention. Reviews (1): Last reviewed commit: "fix: stabilize context engine prompt cac..." | Re-trigger Greptile |
6e77191 to
74d9b56
Compare
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
* fix: stabilize context engine prompt cache touches * fix(changelog): document context-engine prompt cache touch stabilization
What
This PR makes context-engine prompt-cache touch metadata consistent across the embedded runner afterTurn paths so lossless-claw can keep Anthropic and GPT cache state accurate during active tool loops and final turn ingestion.
Why
The loop-hook afterTurn path was dropping runtime context entirely, and the final afterTurn path only reused persisted TTL state. That left lossless-claw operating on stale or missing cache-touch signals, which could force unnecessary deferred compaction once Anthropic TTL expired.
Changes
Testing
pnpm exec vitest run src/agents/pi-embedded-runner/run/attempt.spawn-workspace.context-engine.test.ts src/agents/pi-embedded-runner/tool-result-context-guard.test.tsgit commithook ran repo checks successfully