@@ -589,6 +589,19 @@ function underRoot(root, path) {
589589 return contained !== ".." && ! contained . startsWith ( `..${ String . fromCharCode ( 47 ) } ` ) && ! isAbsolute ( contained )
590590}
591591
592+ async function appliedWorkspaceEvidence ( refs , artifactsPath ) {
593+ const root = await realpath ( resolve ( artifactsPath ) )
594+ const evidence = { }
595+ for ( const [ kind , key ] of [ [ "codebox-patch" , "patch" ] , [ "codebox-changed-files" , "changed_files" ] ] ) {
596+ const ref = refs . find ( ( entry ) => entry . kind === kind && typeof entry . path === "string" && entry . path )
597+ if ( ! ref ) continue
598+ const path = await realpath ( resolve ( root , ref . path ) ) . catch ( ( error ) => error ?. code === "ENOENT" ? "" : Promise . reject ( error ) )
599+ if ( ! path || ! underRoot ( root , path ) ) continue
600+ evidence [ key ] = { artifact_path : relative ( root , path ) . replaceAll ( "\\" , "/" ) }
601+ }
602+ return Object . keys ( evidence ) . length === 2 ? evidence : undefined
603+ }
604+
592605async function canonicalReviewerTranscript ( nativeRuntimeResult , artifactsPath ) {
593606 const publicCore = await import ( pathToFileURL ( join ( codeboxRoot , "packages/runtime-core/dist/public.js" ) ) . href )
594607 const refs = publicCore . normalizePublicArtifactRefDTOs ( nativeRuntimeResult )
@@ -792,6 +805,7 @@ if (toolObservability) {
792805}
793806assertNoRuntimeSourcePaths ( runtimeResult , privateRuntimeSourceRootForSanitization )
794807let workspaceApply = { status : "no-op" , changedFiles : [ ] }
808+ let workspaceEvidence
795809let runnerWorkspaceCore = null
796810let downstreamFailure = null
797811if ( execution . code === 0 && runtimeResult . success === true && request . runner_workspace ?. enabled ) {
@@ -800,6 +814,7 @@ if (execution.code === 0 && runtimeResult.success === true && request.runner_wor
800814 const publicCore = await import ( pathToFileURL ( join ( codeboxRoot , "packages/runtime-core/dist/public.js" ) ) . href )
801815 const refs = publicCore . normalizePublicArtifactRefDTOs ( runtimeResult )
802816 . filter ( ( ref ) => ref . kind === "codebox-patch" || ref . kind === "codebox-changed-files" )
817+ workspaceEvidence = await appliedWorkspaceEvidence ( refs , artifactsPath )
803818 const trustedArtifacts = await trustedArtifactApplyRefs ( trustedApplyArtifactRoot , refs )
804819 workspaceApply = await runnerWorkspaceCore . applyRunnerWorkspacePatch ( { artifactRoot : trustedArtifacts . root , artifactRefs : trustedArtifacts . refs , workspaceRoot : workspace , writablePaths, seedIdentity : runnerWorkspaceSeedSnapshot ?. provenance . identity } )
805820 } catch ( error ) {
@@ -835,7 +850,21 @@ if (execution.code === 0 && request.run_agent && !request.dry_run && !downstream
835850const verificationPassed = verification . every ( ( check ) => check . success )
836851if ( ! verificationPassed ) {
837852 const artifactError = verification . find ( ( check ) => check . artifact_error ) ?. artifact_error
838- downstreamFailure ??= { stage : "verification" , message : artifactError ?. message || "Runner workspace verification did not pass." , ...( artifactError ? { artifact_error : artifactError } : { } ) }
853+ const failedCheck = verification . find ( ( check ) => ! check . success )
854+ const diagnostic = failedCheck ? {
855+ kind : failedCheck . kind ,
856+ command : failedCheck . command ,
857+ exit_code : failedCheck . exit_code ,
858+ stdout_tail : bounded ( failedCheck . stdout , MAX_WORKFLOW_OUTPUT_BYTES ) ,
859+ stderr_tail : bounded ( failedCheck . stderr , MAX_WORKFLOW_OUTPUT_BYTES ) ,
860+ } : undefined
861+ downstreamFailure ??= {
862+ stage : "verification" ,
863+ message : artifactError ?. message || "Runner workspace verification did not pass." ,
864+ ...( artifactError ? { artifact_error : artifactError } : { } ) ,
865+ ...( diagnostic ? { diagnostic } : { } ) ,
866+ ...( workspaceApply . status === "applied" && workspaceEvidence ? { evidence : workspaceEvidence } : { } ) ,
867+ }
839868}
840869const runtimeRecord = record ( runtimeResult )
841870const agentResult = record ( runtimeRecord . agent_task_run_result )
0 commit comments