import { assert, codedError, hashValue, recordError, summarizeRecordedError, } from '../assertions/core.mjs'; import { fs, os, path, TextDecoder } from '../dependencies.mjs'; import { mainAgentId, projectSupervisorAgentId, sentinelFileName, sentinelSchema, state, } from '../runtime-state.mjs'; import { isContextCompactionSuite } from '../suites/context-compaction.mjs'; import { isGoalRuntimeSuite } from '../suites/goal.mjs'; import { isParallelReadSuite } from '../suites/parallel-read.mjs'; import { isProjectSkillSuite } from '../suites/project-skill.mjs'; import { isResponseStreamSuite } from '../suites/response-stream.mjs'; import { isScopedAgentsSuite } from '../suites/scoped-agents.mjs'; import { isSteerRunnerKillSuite } from '../suites/steer-runner-kill.mjs'; import { isSupervisorAutonomousPlayableLaneDefenseSuite } from '../suites/supervisor-autonomous-playable.mjs'; import { isSupervisorSwarmSuite } from '../suites/supervisor-swarm.mjs'; import { isUserInputRuntimeSuite } from '../suites/user-input.mjs'; import { isWebSearchSuite } from '../suites/web-search.mjs'; import { isPathInside, readJson } from './io.mjs'; export async function removeDisposableProject() { const [realTemp, realProject] = await Promise.all([ fs.realpath(os.tmpdir()), fs.realpath(state.projectRoot), ]); if (!isPathInside(realTemp, realProject)) return false; const sentinelPath = path.join(realProject, sentinelFileName); const metadata = await fs.lstat(sentinelPath).catch(() => null); if (!metadata?.isFile() || metadata.isSymbolicLink()) return false; const sentinel = await readJson(sentinelPath).catch(() => null); if ( sentinel?.schemaVersion !== sentinelSchema || sentinel?.token !== state.sentinelToken ) { return false; } await fs.rm(realProject, { recursive: true, force: false }); return true; } export function providerUsedFromEvidence(evidence) { const requestIdentityCount = evidence?.providerRequestIdentityCount; const startedCount = evidence?.providerLifecycleStartedCount; const terminalCount = evidence?.providerLifecycleTerminalCount; const completedCount = evidence?.providerLifecycleCompletedCount; return ( evidence?.evidenceCompleteness === 'complete' && evidence.providerAgentMode === 'provider' && evidence.providerBindingMatched === true && typeof evidence.providerModel === 'string' && evidence.providerModel.trim().length > 0 && typeof evidence.providerApiKind === 'string' && evidence.providerApiKind.trim().length > 0 && typeof evidence.providerReasoningEffort === 'string' && evidence.providerReasoningEffort.trim().length > 0 && /^[0-9a-f]{64}$/u.test(evidence.providerBaseUrlSha256 ?? '') && Number.isSafeInteger(evidence.providerBoundAgentCount) && evidence.providerBoundAgentCount > 0 && Number.isSafeInteger(requestIdentityCount) && Number.isSafeInteger(startedCount) && Number.isSafeInteger(terminalCount) && Number.isSafeInteger(completedCount) && requestIdentityCount > 0 && startedCount === requestIdentityCount && terminalCount === requestIdentityCount && completedCount === requestIdentityCount && evidence.providerLifecycleFailedCount === 0 && evidence.openProviderLifecycleCount === 0 && evidence.duplicateProviderLifecycleCount === 0 ); } export function buildSummary() { const secretLeakCount = state.transcriptLeakCount + state.projectLeakCount + state.reportLeakCount; const base = { status: state.status, suite: state.suite, providerUsed: providerUsedFromEvidence(state.evidence), config: state.config, blocked: state.blocked, run: { agentId: isUserInputRuntimeSuite() || isSupervisorAutonomousPlayableLaneDefenseSuite() || isSupervisorSwarmSuite() ? projectSupervisorAgentId : mainAgentId, runIdHash: hashValue(state.initialRunId), sessionIdHash: hashValue(state.initialSessionId), runnerKilled: isSupervisorAutonomousPlayableLaneDefenseSuite() ? false : state.runnerKilled, resumed: state.resumed, identityStable: state.identityStable, }, evidence: { ...state.evidence, secretLeakCount, lureLeakCount: state.lureLeakCount, projectPathTranscriptLeakCount: state.projectPathTranscriptLeakCount, projectPathReportLeakCount: state.projectPathReportLeakCount, ...(isWebSearchSuite() || isContextCompactionSuite() || isUserInputRuntimeSuite() || isScopedAgentsSuite() || isProjectSkillSuite() || isParallelReadSuite() || isSupervisorAutonomousPlayableLaneDefenseSuite() || isSupervisorSwarmSuite() || isSteerRunnerKillSuite() ? { formalConfigPathTranscriptLeakCount: state.formalConfigPathTranscriptLeakCount, formalConfigPathReportLeakCount: state.formalConfigPathReportLeakCount, } : {}), }, cleanup: { performed: state.cleanupPerformed, kept: Boolean(state.options?.keepProject), }, errorCount: state.errors.length, errorHashes: state.errors.map(summarizeRecordedError), }; base.summaryHash = hashValue(JSON.stringify(base)); return base; } export function emptyEvidence() { return { taskCount: 0, eventCount: 0, agentDbRecordCount: 0, successfulToolExecutionCount: 0, toolPlanProtocolCount: 0, structuredPlanUpdateCount: 0, structuredPlanRevision: 0, structuredPlanCompletedStepCount: 0, structuredPlanRegressionCount: 0, structuredPlanPreKillRevision: 0, structuredPlanPreKillCompletedStepCount: 0, structuredPlanPreKillIncompleteStepCount: 0, structuredPlanPreKillTerminalStepHash: null, structuredPlanRecoveredRevision: 0, structuredPlanRecoveredCompletedStepCount: 0, structuredPlanRecoveredTerminalStepHash: null, structuredPlanTimelineUpdateCount: 0, structuredPlanTimelineAnchoredUpdateCount: 0, structuredPlanCompletionTransitionCount: 0, structuredPlanCompletionObservationCount: 0, structuredPlanPrematureCompletionCount: 0, structuredPlanTimelineHash: null, steerAcceptedPlanRevision: 0, steerSequence: 0, steerIdHash: null, steerMessageIdHash: null, steerInstructionSha256: null, steerProviderInterrupted: false, steerProviderPlanningWaitMatched: false, steerCompletedStepCountAtAcceptance: 0, steerIncompleteStepCountAtAcceptance: 0, steerFirstPostPlanRevision: 0, steerFirstPostIncompleteStepCount: 0, steerIncompletePlanReordered: false, steerOldPendingActionCount: 0, steerOldPendingActionSetHash: null, steerOldPendingExecutionCount: 0, steerOldPlanMaterializedActionCount: 0, steerAcceptanceWindowExecutionCount: 0, steerSideEffectReceiptCountAtAcceptance: 0, steerSideEffectSnapshotHash: null, steerPreSideEffectReplayCount: 0, steerLedgerRecordCount: 0, steerAppliedCount: 0, steerClosedCount: 0, steerAuditCount: 0, steerTaskRunCountBefore: 0, steerTaskRunCountAfter: 0, steerTaskRunSetHash: null, finalTargetMainRunCount: 0, finalLegalMainLineageRunCount: 0, finalUnexpectedMainRunCount: 0, finalTargetMainRunSetHash: null, steerPublicInstructionLeakCount: 0, steerInstructionReportLeakCount: 0, confirmedActionLifecycleCount: 0, sideEffectActionCount: 0, sideEffectReplayCount: 0, idempotentReplayActionCount: 0, actionReceiptReplayRecordCount: 0, completedProjectionCount: 0, finalAssistantAuditCount: 0, projectRevision: 0, projectIndexExecutionCount: 0, gitInspectExecutionCount: 0, gitInspectChangedFileCount: 0, gitInspectRevisionNeutral: false, gitInspectPostCommitSelectedPathsClean: false, gitCommitExecutionCount: 0, gitCommitPathCount: 0, gitCommitAuditCount: 0, gitCommitReceiptCount: 0, gitCommitParentMatched: false, gitCommitTreeMatched: false, gitCommitReflogMatched: false, gitCommitPostInspectSelectedPathsClean: false, repositoryContextSourceCount: 0, checkpointFileCount: 0, patchsetExecutionCount: 0, patchsetPreparedAuditCount: 0, patchsetCompletedAuditCount: 0, patchsetChangeCount: 0, patchsetRevisionDelta: 0, patchsetContentDiffFileCount: 0, patchsetCheckpointBound: false, patchsetExpectedSha256Matched: false, halfCompletedFileCount: 0, commandExecRunCount: 0, commandExecFailedCount: 0, commandExecSucceededCount: 0, commandOutputReadExecutionCount: 0, commandOutputPageCount: 0, commandOutputMarkerSidecarCount: 0, commandOutputMarkerContextCount: 0, commandOutputMarkerTaskLeakCount: 0, commandOutputMarkerEventLeakCount: 0, commandOutputMarkerAgentDbLeakCount: 0, commandOutputMarkerConversationLeakCount: 0, commandOutputMarkerActivityLeakCount: 0, commandOutputMarkerOutputLeakCount: 0, commandOutputMarkerRuntimeStateLeakCount: 0, commandOutputMarkerReceiptLeakCount: 0, commandOutputReadReceiptCount: 0, commandOutputMarkerReportLeakCount: 0, editorApiAssetCount: 0, verificationPassed: false, browserValidationCount: 0, imageInspectExecutionCount: 0, imageInspectImageCount: 0, imageInspectDedicatedAuditCount: 0, imageInspectReceiptCount: 0, imageInspectResponseIdPresent: false, persistedImagePayloadLeakCount: 0, isolatedInstanceCount: 0, isolatedTemplateCount: 0, isolatedJoinCount: 0, isolatedJoinDeliveryTarget: null, isolatedParentWakeDispatchCount: 0, actionHistoryExecutionCount: 0, actionHistoryResultCount: 0, actionHistoryRecursiveResultCount: 0, actionReceiptCount: 0, mainRunActionReceiptCount: 0, actionReceiptRequiredToolCount: 0, actionReceiptDuplicateIdentityCount: 0, actionReceiptSecretLeakCount: 0, actionReceiptLureLeakCount: 0, conversationMessageCount: 0, targetSessionMessageCount: 0, targetSessionUserMessageCount: 0, targetSessionAssistantMessageCount: 0, targetSessionConversationAuditCount: 0, finalAssistantCount: 0, duplicateActionCount: 0, duplicateMessageCount: 0, duplicateReceiptCount: 0, confirmedActionCount: 0, projectPathPublicLeakCount: 0, projectPathPublicSurfaceCount: 0, projectPathTranscriptLeakCount: 0, projectPathReportLeakCount: 0, secretLeakCount: 0, lureLeakCount: 0, paths: [], }; } export async function collectPartialRuntimeJsonlSurface( suitePrefix, surface, resolveFiles, ) { let files; try { files = await resolveFiles(); } catch { const errors = ['surface-list-failed']; recordError( `${suitePrefix}-partial-${surface}-read-failed`, codedError(errors[0]), ); return { records: [], errors }; } const result = await readJsonlFilesPreservingValidRecords(files); if (result.errors.length > 0) { recordError( `${suitePrefix}-partial-${surface}-read-failed`, codedError([...new Set(result.errors)].join(',')), ); } return { records: result.records, errors: [...new Set(result.errors)], }; } export async function readJsonlFilesPreservingValidRecords(files) { const records = []; const errors = []; for (const file of files) { const result = await readJsonlPreservingValidRecords(file); records.push(...result.records); errors.push(...result.errors); } return { records, errors }; } export async function readJsonlPreservingValidRecords(file) { let content; try { content = await fs.readFile(file); } catch (error) { return { records: [], errors: [ error?.code === 'ENOENT' ? 'file-disappeared' : 'file-read-failed', ], }; } const records = []; const errors = []; const lines = splitJsonlBufferLines(content); for (const lineRecord of lines) { let line; try { line = decodeUtf8Fatal(lineRecord.bytes, 'jsonl-invalid-utf8'); } catch { errors.push('invalid-utf8'); continue; } if (line.trim().length === 0) continue; try { const record = JSON.parse(line); if (!record || typeof record !== 'object' || Array.isArray(record)) { errors.push('invalid-record'); continue; } records.push(record); } catch { errors.push(lineRecord.terminated ? 'invalid-record' : 'truncated-tail'); } } return { records, errors }; } export function splitJsonlBufferLines(content) { assert(Buffer.isBuffer(content), 'jsonl-content-not-buffer'); const lines = []; let start = 0; for (let index = 0; index < content.length; index += 1) { if (content[index] !== 0x0a) continue; let end = index; if (end > start && content[end - 1] === 0x0d) end -= 1; lines.push({ bytes: content.subarray(start, end), terminated: true }); start = index + 1; } if (start < content.length) { lines.push({ bytes: content.subarray(start), terminated: false }); } return lines; } export function decodeUtf8Fatal(content, code = 'invalid-utf8') { try { return new TextDecoder('utf-8', { fatal: true }).decode(content); } catch (error) { throw codedError(code, error); } } export async function readLatestJsonFile(files) { const candidates = []; for (const file of files.filter((entry) => entry.endsWith('.json'))) { const metadata = await fs.stat(file).catch(() => null); if (metadata?.isFile()) candidates.push({ file, mtimeMs: metadata.mtimeMs }); } candidates.sort((left, right) => right.mtimeMs - left.mtimeMs); return candidates.length > 0 ? readJson(candidates[0].file).catch(() => null) : null; } export function isIsolatedRunnerSuite() { return ( isSteerRunnerKillSuite() || isGoalRuntimeSuite() || isResponseStreamSuite() || isWebSearchSuite() || isContextCompactionSuite() || isUserInputRuntimeSuite() || isScopedAgentsSuite() || isProjectSkillSuite() || isParallelReadSuite() || isSupervisorAutonomousPlayableLaneDefenseSuite() || isSupervisorSwarmSuite() ); }