@@ -78,6 +78,7 @@ import {
7878 type PreparedCompartmentInjection ,
7979 prepareCompartmentInjection ,
8080 renderExternalMemoryBlock ,
81+ renderExternalMemoryDelta ,
8182 renderMemoryBlockV2 ,
8283 trimMemoriesToBudgetV2 ,
8384 trimUserMemoriesToBudget ,
@@ -1645,6 +1646,14 @@ function renderMemoryUpdatesBlockPi(args: {
16451646interface RenderM1PiResult {
16461647 text : string ;
16471648 memoryUpdateCount : number ;
1649+ /** The <external-memory> delta block (late-arrival snapshot) when present,
1650+ * "" otherwise. Excluded from the injectM0M1Pi pressure-refold token math
1651+ * so a large recall can NEVER cause an m[0] refold (parity with OpenCode). */
1652+ externalDeltaText : string ;
1653+ /** True when freshly rendered from current DB state. False when replayed
1654+ * from a sibling-adoption row. The pressure-refold backstop must only fire
1655+ * on recomputed bytes (parity with OpenCode RenderM1Result.recomputed). */
1656+ recomputed : boolean ;
16481657}
16491658
16501659function renderM1PiWithMetadata (
@@ -1767,28 +1776,42 @@ function renderM1PiWithMetadata(
17671776
17681777 // External memory delta: when the live recall hash differs from the m[0]
17691778 // baseline hash, surface the current recall snapshot as a delta. Mirrors
1770- // OpenCode renderM1's renderExternalMemoryDelta path. The delta carries ALL
1771- // slices (profile lines reconcile into <user-profile> at the next HARD fold).
1772- const liveExternalRecallHash = readExternalRecallHash ( db , state . sessionId ) ;
1773- if ( liveExternalRecallHash !== markers . externalRecallHash ) {
1774- const recallRead = readExternalRecallSnapshot ( db , state . sessionId ) ;
1775- if ( recallRead . state === "done" && recallRead . snapshot ) {
1776- const externalBlock = renderExternalMemoryBlock ( recallRead . snapshot ) ;
1777- if ( externalBlock ) sections . push ( externalBlock ) ;
1779+ // OpenCode renderM1WithMetadata's renderExternalMemoryDelta path. The delta
1780+ // carries ALL slices including profile (profile lines reconcile into
1781+ // <user-profile> at the next HARD fold). Captured separately so the caller
1782+ // can subtract its tokens from the pressure-refold math — recall is NOT a
1783+ // bust trigger (parity with OpenCode RenderM1Result.externalDeltaText).
1784+ let externalDeltaText = "" ;
1785+ const recallRead = readExternalRecallSnapshot ( db , state . sessionId ) ;
1786+ if ( recallRead . state === "done" && recallRead . snapshot ) {
1787+ const currentRecallHash = computeRecallSnapshotHash ( recallRead . snapshot ) ;
1788+ if (
1789+ currentRecallHash !== "" &&
1790+ currentRecallHash !== markers . externalRecallHash
1791+ ) {
1792+ const delta = renderExternalMemoryDelta ( recallRead . snapshot ) ;
1793+ if ( delta ) {
1794+ externalDeltaText = delta ;
1795+ sections . push ( delta ) ;
1796+ }
17781797 }
17791798 }
17801799
17811800 if ( sections . length === 0 ) {
17821801 return {
17831802 text : PI_M1_PLACEHOLDER ,
17841803 memoryUpdateCount : memoryUpdates . count ,
1804+ externalDeltaText : "" ,
1805+ recomputed : true ,
17851806 } ;
17861807 }
17871808 // Join with "\n" (single newline) to match OpenCode renderM1 exactly — the
17881809 // m[1] delta bytes must be identical across harnesses.
17891810 return {
17901811 text : `<session-history-since>\n${ sections . join ( "\n" ) } \n</session-history-since>` ,
17911812 memoryUpdateCount : memoryUpdates . count ,
1813+ externalDeltaText,
1814+ recomputed : true ,
17921815 } ;
17931816}
17941817
@@ -2015,6 +2038,7 @@ function softRefreshCachedM1Pi(args: {
20152038 markers : PiM0SnapshotMarkers ;
20162039 memoryUpdateCount : number ;
20172040 recomputed : boolean ;
2041+ externalDeltaText : string ;
20182042} {
20192043 const preRenderedKeyFilesBlock = preRenderKeyFilesBlockPi (
20202044 args . state ,
@@ -2043,15 +2067,20 @@ function softRefreshCachedM1Pi(args: {
20432067 args . db ,
20442068 args . state . sessionId ,
20452069 ) ;
2046- return {
2047- ...applyCachedPiRow ( {
2048- row : sibling ,
2049- state : args . state ,
2050- compartmentsForNormalization : siblingCompartments ,
2051- } ) ,
2052- memoryUpdateCount : 0 ,
2053- recomputed : false ,
2054- } ;
2070+ return {
2071+ ...applyCachedPiRow ( {
2072+ row : sibling ,
2073+ state : args . state ,
2074+ compartmentsForNormalization : siblingCompartments ,
2075+ } ) ,
2076+ memoryUpdateCount : 0 ,
2077+ recomputed : false ,
2078+ // Sibling-adoption replay: the bytes are persisted, not freshly
2079+ // rendered. The external delta is unknown from the persisted row;
2080+ // use "" so the pressure backstop (which only fires on recomputed
2081+ // bytes) is never triggered by a replayed sibling m[1].
2082+ externalDeltaText : "" ,
2083+ } ;
20552084 }
20562085
20572086 const markers = markersFromCachedPiRow (
@@ -2103,6 +2132,7 @@ function softRefreshCachedM1Pi(args: {
21032132 markers : { ...markers , lastBaselineEndMessageId : advancedBoundary } ,
21042133 memoryUpdateCount : rendered . memoryUpdateCount ,
21052134 recomputed : true ,
2135+ externalDeltaText : rendered . externalDeltaText ,
21062136 } ;
21072137 } catch ( error ) {
21082138 try {
@@ -2164,6 +2194,10 @@ export function injectM0M1Pi(
21642194 let memoryUpdateCount = 0 ;
21652195 let m1Recomputed = false ;
21662196 let freshFallbackRenderedMemoryIds : number [ ] | null = null ;
2197+ // Tracks the external-recall delta text from the freshly rendered m[1] so
2198+ // the pressure backstop can subtract its tokens — recall must NEVER cause a
2199+ // fold (parity with OpenCode injectM0M1 externalDeltaText subtraction).
2200+ let m1ExternalDeltaText = "" ;
21672201
21682202 if ( decision . value ) {
21692203 // On contention exhaustion, reuse the cached m[0]/m[1] pair rather than
@@ -2259,6 +2293,7 @@ export function injectM0M1Pi(
22592293 m1 = freshM1 . text ;
22602294 memoryUpdateCount = freshM1 . memoryUpdateCount ;
22612295 m1Recomputed = true ;
2296+ m1ExternalDeltaText = freshM1 . externalDeltaText ;
22622297 } else if ( contentionExhausted ) {
22632298 // m[1] was replayed with the cached m[0] pair above.
22642299 } else if ( recomputeM1ThisPass ) {
@@ -2274,6 +2309,7 @@ export function injectM0M1Pi(
22742309 markers = refreshed . markers ;
22752310 memoryUpdateCount = refreshed . memoryUpdateCount ;
22762311 m1Recomputed = refreshed . recomputed ;
2312+ m1ExternalDeltaText = refreshed . externalDeltaText ;
22772313 } else {
22782314 const replayed = replayCachedM1Pi ( db , state , currentCompartments ) ;
22792315 m0 = replayed . m0 ;
@@ -2294,6 +2330,15 @@ export function injectM0M1Pi(
22942330 // Token counts (NOT char lengths) on both sides of the ratio — parity with
22952331 // OpenCode. The documented intent is "m[1] exceeds ~15% of m[0] tokens";
22962332 // char length diverges from token count on XML-heavy / non-Latin content.
2333+ //
2334+ // External recall content must NEVER CAUSE a fold (spec: not a bust trigger);
2335+ // it rides along when a fold fires for other reasons. Two layers of
2336+ // subtraction from m1Tokens: the delta itself (late recall) AND a small
2337+ // wrapper overhead (every m[1] carries the wrapper, empty or not — not a
2338+ // drift signal). The wrapper tokens are also subtracted from the absolute
2339+ // cap budget for symmetry, so a tiny m[0] baseline (where the wrapper
2340+ // alone would exceed the cap) does not falsely fire a refold when the
2341+ // only m[1] content is the recall delta. (Parity with OpenCode injectM0M1.)
22972342 const M0_DRIFT_RATIO_FLOOR_TOKENS = 500 ;
22982343 const M1_DRIFT_RATIO = 0.15 ;
22992344 const M1_ABSOLUTE_CAP_RATIO = 0.2 ;
@@ -2302,8 +2347,21 @@ export function injectM0M1Pi(
23022347 M1_ABSOLUTE_CAP_RATIO ;
23032348 const m1HasContent = m1 !== PI_M1_PLACEHOLDER ;
23042349 const m1Tokens = m1HasContent ? estimateTokens ( m1 ) : 0 ;
2350+ const M1_PRESSURE_WRAPPER_TOKENS = 20 ;
2351+ const externalDeltaTokens = m1ExternalDeltaText
2352+ ? estimateTokens ( m1ExternalDeltaText )
2353+ : 0 ;
2354+ const m1PressureTokens = Math . max (
2355+ 0 ,
2356+ m1Tokens - externalDeltaTokens - M1_PRESSURE_WRAPPER_TOKENS ,
2357+ ) ;
2358+ const m1AbsoluteContentBudget = Math . max (
2359+ 0 ,
2360+ m1AbsoluteBudget - M1_PRESSURE_WRAPPER_TOKENS ,
2361+ ) ;
23052362 const m0Tokens = estimateTokens ( m0 ) ;
2306- const m1OverAbsoluteCap = m1HasContent && m1Tokens > m1AbsoluteBudget ;
2363+ const m1OverAbsoluteCap =
2364+ m1HasContent && m1PressureTokens > m1AbsoluteContentBudget ;
23072365 if (
23082366 ! materialized &&
23092367 ! contentionExhausted &&
@@ -2313,7 +2371,7 @@ export function injectM0M1Pi(
23132371 m1OverAbsoluteCap ||
23142372 ( m1HasContent &&
23152373 m0Tokens >= M0_DRIFT_RATIO_FLOOR_TOKENS &&
2316- m1Tokens > m0Tokens * M1_DRIFT_RATIO ) )
2374+ m1PressureTokens > m0Tokens * M1_DRIFT_RATIO ) )
23172375 ) {
23182376 decision = { value : true , reason : "drift" } ;
23192377 try {
0 commit comments