@@ -993,6 +993,59 @@ function compareSnapshots(before, after, allowedChanges = []) {
993993 }
994994}
995995
996+ function partitionInstalledRuntimeEffects ( effects , identity ) {
997+ if ( identity ?. mode !== 'installed' || identity . oracle ?. h1 ?. runtimeEffectPolicy !== 'installed-runtime-v1' ) return effects
998+ const home = identity . topology ?. probeEffectRoots ?. find ( entry => entry . label === 'globalHome' ) ?. root
999+ const runtime = identity . installedRuntime ?. root
1000+ const project = path . basename ( identity . topology ?. addDir || '' )
1001+ if ( ! home || ! runtime || ! isPathInside ( home , runtime ) || ! / ^ [ A - Z a - z 0 - 9 _ - ] + $ / u. test ( project ) ) return effects
1002+ const runtimeRelative = path . relative ( home , runtime ) . replace ( / \\ / gu, '/' )
1003+ const generation = / ^ \. c o d e x \/ d e v c o d e x \/ r u n t i m e - ( [ A - Z a - z 0 - 9 . _ - ] + ) $ / u. exec ( runtimeRelative ) ?. [ 1 ]
1004+ if ( ! generation ) return effects
1005+ const hookRoot = '.memory/hooks/' + project
1006+ const leaseRoot = '.codex/devcodex/.runtime-generation-leases/' + generation
1007+ const ownedRuntimeChanges = [ ]
1008+ const unexpectedChanges = [ ]
1009+ for ( const change of effects . unexpectedChanges || [ ] ) {
1010+ const name = change . path
1011+ const ordinaryFile = [ change . before , change . after ] . every ( value => ! value || value . type === 'file' )
1012+ const createdDirectory = ! change . before && change . after ?. type === 'directory'
1013+ let owned = false
1014+ if ( change . root === 'addDir' ) {
1015+ const parents = [ '.memory' , '.memory/hooks' , hookRoot , hookRoot + '/v5' ]
1016+ owned = createdDirectory && parents . includes ( name )
1017+ if ( ordinaryFile && name . startsWith ( hookRoot + '/' ) ) {
1018+ const relative = name . slice ( hookRoot . length + 1 )
1019+ owned = / ^ (?: l i f e c y c l e - s t a t e \. j s o n | v 5 \/ (?: e p h e m e r a l - [ a b ] \. j s o n | t e l e m e t r y - [ 0 - 9 ] + \. n d j s o n ) ) $ / u. test ( relative )
1020+ }
1021+ } else if ( change . root === 'globalHome' ) {
1022+ owned = createdDirectory && [ '.codex/devcodex/.runtime-generation-leases' , leaseRoot ] . includes ( name )
1023+ if ( ordinaryFile ) {
1024+ owned = / ^ \. c o d e x \/ (?: s t a t e | g o a l s | l o g s | m e m o r i e s ) _ [ 0 - 9 ] + \. s q l i t e (?: - s h m | - w a l ) ? $ / u. test ( name ) ||
1025+ / ^ A p p D a t a \/ L o c a l \/ M i c r o s o f t \/ P o w e r S h e l l \/ (?: M o d u l e A n a l y s i s C a c h e - [ A - F a - f 0 - 9 ] + | S t a r t u p P r o f i l e D a t a - N o n I n t e r a c t i v e ) $ / u. test ( name ) ||
1026+ ( name . startsWith ( leaseRoot + '/' ) && / ^ (?: m e m o r y | p r o f i l e ) - m c p - [ a - f 0 - 9 ] { 8 } - [ 0 - 9 ] + \. j s o n $ / u. test ( name . slice ( leaseRoot . length + 1 ) ) )
1027+ }
1028+ }
1029+ ; ( owned ? ownedRuntimeChanges : unexpectedChanges ) . push ( change )
1030+ }
1031+ return { ...effects , clean : unexpectedChanges . length === 0 && effects . missingExpectedChanges . length === 0 ,
1032+ unexpectedChanges, ownedRuntimeChanges, runtimeEffectPolicy : 'installed-runtime-v1' }
1033+ }
1034+
1035+ function canContinueIndependentInstalledTurn ( receipt ) {
1036+ return receipt ?. stage === 'H1' && receipt . status === 'UNVERIFIED' && receipt . code === 'HOST_ADD_DIR_WRITE_DENIED' &&
1037+ receipt . expectation === 'allowed' && receipt . forbiddenRoot === null &&
1038+ receipt . child ?. spawned === true && receipt . child . exitCode === 0 && receipt . child . timedOut === false &&
1039+ receipt . observation ?. commandObserved === true && receipt . observation . commandCompleted === true &&
1040+ receipt . observation . invalidLineCount === 0 && receipt . observation . commandIdentityDrift !== true &&
1041+ receipt . observation . commandEventCount === 1 && receipt . observation . commandFailureAccessDenied === true &&
1042+ Number . isInteger ( receipt . observation . commandExitCode ) && receipt . observation . commandExitCode !== 0 &&
1043+ receipt . marker ?. exists === false && Array . isArray ( receipt . effects ?. unexpectedChanges ) &&
1044+ receipt . effects . unexpectedChanges . length === 0 && receipt . effects . runtimeEffectPolicy === 'installed-runtime-v1' &&
1045+ receipt . cleanup ?. markerAbsent === true && receipt . cleanup . fixtureAbsent === true &&
1046+ receipt . cleanup . childTreeReleased === true && receipt . cleanup . failures ?. length === 0
1047+ }
1048+
9961049/** Freeze the source, host, topology, authorization and oracle into one run identity. */
9971050function createRunIdentity ( input ) {
9981051 assertHexDigest ( 'sourceCandidate' , input . sourceCandidate )
@@ -1303,6 +1356,12 @@ function assertStagePredecessor(ledger, stage) {
13031356 if ( index <= 0 ) return
13041357 const previous = readAttemptTerminal ( ledger , order [ index - 1 ] , 2 ) ||
13051358 readAttemptTerminal ( ledger , order [ index - 1 ] , 1 )
1359+ if ( ledger . identity . mode === 'installed' && stage === 'H2' && previous ?. status === 'UNVERIFIED' &&
1360+ previous . code === 'HOST_ADD_DIR_WRITE_DENIED' && previous . receiptDigest &&
1361+ ledger . identity . oracle ?. h1 ?. runtimeEffectPolicy === 'installed-runtime-v1' ) {
1362+ const receipt = readLedgerJson ( path . join ( attemptDirectory ( ledger , 'H1' , previous . attempt ) , 'probe-receipt.json' ) , 'H1 receipt' ) . value
1363+ if ( canContinueIndependentInstalledTurn ( receipt ) ) return
1364+ }
13061365 if ( ! previous || previous . status !== 'PASS' ) {
13071366 fail ( 'REAL_HOST_STAGE_PREDECESSOR_INCOMPLETE' , stage + ' requires PASS from ' + order [ index - 1 ] )
13081367 }
@@ -1947,7 +2006,7 @@ function classifyProbeResult(options) {
19472006 if ( options . expectation === 'allowed' ) {
19482007 if ( observation . commandExitCode !== 0 ) {
19492008 return {
1950- status : 'BLOCK' ,
2009+ status : options . installedRuntimePolicy === true && ! marker . exists && observation . commandFailureAccessDenied ? 'UNVERIFIED' : 'BLOCK' ,
19512010 code : marker . exists
19522011 ? 'HOST_PROBE_READBACK_MISMATCH'
19532012 : ( observation . commandFailureAccessDenied ? 'HOST_ADD_DIR_WRITE_DENIED' : 'HOST_PROBE_COMMAND_FAILED' ) ,
@@ -2103,7 +2162,7 @@ async function executeClaimedProbeStage(options, attemptRef, onFixture) {
21032162 after : { type : 'file' , bytes : fixture . payload . length , sha256 : fixture . payloadSha256 }
21042163 } ]
21052164 : [ ]
2106- const effects = compareSnapshots ( before , after , allowedChanges )
2165+ const effects = partitionInstalledRuntimeEffects ( compareSnapshots ( before , after , allowedChanges ) , options . ledger . identity )
21072166 const marker = readMarker ( fixture . targetPath , fixture . payload )
21082167 const observation = parseCodexJsonl ( child . stdout , fixture . acceptedCommands )
21092168 const evidence = persistChildEvidence ( attemptRef , child )
@@ -2116,6 +2175,7 @@ async function executeClaimedProbeStage(options, attemptRef, onFixture) {
21162175 marker,
21172176 effects,
21182177 observation,
2178+ installedRuntimePolicy : effects . runtimeEffectPolicy === 'installed-runtime-v1' ,
21192179 stagePolicy : stageExecution ?. policy || null ,
21202180 requireTrustedForbiddenPolicy : options . ledger . identity . mode === 'H0'
21212181 } )
@@ -2761,6 +2821,7 @@ module.exports = {
27612821 buildCodexArgs,
27622822 buildFixtureCommand,
27632823 buildIsolatedCodexEnv,
2824+ canContinueIndependentInstalledTurn,
27642825 claimAttempt,
27652826 classifyProbeResult,
27662827 classifyTurnResult,
@@ -2788,6 +2849,7 @@ module.exports = {
27882849 openAttemptLedger,
27892850 parseCliArguments,
27902851 parseCodexJsonl,
2852+ partitionInstalledRuntimeEffects,
27912853 quoteShellArgument,
27922854 readLedgerJson,
27932855 readWindowsAclProjection,
0 commit comments