@runcofactor/cli 0.23.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/{account-HWN3W3DJ.js → account-LF73VDLD.js} +3 -3
- package/dist/{alert-2XQKWLXV.js → alert-YDCWKNLG.js} +4 -4
- package/dist/{api-catalog-3DNTXLUR.js → api-catalog-SUJ4DUAW.js} +3 -3
- package/dist/{attachment-EKI6FME3.js → attachment-ZOWURGCW.js} +3 -3
- package/dist/{augmentor-WVDFIJVN.js → augmentor-7JFSE344.js} +3 -3
- package/dist/{chunk-5XJARJVW.js → chunk-4O7KUIYE.js} +2 -2
- package/dist/{chunk-UAF5JTY6.js → chunk-EPMDUCEA.js} +2 -2
- package/dist/{chunk-C6GFGMMI.js → chunk-IC3HQSRW.js} +2 -2
- package/dist/{chunk-5H5LE7ZJ.js → chunk-LNX22N2L.js} +2 -2
- package/dist/{chunk-XFESXI7N.js → chunk-LQ5IBELB.js} +2 -2
- package/dist/{chunk-JWPQUDTG.js → chunk-OCT6HQZK.js} +2 -2
- package/dist/{chunk-JNBZKVZE.js → chunk-QX7RZ5CZ.js} +1 -1
- package/dist/chunk-QX7RZ5CZ.js.map +1 -0
- package/dist/{chunk-FZKJERAJ.js → chunk-SL5GDAWL.js} +2 -2
- package/dist/{chunk-AHVGWPO3.js → chunk-SZOPRIBA.js} +18 -2
- package/dist/chunk-SZOPRIBA.js.map +1 -0
- package/dist/{chunk-HXM3JXCX.js → chunk-TVM3VEAP.js} +2 -2
- package/dist/{chunk-2RGTNVYR.js → chunk-YI4LFJFK.js} +36 -11
- package/dist/{chunk-2RGTNVYR.js.map → chunk-YI4LFJFK.js.map} +1 -1
- package/dist/{credential-YCLLYSXW.js → credential-DAK26ZN5.js} +3 -3
- package/dist/{credential-template-ILUYGLUZ.js → credential-template-2S4IKKWH.js} +3 -3
- package/dist/{dist-FC2BFYMX.js → dist-MQMO6WA3.js} +3 -3
- package/dist/{docs-UGJPGZOR.js → docs-SX5RFWWF.js} +3 -3
- package/dist/{environment-TENLRRC3.js → environment-2OAJCTFK.js} +3 -3
- package/dist/{feature-flag-5EBZJD43.js → feature-flag-2HRNJ6Z6.js} +3 -3
- package/dist/index.js +47 -37
- package/dist/index.js.map +1 -1
- package/dist/{init-YCS4OZFP.js → init-U2Z4ZJCC.js} +3 -3
- package/dist/{install-AVD4R5KA.js → install-VYXTJJVC.js} +3 -3
- package/dist/{issues-TRD5CQ4R.js → issues-QTX3YE5G.js} +3 -3
- package/dist/{knobs-DKAVOTMC.js → knobs-HMONFFHZ.js} +3 -3
- package/dist/{list-W3ONQTUH.js → list-46W2OU5D.js} +3 -3
- package/dist/{local-LLQFYBF3.js → local-4Y75MUYQ.js} +5 -5
- package/dist/{login-X72OFYMF.js → login-GCEIQ5FN.js} +3 -3
- package/dist/{mcp-KGMDCJJO.js → mcp-SLYY6DQL.js} +4 -4
- package/dist/{metrics-IRO7NK4L.js → metrics-3S4ZEA3B.js} +3 -3
- package/dist/{product-FAEOC2BC.js → product-2NW74HNE.js} +3 -3
- package/dist/prompts-NKJEQ62J.js +186 -0
- package/dist/prompts-NKJEQ62J.js.map +1 -0
- package/dist/{property-X6NPV2VK.js → property-E675NNFW.js} +3 -3
- package/dist/{record-CJIEUF2Z.js → record-HELPASIE.js} +4 -4
- package/dist/{release-PGLSKZCM.js → release-ZZIANCH7.js} +3 -3
- package/dist/{sandbox-PBRWVF4Y.js → sandbox-TTFAKM63.js} +82 -7
- package/dist/sandbox-TTFAKM63.js.map +1 -0
- package/dist/{scenarios-5TJ76A5P.js → scenarios-FWFSTCTV.js} +3 -3
- package/dist/{schedule-FRAVS3RH.js → schedule-QIXBH2HF.js} +4 -4
- package/dist/{session-E4PFQPBF.js → session-4RB4TRRU.js} +5 -5
- package/dist/skills/debug-run/SKILL.md +1 -1
- package/dist/{spec-ZNOLW4JR.js → spec-7LGJ4H5W.js} +3 -3
- package/dist/{src-OLQ7ZFHS.js → src-F4UX4PMP.js} +140 -8
- package/dist/src-F4UX4PMP.js.map +1 -0
- package/dist/{src-GEMLVCW4.js → src-FW7TIXEQ.js} +3 -3
- package/dist/{start-EV7J2TEF.js → start-IEUE53KY.js} +3 -3
- package/dist/{tag-UXKWRACA.js → tag-J5SX224K.js} +4 -4
- package/dist/{task-VDLJQKUB.js → task-ONZVZQAQ.js} +3 -3
- package/dist/{test-suite-SOM2MTNH.js → test-suite-STGE6IAV.js} +5 -5
- package/dist/{trace-DZCJO27U.js → trace-O5BVV7ZU.js} +4 -4
- package/dist/{triage-UQAB5HGG.js → triage-VS3S7GXN.js} +4 -4
- package/dist/{utilities-D7EYIATI.js → utilities-ARHQATQ6.js} +3 -3
- package/dist/{workflow-X7QNGJJ2.js → workflow-5FJ4D62D.js} +29 -32
- package/dist/workflow-5FJ4D62D.js.map +1 -0
- package/dist/{workflow-cache-ZMYUGEPB.js → workflow-cache-PDLY7XLW.js} +6 -6
- package/dist/{workflow-debug-LQKP27VI.js → workflow-debug-6IJQ5C3X.js} +6 -6
- package/dist/{workflow-proposals-NEXXWL3O.js → workflow-proposals-MTHYBJGV.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-AHVGWPO3.js.map +0 -1
- package/dist/chunk-JNBZKVZE.js.map +0 -1
- package/dist/sandbox-PBRWVF4Y.js.map +0 -1
- package/dist/src-OLQ7ZFHS.js.map +0 -1
- package/dist/workflow-X7QNGJJ2.js.map +0 -1
- /package/dist/{account-HWN3W3DJ.js.map → account-LF73VDLD.js.map} +0 -0
- /package/dist/{alert-2XQKWLXV.js.map → alert-YDCWKNLG.js.map} +0 -0
- /package/dist/{api-catalog-3DNTXLUR.js.map → api-catalog-SUJ4DUAW.js.map} +0 -0
- /package/dist/{attachment-EKI6FME3.js.map → attachment-ZOWURGCW.js.map} +0 -0
- /package/dist/{augmentor-WVDFIJVN.js.map → augmentor-7JFSE344.js.map} +0 -0
- /package/dist/{chunk-5XJARJVW.js.map → chunk-4O7KUIYE.js.map} +0 -0
- /package/dist/{chunk-UAF5JTY6.js.map → chunk-EPMDUCEA.js.map} +0 -0
- /package/dist/{chunk-C6GFGMMI.js.map → chunk-IC3HQSRW.js.map} +0 -0
- /package/dist/{chunk-5H5LE7ZJ.js.map → chunk-LNX22N2L.js.map} +0 -0
- /package/dist/{chunk-XFESXI7N.js.map → chunk-LQ5IBELB.js.map} +0 -0
- /package/dist/{chunk-JWPQUDTG.js.map → chunk-OCT6HQZK.js.map} +0 -0
- /package/dist/{chunk-FZKJERAJ.js.map → chunk-SL5GDAWL.js.map} +0 -0
- /package/dist/{chunk-HXM3JXCX.js.map → chunk-TVM3VEAP.js.map} +0 -0
- /package/dist/{credential-YCLLYSXW.js.map → credential-DAK26ZN5.js.map} +0 -0
- /package/dist/{credential-template-ILUYGLUZ.js.map → credential-template-2S4IKKWH.js.map} +0 -0
- /package/dist/{dist-FC2BFYMX.js.map → dist-MQMO6WA3.js.map} +0 -0
- /package/dist/{docs-UGJPGZOR.js.map → docs-SX5RFWWF.js.map} +0 -0
- /package/dist/{environment-TENLRRC3.js.map → environment-2OAJCTFK.js.map} +0 -0
- /package/dist/{feature-flag-5EBZJD43.js.map → feature-flag-2HRNJ6Z6.js.map} +0 -0
- /package/dist/{init-YCS4OZFP.js.map → init-U2Z4ZJCC.js.map} +0 -0
- /package/dist/{install-AVD4R5KA.js.map → install-VYXTJJVC.js.map} +0 -0
- /package/dist/{issues-TRD5CQ4R.js.map → issues-QTX3YE5G.js.map} +0 -0
- /package/dist/{knobs-DKAVOTMC.js.map → knobs-HMONFFHZ.js.map} +0 -0
- /package/dist/{list-W3ONQTUH.js.map → list-46W2OU5D.js.map} +0 -0
- /package/dist/{local-LLQFYBF3.js.map → local-4Y75MUYQ.js.map} +0 -0
- /package/dist/{login-X72OFYMF.js.map → login-GCEIQ5FN.js.map} +0 -0
- /package/dist/{mcp-KGMDCJJO.js.map → mcp-SLYY6DQL.js.map} +0 -0
- /package/dist/{metrics-IRO7NK4L.js.map → metrics-3S4ZEA3B.js.map} +0 -0
- /package/dist/{product-FAEOC2BC.js.map → product-2NW74HNE.js.map} +0 -0
- /package/dist/{property-X6NPV2VK.js.map → property-E675NNFW.js.map} +0 -0
- /package/dist/{record-CJIEUF2Z.js.map → record-HELPASIE.js.map} +0 -0
- /package/dist/{release-PGLSKZCM.js.map → release-ZZIANCH7.js.map} +0 -0
- /package/dist/{scenarios-5TJ76A5P.js.map → scenarios-FWFSTCTV.js.map} +0 -0
- /package/dist/{schedule-FRAVS3RH.js.map → schedule-QIXBH2HF.js.map} +0 -0
- /package/dist/{session-E4PFQPBF.js.map → session-4RB4TRRU.js.map} +0 -0
- /package/dist/{spec-ZNOLW4JR.js.map → spec-7LGJ4H5W.js.map} +0 -0
- /package/dist/{src-GEMLVCW4.js.map → src-FW7TIXEQ.js.map} +0 -0
- /package/dist/{start-EV7J2TEF.js.map → start-IEUE53KY.js.map} +0 -0
- /package/dist/{tag-UXKWRACA.js.map → tag-J5SX224K.js.map} +0 -0
- /package/dist/{task-VDLJQKUB.js.map → task-ONZVZQAQ.js.map} +0 -0
- /package/dist/{test-suite-SOM2MTNH.js.map → test-suite-STGE6IAV.js.map} +0 -0
- /package/dist/{trace-DZCJO27U.js.map → trace-O5BVV7ZU.js.map} +0 -0
- /package/dist/{triage-UQAB5HGG.js.map → triage-VS3S7GXN.js.map} +0 -0
- /package/dist/{utilities-D7EYIATI.js.map → utilities-ARHQATQ6.js.map} +0 -0
- /package/dist/{workflow-cache-ZMYUGEPB.js.map → workflow-cache-PDLY7XLW.js.map} +0 -0
- /package/dist/{workflow-debug-LQKP27VI.js.map → workflow-debug-6IJQ5C3X.js.map} +0 -0
- /package/dist/{workflow-proposals-NEXXWL3O.js.map → workflow-proposals-MTHYBJGV.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../diagnostic-workspace/src/assemble-workspace.ts","../../diagnostic-workspace/src/_shared.ts","../../diagnostic-workspace/src/paths.ts","../../diagnostic-workspace/src/manifest-builder.ts","../../diagnostic-workspace/src/reported-failure-builder.ts","../../diagnostic-workspace/src/jsonl-writers.ts","../../diagnostic-workspace/src/workflow-writer.ts","../../diagnostic-workspace/src/sentry-writer.ts","../../diagnostic-workspace/src/trace-extractor.ts","../../diagnostic-workspace/src/screencast-extractor-writer.ts","../../diagnostic-workspace/src/ledger-builder.ts","../../diagnostic-workspace/src/step-rollup-builder.ts","../../diagnostic-workspace/src/summary-builder.ts"],"sourcesContent":["/**\n * Workspace Assembler — the package's main entry.\n *\n * Pure transform: takes a `RunData` JSON blob (produced by the data-fetch\n * layer on the server) plus a local trace.zip path, and writes the canonical\n * diagnostic workspace tree to disk.\n *\n * Both the server (in-process for the v2 agent) and the canary CLI (after\n * fetching `RunData` from the new `/debug/materialize-data` endpoint and\n * downloading the trace via signed URL) call this. Workspace shape is\n * literally the same code — no drift possible.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { computeStepWorkWindows, hostOf, NAVIGATION_ACTIONS } from './_shared.js';\nimport { resolveWorkspacePath, WORKSPACE_DIRS } from './paths.js';\nimport type { DiagnosticWorkspace } from './types.js';\nimport { writeManifest } from './manifest-builder.js';\nimport { writeReportedFailure } from './reported-failure-builder.js';\nimport {\n writeAssertionsAndCacheDecisions,\n writeCommittedActions,\n writeLogs,\n writeRecentRuns,\n writeThoughts,\n writeTimelineActionsAndNavigation,\n writeTimelineSteps,\n writeVariables,\n} from './jsonl-writers.js';\nimport { writeWorkflowDefinition } from './workflow-writer.js';\nimport { writeSentryLogsAndSpans } from './sentry-writer.js';\nimport { writeTrace } from './trace-extractor.js';\nimport { writeLedger } from './ledger-builder.js';\nimport { writeStepRollups } from './step-rollup-builder.js';\nimport { writeSummary, type GreenRunAccess } from './summary-builder.js';\nimport type { RunData } from './run-data.js';\n\nexport interface AssembleWorkspaceInput {\n runData: RunData;\n /** Absolute path to the workspace root (must already be writable). */\n workspaceRoot: string;\n /** Absolute path to a local trace.zip, or null if unavailable. */\n traceZipPath: string | null;\n /**\n * How this workspace's consumer materializes comparison runs — drives the\n * `summary.md` history hint. Defaults to `'cli'` (the CLI's behavior today);\n * the server passes `'agent-tool'` for the v2 agent's primary workspace.\n */\n greenRunAccess?: GreenRunAccess;\n}\n\n/**\n * Build the canonical workspace tree at `workspaceRoot` from `runData`.\n *\n * The caller is responsible for:\n * - Creating `workspaceRoot` (may be empty or pre-existing)\n * - Downloading the trace.zip and passing its path\n * - Cleaning up `workspaceRoot` after use (server: per-job tmp; CLI: --out)\n */\nexport const assembleWorkspace = async (\n input: AssembleWorkspaceInput,\n): Promise<DiagnosticWorkspace> => {\n const { runData, workspaceRoot, traceZipPath, greenRunAccess } = input;\n\n // Idempotent dir tree.\n await fs.mkdir(workspaceRoot, { recursive: true, mode: 0o700 });\n for (const dir of WORKSPACE_DIRS) {\n await fs.mkdir(resolveWorkspacePath(workspaceRoot, dir), { recursive: true, mode: 0o700 });\n }\n\n let partial = runData.partial;\n\n await writeReportedFailure({\n workspaceRoot,\n runStatus: runData.status,\n failedStepName: runData.failedStepName,\n failedStepOrderIndex: runData.failedStepOrderIndex,\n errorMessage: runData.errorMessage,\n });\n\n // JSONL writers — independent dumps.\n await Promise.all([\n writeTimelineSteps(workspaceRoot, runData.steps),\n writeTimelineActionsAndNavigation(workspaceRoot, runData.timeline),\n writeAssertionsAndCacheDecisions(workspaceRoot, runData.steps),\n writeThoughts(workspaceRoot, runData.thoughts),\n writeLogs(workspaceRoot, runData.networkLogs, runData.consoleLogs),\n writeCommittedActions(workspaceRoot, runData.committedActions ?? []),\n writeVariables(workspaceRoot, runData.metadataJson, runData.steps),\n writeRecentRuns(workspaceRoot, recentRunsToWriterShape(runData.recentRuns)),\n writeWorkflowDefinition({\n workspaceRoot,\n workflowId: runData.workflowId,\n workflowName: runData.workflowName,\n nodes: runData.nodes,\n edges: runData.edges,\n }),\n ]);\n\n const sentryPartial = await writeSentryLogsAndSpans({\n workspaceRoot,\n logs: runData.sentryLogs,\n spans: runData.sentrySpans,\n });\n if (sentryPartial) partial = true;\n\n // Composed surfaces — depend on the JSONL streams above being on disk\n // (or, more accurately, on the same in-memory event projection). Computed\n // before the trace write so the screencast filmstrip can be densified around\n // step boundaries and the failure window.\n const eventProjection = projectEvents(runData);\n\n // Absolute ms of each step-started/step-completed annotation — the screencast\n // writer keeps the nearest frame to each so cached/playbook sub-step\n // transitions stay visible.\n const stepBoundaryMs = eventProjection.actions\n .filter(\n (a): a is typeof a & { timestampMs: number } =>\n a.isAnnotation &&\n a.timestampMs !== null &&\n (a.target === 'step-started' || a.target === 'step-completed'),\n )\n .map((a) => a.timestampMs);\n\n // The failed step's true work window (widened for cached/playbook steps) — kept\n // at full screencast density so the failing moment always has real pixels.\n const workWindows = computeStepWorkWindows(eventProjection.steps, eventProjection.actions);\n const failedStepProjected = runData.failedStepId\n ? eventProjection.steps.find((s) => s.id === runData.failedStepId)\n : undefined;\n const failureWindow = failedStepProjected\n ? workWindows.get(failedStepProjected.id) ??\n (failedStepProjected.startedAtMs !== null && failedStepProjected.finishedAtMs !== null\n ? { startMs: failedStepProjected.startedAtMs, endMs: failedStepProjected.finishedAtMs }\n : null)\n : null;\n\n const traceResult = await writeTrace({\n workspaceRoot,\n traceZipPath,\n runStartedAtMs: runData.startedAt ? Date.parse(runData.startedAt) : null,\n stepBoundaryMs,\n failureWindow,\n });\n if (traceResult.partial) partial = true;\n\n await writeLedger({\n workspaceRoot,\n runId: runData.runId,\n workflowId: runData.workflowId,\n workflowName: runData.workflowName,\n runStatus: runData.status,\n runStartedAt: runData.startedAt,\n reportedFailure: {\n failedStepName: runData.failedStepName,\n failedStepOrderIndex: runData.failedStepOrderIndex,\n errorMessage: runData.errorMessage,\n },\n steps: eventProjection.steps,\n thoughts: eventProjection.thoughts,\n actions: eventProjection.actions,\n navigation: eventProjection.navigation,\n network: eventProjection.network,\n consoleLogs: eventProjection.consoleLogs,\n assertions: eventProjection.assertions,\n });\n\n await writeStepRollups({\n workspaceRoot,\n runStartedAt: runData.startedAt,\n steps: eventProjection.steps,\n thoughts: eventProjection.thoughts,\n actions: eventProjection.actions,\n navigation: eventProjection.navigation,\n network: eventProjection.network,\n consoleLogs: eventProjection.consoleLogs,\n assertions: eventProjection.assertions,\n screencastFrames: traceResult.screencastFrames.map((f) => ({\n timestampMs: f.timestampMs,\n pageId: f.pageId,\n file: f.file,\n keptReason: f.keptReason,\n })),\n });\n\n await writeSummary({\n workspaceRoot,\n runId: runData.runId,\n workflowName: runData.workflowName,\n runStatus: runData.status,\n runStartedAt: runData.startedAt,\n runFinishedAt: runData.finishedAt,\n reportedFailure: {\n failedStepId: runData.failedStepId,\n failedStepName: runData.failedStepName,\n failedStepOrderIndex: runData.failedStepOrderIndex,\n errorMessage: runData.errorMessage,\n },\n steps: eventProjection.steps.map((s) => ({\n id: s.id,\n orderIndex: s.orderIndex,\n name: s.name,\n status: s.status,\n startedAtMs: s.startedAtMs,\n durationMs: s.durationMs,\n cacheOutcome: s.cacheOutcome,\n cacheHitSource: s.cacheHitSource,\n cacheOutcomeReason: s.cacheOutcomeReason,\n cacheFailureCategory: s.cacheFailureCategory,\n variablesSet: s.variablesSet,\n thoughtCount: s.thoughtCount,\n domProbeCount: s.domProbeCount,\n errorMessage: s.errorMessage,\n })),\n // Variable keys the failing step's node config references (`$var.X`) — drives the\n // upstream-divergence lineage heuristic. Empty when no failed node / no references.\n failedStepReferencedVars: runData.failedNodeId\n ? extractReferencedVarKeys(\n runData.nodes.find((n) => n.id === runData.failedNodeId)?.configJson,\n )\n : [],\n network: eventProjection.network,\n consoleLogs: eventProjection.consoleLogs,\n navigation: eventProjection.navigation,\n // Mid-run browser crashes (auto-recovered) — annotation entries on the timeline\n // carry the human label in `action` and `crash-recovery` in `annotationType`.\n crashes: runData.timeline.entries\n .filter((e) => e.isAnnotation && e.annotationType === 'crash-recovery')\n .map((e) => ({ label: e.action, relativeTimestampMs: e.timestampMs })),\n recentRuns: runData.recentRuns,\n seedRuns: runData.seedRuns ?? [],\n lastGreenComparison: runData.lastGreenComparison,\n greenRunAccess,\n });\n\n await writeManifest({\n workspaceRoot,\n runId: runData.runId,\n workflowId: runData.workflowId,\n orgId: runData.orgId,\n status: runData.status,\n startedAt: runData.startedAt,\n finishedAt: runData.finishedAt,\n errorMessage: runData.errorMessage,\n workflowName: runData.workflowName,\n failedStepId: runData.failedStepId,\n failedNodeId: runData.failedNodeId,\n failedStepName: runData.failedStepName,\n traceStorageKey: runData.traceStorageKey,\n diagnosticsStorageKey: runData.diagnosticsStorageKey,\n videoStorageKey: runData.videoStorageKey,\n partial,\n });\n\n return {\n root: workspaceRoot,\n runId: runData.runId,\n orgId: runData.orgId,\n materializedAt: new Date().toISOString(),\n runStartedAt: runData.startedAt,\n runStatus: runData.status,\n lastGreenRunId: runData.lastGreenComparison?.greenRunId ?? null,\n };\n};\n\n// ============================================================================\n// Event projection — same shape used by ledger + step-rollup + summary.\n// ============================================================================\n\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === 'object' && !Array.isArray(v);\n\n/**\n * Extract the `$var.<key>` variable keys referenced anywhere in a node's config.\n * Used by the upstream-divergence lineage heuristic: when the failing step depends\n * on a `$var.X` produced by an earlier extractor step, that producer is a candidate.\n * Domain-agnostic — pure data-flow over whatever the node config happens to contain.\n *\n * Mirrors the canonical `VARIABLE_PATTERN` (@chatsdet/types/macros): a reference may be\n * simple (`$var.test_id`) or step-qualified (`$var.Step2_Create.client_id`). We collect\n * EVERY dotted segment so a `variablesSet[].key` (always a simple name) matches whether\n * it is the leaf of a qualified ref or the whole of a simple one. Over-collecting a step\n * qualifier is harmless here — this only seeds candidate hints, never a verdict.\n */\nconst VAR_REFERENCE_RE = /\\$var\\.(\\w+(?:\\.\\w+)*)/g;\nconst extractReferencedVarKeys = (configJson: unknown): string[] => {\n if (configJson === null || configJson === undefined) return [];\n let serialized: string;\n try {\n serialized = typeof configJson === 'string' ? configJson : JSON.stringify(configJson);\n } catch {\n // A malformed/cyclic config must not crash whole-workspace assembly — just skip the hint.\n return [];\n }\n if (!serialized) return [];\n const keys = new Set<string>();\n for (const m of serialized.matchAll(VAR_REFERENCE_RE)) {\n const path = m[1];\n if (!path) continue;\n for (const segment of path.split('.')) {\n if (segment) keys.add(segment);\n }\n }\n return [...keys];\n};\n\nconst stringField = (v: unknown): string | null =>\n typeof v === 'string' && v.length > 0 ? v : null;\n\nconst normalizeTs = (ts: number | string | null | undefined): number | null => {\n if (ts === null || ts === undefined) return null;\n if (typeof ts === 'number') return ts;\n const parsed = Date.parse(ts);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\n/**\n * Tool names that count as a \"DOM probe\" — the agent reading the page directly\n * (vs. the structured snapshot) to find or verify an element. A high probe count\n * on a non-failed step is a signal it struggled to act, even when it reported\n * success. Used by the upstream-divergence churn heuristic.\n */\nconst DOM_PROBE_TOOL_NAMES = new Set(['browser_run_code', 'browser_evaluate']);\n\n/** A variable a step set — projected for the upstream-divergence lineage heuristic. */\ninterface ProjectedVariableSet {\n key: string;\n value: string | null;\n /** 'inputValue' (configured) | 'extracted' (read from the page) | other. */\n source: string | null;\n /** True when the value was extracted from the live page (carries an extractor). */\n extracted: boolean;\n}\n\nconst projectVariablesSet = (meta: Record<string, unknown>): ProjectedVariableSet[] => {\n const raw = Array.isArray(meta.variablesSet) ? meta.variablesSet : [];\n const out: ProjectedVariableSet[] = [];\n for (const c of raw) {\n if (!isPlainObject(c)) continue;\n const key = stringField(c.key) ?? stringField(c.name);\n if (!key) continue;\n const source = stringField(c.source);\n out.push({\n key,\n value: typeof c.value === 'string' ? c.value : null,\n source,\n extracted: source === 'extracted' || typeof c.extractorExpression === 'string',\n });\n }\n return out;\n};\n\nconst projectEvents = (runData: RunData) => {\n const baselineMs = runData.timeline.startTimestamp\n ? Date.parse(runData.timeline.startTimestamp)\n : null;\n\n const thoughts = runData.thoughts.map((t) => ({\n stepId: t.stepId,\n timestampMs: Date.parse(t.createdAt),\n toolName: t.toolName,\n content: t.content,\n }));\n\n // Per-step churn signal: total thoughts and how many were direct DOM probes.\n // Bucketed once here so the summary's upstream-divergence heuristic can flag a\n // non-failed step that thrashed (high churn + repeated probing) yet reported success.\n const thoughtStatsByStep = new Map<string, { thoughtCount: number; domProbeCount: number }>();\n for (const t of thoughts) {\n if (!t.stepId) continue;\n const cur = thoughtStatsByStep.get(t.stepId) ?? { thoughtCount: 0, domProbeCount: 0 };\n cur.thoughtCount += 1;\n if (t.toolName && DOM_PROBE_TOOL_NAMES.has(t.toolName)) cur.domProbeCount += 1;\n thoughtStatsByStep.set(t.stepId, cur);\n }\n\n const steps = runData.steps.map((s) => {\n const meta = isPlainObject(s.metadataJson) ? s.metadataJson : {};\n const startedAtMs = s.startedAt ? Date.parse(s.startedAt) : null;\n const finishedAtMs = s.finishedAt ? Date.parse(s.finishedAt) : null;\n const churn = thoughtStatsByStep.get(s.id) ?? { thoughtCount: 0, domProbeCount: 0 };\n return {\n id: s.id,\n nodeId: s.nodeId,\n orderIndex: s.orderIndex,\n name: s.nodeName,\n nodeType: s.nodeType,\n status: s.status,\n startedAtMs,\n finishedAtMs,\n durationMs:\n startedAtMs !== null && finishedAtMs !== null ? finishedAtMs - startedAtMs : null,\n errorMessage: s.errorMessage,\n cacheOutcome: stringField(meta.cacheOutcome),\n cacheHitSource: stringField(meta.cacheHitSource),\n cacheOutcomeReason: stringField(meta.cacheOutcomeReason),\n cacheFailureCategory: stringField(meta.cacheFailureCategory),\n variablesSet: projectVariablesSet(meta),\n thoughtCount: churn.thoughtCount,\n domProbeCount: churn.domProbeCount,\n };\n });\n\n const actions = runData.timeline.entries.map((e) => ({\n action: e.action,\n target: e.target ?? null,\n url: e.url ?? null,\n timestampMs: baselineMs !== null ? baselineMs + e.timestampMs : null,\n success: e.success,\n isAnnotation: e.isAnnotation ?? false,\n }));\n\n const navigation: Array<{\n timestampMs: number | null;\n action: string;\n from: string | null;\n to: string | null;\n crossHost: boolean;\n }> = [];\n let prevUrl: string | null = null;\n for (const a of actions) {\n const isNav = NAVIGATION_ACTIONS.has(a.action);\n const urlChanged = a.url !== null && prevUrl !== null && a.url !== prevUrl;\n if (!isNav && !urlChanged) {\n if (a.url) prevUrl = a.url;\n continue;\n }\n navigation.push({\n timestampMs: a.timestampMs,\n action: a.action,\n from: prevUrl,\n to: a.url,\n crossHost:\n hostOf(prevUrl) !== null && hostOf(a.url) !== null && hostOf(prevUrl) !== hostOf(a.url),\n });\n if (a.url) prevUrl = a.url;\n }\n\n const network = runData.networkLogs.map((n) => ({\n timestampMs: normalizeTs(n.timestamp ?? null),\n url: n.url,\n method: n.method,\n status: n.status ?? null,\n }));\n\n const consoleLogs = runData.consoleLogs.map((c) => ({\n timestampMs: normalizeTs(c.timestamp),\n type: c.type,\n text: c.text,\n }));\n\n const assertions: Array<{\n stepId: string;\n timestampMs: number | null;\n condition: string | null;\n severity: string | null;\n nonBlocking: boolean;\n passed: boolean;\n reason: string | null;\n }> = [];\n for (const s of runData.steps) {\n const meta = isPlainObject(s.metadataJson) ? s.metadataJson : {};\n const raw = Array.isArray(meta.assertionResults) ? meta.assertionResults : [];\n for (const r of raw) {\n if (!isPlainObject(r)) continue;\n assertions.push({\n stepId: s.id,\n timestampMs: s.startedAt ? Date.parse(s.startedAt) : null,\n condition: stringField(r.condition),\n severity: stringField(r.severity),\n nonBlocking: Boolean(r.nonBlocking),\n passed: Boolean(r.passed),\n reason: stringField(r.reason),\n });\n }\n }\n\n return { steps, thoughts, actions, navigation, network, consoleLogs, assertions };\n};\n\nconst recentRunsToWriterShape = (\n runs: ReadonlyArray<RunData['recentRuns'][number]>,\n) =>\n runs.map((r) => ({\n id: r.testRunId,\n workflowRunId: r.workflowRunId,\n status: r.status,\n startedAt: r.startedAt,\n finishedAt: r.finishedAt,\n errorMessage: r.errorMessage,\n }));\n","/**\n * Shared internal helpers for the workspace builders.\n *\n * Time formatting (`formatRelative`, `formatAbsolute`, `formatPrefix`) and the\n * navigation-event derivation (`NAVIGATION_ACTIONS`, `hostOf`) live here so the\n * ledger, per-step rollup, summary, and JSONL writers all agree on the format\n * and the rules. Avoids the dual-validator drift pattern.\n */\n\n/** Set of action `type` strings that count as a navigation event. */\nexport const NAVIGATION_ACTIONS = new Set([\n 'navigate',\n 'navigation',\n 'pushstate',\n 'popstate',\n 'pushState',\n 'popState',\n 'redirect',\n 'load',\n]);\n\n/**\n * Extract a normalized hostname from a URL, lowercased and stripped of `www.`.\n * Returns null on invalid input. Used to detect cross-host transitions\n * consistently across builders.\n */\nexport const hostOf = (raw: unknown): string | null => {\n if (typeof raw !== 'string' || raw.length === 0) return null;\n try {\n return new URL(raw).hostname.toLowerCase().replace(/^www\\./, '');\n } catch {\n return null;\n }\n};\n\n/**\n * Format a duration as `T+S.SSSs` / `T-S.SSSs` relative to a baseline.\n * Used in ledger lines, per-step rollups, and summary step rows.\n */\nexport const formatRelative = (ms: number): string => {\n const sign = ms < 0 ? '-' : '+';\n const abs = Math.abs(ms);\n const seconds = Math.floor(abs / 1000);\n const millis = abs % 1000;\n return `T${sign}${seconds}.${String(millis).padStart(3, '0')}s`;\n};\n\n/** Format an absolute wall-clock timestamp as `HH:MM:SS.mmm` in UTC. */\nexport const formatAbsolute = (ms: number): string => {\n const d = new Date(ms);\n const hh = String(d.getUTCHours()).padStart(2, '0');\n const mm = String(d.getUTCMinutes()).padStart(2, '0');\n const ss = String(d.getUTCSeconds()).padStart(2, '0');\n const mil = String(d.getUTCMilliseconds()).padStart(3, '0');\n return `${hh}:${mm}:${ss}.${mil}`;\n};\n\n/**\n * Format a timestamp prefix with both relative and absolute times, suitable\n * for ledger lines and per-step rollup events. Falls back to `[unknown @ unknown]`\n * when timestamps are unknown.\n */\nexport const formatPrefix = (\n timestampMs: number | null,\n baselineMs: number | null,\n): string => {\n if (timestampMs === null) return '[unknown @ unknown]';\n const rel = baselineMs !== null ? formatRelative(timestampMs - baselineMs) : 'T+?';\n const abs = formatAbsolute(timestampMs);\n return `[${rel} @ ${abs}]`;\n};\n\n/** Collapse whitespace runs to single spaces and trim. */\nexport const oneLine = (s: string): string => s.replace(/\\s+/g, ' ').trim();\n\n// ============================================================================\n// Step work windows\n// ============================================================================\n\n/** A step's true execution window in absolute ms. */\nexport interface StepWorkWindow {\n startMs: number;\n endMs: number;\n}\n\n/** Minimal step shape needed to compute work windows. */\ninterface WorkWindowStep {\n id: string;\n orderIndex: number;\n startedAtMs: number | null;\n finishedAtMs: number | null;\n}\n\n/** Minimal action shape needed to compute work windows. */\ninterface WorkWindowAction {\n /** For annotations, the human label (step name); otherwise the action type. */\n action: string;\n /** For annotations, the classifier (`step-started` / `step-completed` / …). */\n target: string | null;\n timestampMs: number | null;\n isAnnotation: boolean;\n}\n\n/**\n * A step record's `startedAt`/`finishedAt` may only reflect the *commit* moment\n * (e.g. a cache/playbook step whose row is written when the step finalizes),\n * while the real browser work ran earlier under the step's\n * `step-started`→`step-completed` annotation bracket. Windowing untyped events\n * (actions, nav, network, console) by the record bounds then drops all the real\n * work into a dead zone — invisible in the step's rollup and mis-grouped in the\n * ledger.\n *\n * This pairs consecutive `step-started`/`step-completed` annotations into ordered\n * brackets and matches each, in execution order, to the step whose `finishedAtMs`\n * lands within `toleranceMs` of the bracket's completion (the record commits ≈ at\n * `step-completed`). A matched step's work window widens to cover both the record\n * bounds and the bracket. Steps with no matching bracket (login/setup, or runs\n * without these annotations) are absent from the map — callers fall back to the\n * record bounds, preserving existing behavior when the signal is absent.\n */\nexport const computeStepWorkWindows = (\n steps: ReadonlyArray<WorkWindowStep>,\n actions: ReadonlyArray<WorkWindowAction>,\n toleranceMs = 2000,\n): Map<string, StepWorkWindow> => {\n // Ordered (step-started, step-completed) brackets from the annotation stream.\n const sortedAnnotations = actions\n .filter(\n (a): a is WorkWindowAction & { timestampMs: number } =>\n a.isAnnotation && a.timestampMs !== null,\n )\n .slice()\n .sort((a, b) => a.timestampMs - b.timestampMs);\n\n const brackets: Array<{ startMs: number; endMs: number }> = [];\n let openStartMs: number | null = null;\n for (const a of sortedAnnotations) {\n if (a.target === 'step-started') {\n openStartMs = a.timestampMs;\n } else if (a.target === 'step-completed' && openStartMs !== null) {\n brackets.push({ startMs: openStartMs, endMs: a.timestampMs });\n openStartMs = null;\n }\n }\n\n const stepsByOrder = steps\n .slice()\n .sort((a, b) => a.orderIndex - b.orderIndex);\n\n const windows = new Map<string, StepWorkWindow>();\n let stepCursor = 0;\n for (const bracket of brackets) {\n // Advance past steps that finished well before this bracket completed (they\n // own no bracket — keep their record bounds) and steps with no finish time.\n while (stepCursor < stepsByOrder.length) {\n const step = stepsByOrder[stepCursor]!;\n if (step.finishedAtMs === null) {\n stepCursor++;\n continue;\n }\n if (step.finishedAtMs < bracket.endMs - toleranceMs) {\n stepCursor++;\n continue;\n }\n break;\n }\n const step = stepsByOrder[stepCursor];\n if (\n step !== undefined &&\n step.finishedAtMs !== null &&\n Math.abs(step.finishedAtMs - bracket.endMs) <= toleranceMs\n ) {\n const recordStart = step.startedAtMs ?? bracket.startMs;\n windows.set(step.id, {\n startMs: Math.min(recordStart, bracket.startMs),\n endMs: Math.max(step.finishedAtMs, bracket.endMs),\n });\n stepCursor++;\n }\n // Otherwise this bracket has no step within tolerance — skip it, keep the cursor.\n }\n\n return windows;\n};\n\n/** Truncate to at most `max` characters, appending `…` when needed. */\nexport const truncate = (s: string, max: number): string =>\n s.length <= max ? s : `${s.slice(0, max - 1)}…`;\n\n// ============================================================================\n// Trace clock — one absolute axis for actions and screencast frames\n// ============================================================================\n\n/** Minimal action shape the trace clock needs. */\ninterface TraceClockAction {\n startTime: number;\n wallTime?: number;\n}\n\n/**\n * The diagnostic workspace places every browser artifact on one absolute-ms\n * axis anchored at the run's start. Trace actions carry two clocks:\n *\n * - `startTime` — a monotonic process clock that RESTARTS per browser segment.\n * The legacy `runStartedAtMs + (startTime - startTime[0])` math is only\n * correct for single-segment traces; a stitched multi-segment trace skews.\n * - `wallTime` — wall-clock epoch ms, segment-stable, and the SAME clock the\n * screencast `frameSwapWallTime` uses.\n *\n * `makeTraceClock` anchors both actions and screencast frames to the run-start\n * axis via wall time, so frames drop into the exact same `timestampMs` space the\n * ledger/rollups/`inWindow` already use — no cross-clock arithmetic for readers.\n * When the first action lacks `wallTime` (older/partial traces), it falls back\n * to the monotonic anchor and reports `approxAlignment = true`, which callers\n * surface so the screencast index is honestly marked.\n */\nexport interface TraceClock {\n /** Map a wall-clock epoch ms (action.wallTime / frame.frameSwapWallTime) to the run axis. */\n absFromWall: (wallMs: number) => number;\n /** Map a trace action to the run axis (wall when present, monotonic fallback otherwise). */\n absFromAction: (action: TraceClockAction) => number;\n /** True when no wall-clock anchor was available; screencast alignment is approximate. */\n approxAlignment: boolean;\n}\n\nexport const makeTraceClock = (\n actions: ReadonlyArray<TraceClockAction>,\n runStartedAtMs: number | null,\n): TraceClock => {\n const base = runStartedAtMs ?? 0;\n const first = actions[0];\n const wallAnchor =\n first && typeof first.wallTime === 'number' ? first.wallTime : null;\n const monoAnchor = first ? first.startTime : 0;\n\n if (wallAnchor !== null) {\n const absFromWall = (wallMs: number): number => base + (wallMs - wallAnchor);\n return {\n absFromWall,\n absFromAction: (action) =>\n typeof action.wallTime === 'number'\n ? absFromWall(action.wallTime)\n : base + (action.startTime - monoAnchor),\n approxAlignment: false,\n };\n }\n\n // No wall anchor (no action carried wallTime). Actions fall back to the\n // monotonic clock. Screencast `frameSwapWallTime` is already an absolute epoch\n // (and the run started at ~`base`, also an epoch), so the frame's wall time is\n // its own best absolute position — return it as-is. Both lanes then sit at\n // ≈epoch scale and stay mutually coherent, but the alignment is approximate.\n return {\n absFromWall: (wallMs: number) => wallMs,\n absFromAction: (action) => base + (action.startTime - monoAnchor),\n approxAlignment: true,\n };\n};\n","/**\n * Workspace Path Conventions\n *\n * @module workflows/diagnostics/materialize/paths\n * @description Single source of truth for the relative paths inside a diagnostic workspace.\n * Every builder writes through these helpers; every reader (agent prompt, CLI subcommands)\n * uses these constants. Renaming a path is a one-file change.\n */\n\nimport * as path from 'node:path';\n\nexport const WORKSPACE_PATHS = {\n manifest: 'manifest.json',\n reportedFailure: 'reported-failure.md',\n summary: 'summary.md',\n ledger: 'ledger.md',\n ledgerIndex: 'ledger-index.md',\n\n steps: 'steps', // steps/<NNN>-<stepId>.md\n\n timeline: 'timeline',\n timelineSteps: 'timeline/steps.jsonl',\n timelineActions: 'timeline/actions.jsonl',\n timelineNavigation: 'timeline/navigation.jsonl',\n timelineAssertions: 'timeline/assertions.jsonl',\n timelineCacheDecisions: 'timeline/cache-decisions.jsonl',\n\n thoughts: 'thoughts',\n thoughtsAll: 'thoughts/all.jsonl',\n thoughtsByStep: 'thoughts/by-step', // thoughts/by-step/<stepId>.md\n\n browser: 'browser',\n browserTraceZip: 'browser/trace.zip',\n browserActions: 'browser/actions.jsonl',\n browserDoms: 'browser/doms', // browser/doms/<NNNN>-<timestamp>.html\n browserFrames: 'browser/frames', // browser/frames/<NNNN>-<timestamp>.png\n browserA11y: 'browser/a11y', // browser/a11y/<NNNN>-<timestamp>.yaml\n browserResources: 'browser/resources',\n // Continuous screencast filmstrip — real pixels at every moment, including\n // evaluate/wait moments where there is no per-action DOM-snapshot frame.\n browserScreencast: 'browser/screencast', // browser/screencast/<NNNN>-<timestamp>.jpg\n browserScreencastIndex: 'browser/screencast/index.jsonl',\n\n logs: 'logs',\n logsNetwork: 'logs/network.jsonl',\n logsNetworkErrors: 'logs/network-errors.jsonl',\n logsConsole: 'logs/console.jsonl',\n logsConsoleErrors: 'logs/console-errors.jsonl',\n logsSentry: 'logs/sentry-logs.jsonl',\n logsSentrySpans: 'logs/sentry-spans.jsonl',\n\n // Mutations a prior cache/L2 layer already committed (cache_replay:* / l2_playbook:*).\n committedActions: 'committed-actions.md',\n committedActionsJsonl: 'committed-actions.jsonl',\n\n workflow: 'workflow',\n workflowDefinition: 'workflow/definition.json',\n workflowSnapshot: 'workflow/snapshot.json',\n workflowNodes: 'workflow/nodes', // workflow/nodes/<nodeId>.json\n\n variables: 'variables',\n variablesInputs: 'variables/inputs.json',\n variablesLineage: 'variables/lineage.jsonl',\n\n history: 'history',\n historyRecentRuns: 'history/recent-runs.jsonl',\n historyLastGreen: 'history/last-green', // CLI-only: `canary workflow debug materialize --out` target\n historyRuns: 'history/runs', // agent-only: history/runs/<runId>/ — comparison workspaces from materialize_run\n\n notes: 'notes',\n} as const;\n\n/** Subdirectories created up-front (idempotent) so builders can write files without mkdir-ing each time. */\nexport const WORKSPACE_DIRS: ReadonlyArray<string> = [\n WORKSPACE_PATHS.steps,\n WORKSPACE_PATHS.timeline,\n WORKSPACE_PATHS.thoughts,\n WORKSPACE_PATHS.thoughtsByStep,\n WORKSPACE_PATHS.browser,\n WORKSPACE_PATHS.browserDoms,\n WORKSPACE_PATHS.browserFrames,\n WORKSPACE_PATHS.browserA11y,\n WORKSPACE_PATHS.browserResources,\n WORKSPACE_PATHS.browserScreencast,\n WORKSPACE_PATHS.logs,\n WORKSPACE_PATHS.workflow,\n WORKSPACE_PATHS.workflowNodes,\n WORKSPACE_PATHS.variables,\n WORKSPACE_PATHS.history,\n WORKSPACE_PATHS.notes,\n];\n\n/** Resolve a workspace-relative path to an absolute path under the workspace root. */\nexport const resolveWorkspacePath = (root: string, relative: string): string =>\n path.join(root, relative);\n\n/** Build the per-step rollup filename: `steps/003-<stepId>.md`. */\nexport const stepRollupRelativePath = (orderIndex: number, stepId: string): string =>\n path.join(WORKSPACE_PATHS.steps, `${String(orderIndex).padStart(3, '0')}-${stepId}.md`);\n\n/** Build the per-step thoughts filename: `thoughts/by-step/<stepId>.md`. */\nexport const thoughtsByStepRelativePath = (stepId: string): string =>\n path.join(WORKSPACE_PATHS.thoughtsByStep, `${stepId}.md`);\n\n/** Build the per-node config filename: `workflow/nodes/<nodeId>.json`. */\nexport const workflowNodeRelativePath = (nodeId: string): string =>\n path.join(WORKSPACE_PATHS.workflowNodes, `${nodeId}.json`);\n\n/** Build the per-action artifact filename: `<NNNN>-<absoluteTsMs>.<ext>`. */\nexport const actionArtifactBasename = (\n actionIndex: number,\n absoluteTsMs: number,\n ext: 'html' | 'png' | 'yaml',\n): string => `${String(actionIndex).padStart(4, '0')}-${absoluteTsMs}.${ext}`;\n\n/** Build the per-frame screencast filename: `<NNNN>-<absoluteTsMs>.jpg`. */\nexport const screencastFrameBasename = (frameIndex: number, absoluteTsMs: number): string =>\n `${String(frameIndex).padStart(4, '0')}-${absoluteTsMs}.jpg`;\n","/**\n * Manifest Builder\n *\n * @module @chatsdet/diagnostic-workspace/manifest-builder\n * @description Writes `manifest.json` — the workspace's machine-readable metadata file.\n * The `runStartedAt` field is the canonical baseline for every `T+S.SSSs` relative\n * timestamp in the ledger and per-step rollups.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { resolveWorkspacePath, WORKSPACE_PATHS } from './paths.js';\nimport type { WorkspaceManifest } from './types.js';\n\nexport interface ManifestBuilderInput {\n workspaceRoot: string;\n runId: string;\n workflowId: string;\n orgId: string;\n status: string;\n /** ISO timestamp or null. */\n startedAt: string | null;\n /** ISO timestamp or null. */\n finishedAt: string | null;\n errorMessage: string | null;\n workflowName: string;\n failedStepId: string | null;\n failedNodeId: string | null;\n failedStepName: string | null;\n traceStorageKey: string | null;\n diagnosticsStorageKey: string | null;\n videoStorageKey: string | null;\n partial: boolean;\n}\n\nexport const writeManifest = async (input: ManifestBuilderInput): Promise<WorkspaceManifest> => {\n const startedMs = input.startedAt ? Date.parse(input.startedAt) : null;\n const finishedMs = input.finishedAt ? Date.parse(input.finishedAt) : null;\n const durationMs =\n startedMs !== null && finishedMs !== null ? finishedMs - startedMs : null;\n\n const manifest: WorkspaceManifest = {\n runId: input.runId,\n workflowId: input.workflowId,\n orgId: input.orgId,\n status: input.status,\n startedAt: input.startedAt,\n finishedAt: input.finishedAt,\n durationMs,\n errorMessage: input.errorMessage,\n workflowName: input.workflowName,\n failedStepId: input.failedStepId,\n failedNodeId: input.failedNodeId,\n failedStepName: input.failedStepName,\n traceStorageKey: input.traceStorageKey,\n diagnosticsStorageKey: input.diagnosticsStorageKey,\n videoStorageKey: input.videoStorageKey,\n materializedAt: new Date().toISOString(),\n partial: input.partial,\n };\n\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.manifest),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n 'utf-8',\n );\n\n return manifest;\n};\n","/**\n * Reported-Failure Builder\n *\n * @module @chatsdet/diagnostic-workspace/reported-failure-builder\n * @description Writes `reported-failure.md` — the test runner's hypothesis about what\n * failed. Treated as a hypothesis to verify, not a fact, by the diagnostic agent's\n * procedural prompt. Always includes the explicit \"verify before trusting\" header.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { resolveWorkspacePath, WORKSPACE_PATHS } from './paths.js';\n\nexport interface ReportedFailureInput {\n workspaceRoot: string;\n runStatus: string;\n failedStepName: string | null;\n failedStepOrderIndex: number | null;\n errorMessage: string | null;\n}\n\nexport const writeReportedFailure = async (input: ReportedFailureInput): Promise<void> => {\n const lines: string[] = [];\n lines.push('# Reported Failure');\n lines.push('');\n lines.push(\n '**This is the test runner\\'s hypothesis. Verify with evidence before trusting it — the root cause is often upstream of the visible failure.**',\n );\n lines.push('');\n lines.push(`Run status: \\`${input.runStatus}\\``);\n lines.push('');\n\n if (input.runStatus !== 'failed') {\n lines.push(\n `> The run did not end in a \\`failed\\` status. The test runner did not designate a failed step.`,\n );\n lines.push('');\n } else if (!input.failedStepName) {\n lines.push(\n `> The run is \\`failed\\` but no failed step was identified. Investigate the run-level error message and walk the timeline.`,\n );\n lines.push('');\n } else {\n const ordinal = input.failedStepOrderIndex !== null ? ` (step ${input.failedStepOrderIndex})` : '';\n lines.push(`Failed step${ordinal}: **${input.failedStepName}**`);\n lines.push('');\n }\n\n if (input.errorMessage) {\n lines.push('## Error message');\n lines.push('');\n lines.push('```');\n lines.push(input.errorMessage);\n lines.push('```');\n lines.push('');\n }\n\n lines.push('## What to do next');\n lines.push('');\n lines.push(\n '1. Read `summary.md` for the run-level overview and step table.',\n );\n lines.push(\n '2. Open the failed step\\'s rollup at `steps/<NNN>-<stepId>.md` to gather evidence at the failure point.',\n );\n lines.push(\n '3. Walk backwards through prior `steps/*.md` rollups — the divergence often happens upstream.',\n );\n lines.push('');\n\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.reportedFailure),\n `${lines.join('\\n')}\\n`,\n 'utf-8',\n );\n};\n","/**\n * JSONL Writers\n *\n * @module @chatsdet/diagnostic-workspace/jsonl-writers\n * @description Dump per-domain data to JSONL files in the workspace. Minimal transformation\n * — the agent uses `jq` to filter. Each writer is independent and idempotent.\n *\n * Inputs use ISO timestamp strings (matching the `RunData` JSON contract); writers convert\n * to ms internally where needed.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { hostOf, NAVIGATION_ACTIONS } from './_shared.js';\nimport {\n resolveWorkspacePath,\n thoughtsByStepRelativePath,\n WORKSPACE_PATHS,\n} from './paths.js';\n\nconst writeJsonl = (absolutePath: string, lines: ReadonlyArray<unknown>): Promise<void> =>\n fs.writeFile(\n absolutePath,\n lines.length === 0 ? '' : `${lines.map((l) => JSON.stringify(l)).join('\\n')}\\n`,\n 'utf-8',\n );\n\nconst writeJson = (absolutePath: string, value: unknown): Promise<void> =>\n fs.writeFile(absolutePath, `${JSON.stringify(value, null, 2)}\\n`, 'utf-8');\n\nconst writeText = (absolutePath: string, text: string): Promise<void> =>\n fs.writeFile(absolutePath, text, 'utf-8');\n\nconst isoToMs = (iso: string | null): number | null => {\n if (!iso) return null;\n const parsed = Date.parse(iso);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nconst isObject = (v: unknown): v is Record<string, unknown> =>\n v !== null && typeof v === 'object' && !Array.isArray(v);\n\n// ============================================================================\n// timeline/steps.jsonl\n// ============================================================================\n\nexport interface RunStepLike {\n id: string;\n nodeId: string;\n status: string;\n startedAt: string | null;\n finishedAt: string | null;\n errorMessage: string | null;\n orderIndex: number;\n metadataJson: Record<string, unknown> | null | unknown;\n /** Human-readable name resolved from the workflow node. Caller computes this. */\n nodeName: string | null;\n /** Node type from the workflow definition. Caller resolves this. */\n nodeType: string | null;\n}\n\nexport const writeTimelineSteps = async (\n workspaceRoot: string,\n steps: ReadonlyArray<RunStepLike>,\n): Promise<void> => {\n const lines = steps\n .slice()\n .sort((a, b) => a.orderIndex - b.orderIndex)\n .map((step) => {\n const meta = isObject(step.metadataJson) ? step.metadataJson : {};\n const startedMs = isoToMs(step.startedAt);\n const finishedMs = isoToMs(step.finishedAt);\n return {\n id: step.id,\n nodeId: step.nodeId,\n orderIndex: step.orderIndex,\n name: step.nodeName,\n nodeType: step.nodeType,\n status: step.status,\n startedAt: step.startedAt,\n finishedAt: step.finishedAt,\n startedAtMs: startedMs,\n finishedAtMs: finishedMs,\n durationMs:\n startedMs !== null && finishedMs !== null ? finishedMs - startedMs : null,\n errorMessage: step.errorMessage,\n cacheOutcome: meta.cacheOutcome ?? null,\n cacheHitSource: meta.cacheHitSource ?? null,\n cacheProcessingStatus: meta.cacheProcessingStatus ?? null,\n cacheOutcomeReason: meta.cacheOutcomeReason ?? null,\n };\n });\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.timelineSteps),\n lines,\n );\n};\n\n// ============================================================================\n// timeline/actions.jsonl + navigation.jsonl\n// ============================================================================\n\nexport interface ActionTimelineEntry {\n action: string;\n target?: string;\n value?: string;\n url?: string;\n /** Relative ms from `startTimestamp`. */\n timestampMs: number;\n success: boolean;\n isAnnotation?: boolean;\n /** Annotation classifier (e.g. `crash-recovery`) when `isAnnotation` is true. */\n annotationType?: string;\n}\n\nexport interface ParsedTimeline {\n /** ISO baseline for the entries' relative `timestampMs`. */\n startTimestamp?: string;\n entries: ActionTimelineEntry[];\n}\n\n\nexport const writeTimelineActionsAndNavigation = async (\n workspaceRoot: string,\n timeline: ParsedTimeline,\n): Promise<void> => {\n const baselineMs = timeline.startTimestamp ? Date.parse(timeline.startTimestamp) : null;\n\n const actions = timeline.entries.map((e) => ({\n action: e.action,\n target: e.target ?? null,\n value: e.value ?? null,\n url: e.url ?? null,\n relativeTimestampMs: e.timestampMs,\n timestampMs: baselineMs !== null ? baselineMs + e.timestampMs : null,\n success: e.success,\n isAnnotation: e.isAnnotation ?? false,\n // e.g. `crash-recovery` — lets the agent `jq` mid-run browser crashes. Omitted\n // for ordinary actions so it doesn't bloat every row.\n ...(e.annotationType ? { annotationType: e.annotationType } : {}),\n }));\n\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.timelineActions),\n actions,\n );\n\n const navRows: Array<{\n relativeTimestampMs: number;\n timestampMs: number | null;\n action: string;\n from: string | null;\n to: string | null;\n crossHost: boolean;\n }> = [];\n let prevUrl: string | null = null;\n for (const a of actions) {\n const isNavAction = NAVIGATION_ACTIONS.has(a.action);\n const urlChanged = a.url !== null && prevUrl !== null && a.url !== prevUrl;\n if (!isNavAction && !urlChanged) {\n if (a.url) prevUrl = a.url;\n continue;\n }\n const fromHost = hostOf(prevUrl);\n const toHost = hostOf(a.url);\n navRows.push({\n relativeTimestampMs: a.relativeTimestampMs,\n timestampMs: a.timestampMs,\n action: a.action,\n from: prevUrl,\n to: a.url,\n crossHost: fromHost !== null && toHost !== null && fromHost !== toHost,\n });\n if (a.url) prevUrl = a.url;\n }\n\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.timelineNavigation),\n navRows,\n );\n};\n\n// ============================================================================\n// timeline/assertions.jsonl + cache-decisions.jsonl (derived from step metadata)\n// ============================================================================\n\nexport const writeAssertionsAndCacheDecisions = async (\n workspaceRoot: string,\n steps: ReadonlyArray<RunStepLike>,\n): Promise<void> => {\n const sortedSteps = steps.slice().sort((a, b) => a.orderIndex - b.orderIndex);\n\n const assertions: Array<Record<string, unknown>> = [];\n const cacheDecisions: Array<Record<string, unknown>> = [];\n\n for (const step of sortedSteps) {\n const meta = isObject(step.metadataJson) ? step.metadataJson : {};\n const startedMs = isoToMs(step.startedAt);\n\n const rawAssertions = Array.isArray(meta.assertionResults)\n ? (meta.assertionResults as ReadonlyArray<unknown>)\n : [];\n for (const r of rawAssertions) {\n if (!isObject(r)) continue;\n assertions.push({\n stepId: step.id,\n nodeId: step.nodeId,\n orderIndex: step.orderIndex,\n stepStatus: step.status,\n timestampMs: startedMs,\n assertionId: r.inlineAssertionId ?? r.assertionId ?? r.key ?? null,\n condition: r.condition ?? null,\n severity: r.severity ?? null,\n nonBlocking: Boolean(r.nonBlocking),\n passed: Boolean(r.passed),\n reason: r.reason ?? null,\n });\n }\n\n cacheDecisions.push({\n stepId: step.id,\n nodeId: step.nodeId,\n orderIndex: step.orderIndex,\n stepStatus: step.status,\n timestampMs: startedMs,\n cacheOutcome: meta.cacheOutcome ?? null,\n cacheHitSource: meta.cacheHitSource ?? null,\n cacheProcessingStatus: meta.cacheProcessingStatus ?? null,\n cacheOutcomeReason: meta.cacheOutcomeReason ?? null,\n });\n }\n\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.timelineAssertions),\n assertions,\n );\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.timelineCacheDecisions),\n cacheDecisions,\n );\n};\n\n// ============================================================================\n// thoughts/all.jsonl + thoughts/by-step/<stepId>.md\n// ============================================================================\n\nexport interface ThoughtLike {\n id: string;\n stepId: string | null;\n nodeId: string | null;\n toolName: string | null;\n content: string;\n orderIndex: number;\n /** ISO timestamp. */\n createdAt: string;\n}\n\nexport const writeThoughts = async (\n workspaceRoot: string,\n thoughts: ReadonlyArray<ThoughtLike>,\n): Promise<void> => {\n const sorted = thoughts.slice().sort((a, b) => a.orderIndex - b.orderIndex);\n\n const allRows = sorted.map((t) => ({\n id: t.id,\n stepId: t.stepId,\n nodeId: t.nodeId,\n toolName: t.toolName,\n orderIndex: t.orderIndex,\n timestampMs: isoToMs(t.createdAt),\n createdAt: t.createdAt,\n content: t.content,\n }));\n\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.thoughtsAll),\n allRows,\n );\n\n const byStep = new Map<string, ThoughtLike[]>();\n for (const t of sorted) {\n const key = t.stepId ?? '_no-step';\n const list = byStep.get(key) ?? [];\n list.push(t);\n byStep.set(key, list);\n }\n\n // Write all per-step files concurrently — they target distinct paths.\n const renderStep = ([stepId, stepThoughts]: [string, ThoughtLike[]]): {\n relativePath: string;\n body: string;\n } => {\n const md: string[] = [];\n md.push(`# Thoughts for ${stepId === '_no-step' ? '(no step)' : `step ${stepId}`}`);\n md.push('');\n for (const t of stepThoughts) {\n const tool = t.toolName ? ` [tool: ${t.toolName}]` : '';\n md.push(`## ${t.createdAt}${tool}`);\n md.push('');\n md.push(t.content);\n md.push('');\n }\n return {\n relativePath: thoughtsByStepRelativePath(stepId),\n body: `${md.join('\\n')}\\n`,\n };\n };\n const rendered = [...byStep.entries()].map(renderStep);\n await Promise.all(\n rendered.map(({ relativePath, body }) =>\n writeText(resolveWorkspacePath(workspaceRoot, relativePath), body),\n ),\n );\n};\n\n// ============================================================================\n// logs/{network,console}.jsonl (raw + errors)\n// ============================================================================\n\nexport interface NetworkLogLike {\n url: string;\n method: string;\n status: number | null;\n durationMs: number | null;\n requestBody: string | null;\n responseBody: string | null;\n contentType: string | null;\n timestamp?: number | string | null;\n}\n\nexport interface ConsoleLogLike {\n type: string;\n text: string;\n timestamp: number | string | null;\n location: string | null;\n}\n\nconst normalizeTimestamp = (ts: number | string | null | undefined): number | null => {\n if (ts === null || ts === undefined) return null;\n if (typeof ts === 'number') return ts;\n const parsed = Date.parse(ts);\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nexport const writeLogs = async (\n workspaceRoot: string,\n network: ReadonlyArray<NetworkLogLike>,\n consoleLogs: ReadonlyArray<ConsoleLogLike>,\n): Promise<void> => {\n const networkRows = network.map((e) => ({\n timestampMs: normalizeTimestamp(e.timestamp ?? null),\n url: e.url,\n method: e.method,\n status: e.status ?? null,\n durationMs: e.durationMs ?? null,\n requestBody: e.requestBody ?? null,\n responseBody: e.responseBody ?? null,\n contentType: e.contentType ?? null,\n }));\n const networkErrors = networkRows.filter(\n (r) => typeof r.status === 'number' && r.status >= 400,\n );\n\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.logsNetwork),\n networkRows,\n );\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.logsNetworkErrors),\n networkErrors,\n );\n\n const consoleRows = consoleLogs.map((e) => ({\n timestampMs: normalizeTimestamp(e.timestamp),\n type: e.type,\n text: e.text,\n location: e.location ?? null,\n }));\n const consoleErrors = consoleRows.filter(\n (r) => r.type === 'error' || r.type === 'warning',\n );\n\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.logsConsole),\n consoleRows,\n );\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.logsConsoleErrors),\n consoleErrors,\n );\n};\n\n// ============================================================================\n// committed-actions.{md,jsonl}\n// ============================================================================\n\nexport interface CommittedActionLike {\n ts: string;\n executor: string;\n actionType: string;\n target: string;\n pageUrl: string | null;\n success: boolean;\n}\n\n/**\n * Mutations a prior cache/L2 layer already committed during THIS run. A\n * destructive row here (a revoke/delete that succeeded) means the target's\n * later absence is an EXPECTED side effect — not evidence a create step failed.\n */\nexport const writeCommittedActions = async (\n workspaceRoot: string,\n actions: ReadonlyArray<CommittedActionLike>,\n): Promise<void> => {\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.committedActionsJsonl),\n actions,\n );\n\n const lines: string[] = ['# Committed actions (prior cache/L2 layers)', ''];\n if (actions.length === 0) {\n lines.push(\n '_No prior-layer (cache_replay / l2_playbook) actions were recorded for this run._',\n );\n } else {\n lines.push(\n 'A prior cache/L2 layer already executed these actions during this run.',\n 'If one of them deleted/revoked a record, that record being absent later is EXPECTED —',\n 'do NOT attribute the absence to a failed upstream \"create\" step.',\n '',\n );\n for (const a of actions) {\n // `success` here means the action was performed/recorded (recorded\n // post-landing), not that the server returned 2xx — say \"performed\".\n lines.push(\n `- ${a.ts} · ${a.executor} · ${a.actionType} \"${a.target}\"${\n a.success ? ' · performed' : ''\n }${a.pageUrl ? ` · ${a.pageUrl}` : ''}`,\n );\n }\n }\n await writeText(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.committedActions),\n `${lines.join('\\n')}\\n`,\n );\n};\n\n// ============================================================================\n// variables/{inputs.json,lineage.jsonl}\n// ============================================================================\n\nexport const writeVariables = async (\n workspaceRoot: string,\n runMetadata: Record<string, unknown> | null | undefined,\n steps: ReadonlyArray<RunStepLike>,\n): Promise<void> => {\n const inputs =\n isObject(runMetadata) && isObject(runMetadata.workflowInputValues)\n ? runMetadata.workflowInputValues\n : {};\n await writeJson(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.variablesInputs),\n inputs,\n );\n\n const sortedSteps = steps.slice().sort((a, b) => a.orderIndex - b.orderIndex);\n const lineageRows: Array<Record<string, unknown>> = [];\n for (const step of sortedSteps) {\n const meta = isObject(step.metadataJson) ? step.metadataJson : {};\n const captures = Array.isArray(meta.variablesSet) ? meta.variablesSet : [];\n const startedMs = isoToMs(step.startedAt);\n for (const c of captures) {\n if (!isObject(c)) continue;\n lineageRows.push({\n name: c.name ?? c.key ?? null,\n value: c.value ?? null,\n definedAtStepId: step.id,\n definedAtNodeId: step.nodeId,\n definedAtOrderIndex: step.orderIndex,\n definedAtTimestampMs: startedMs,\n });\n }\n }\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.variablesLineage),\n lineageRows,\n );\n};\n\n// ============================================================================\n// history/recent-runs.jsonl\n// ============================================================================\n\nexport interface RecentRunLike {\n id: string;\n workflowRunId: string | null;\n status: string;\n /** ISO. */\n startedAt: string | null;\n /** ISO. */\n finishedAt: string | null;\n errorMessage: string | null;\n}\n\nexport const writeRecentRuns = async (\n workspaceRoot: string,\n runs: ReadonlyArray<RecentRunLike>,\n): Promise<void> => {\n const rows = runs.map((r) => ({\n testRunId: r.id,\n workflowRunId: r.workflowRunId,\n status: r.status,\n startedAt: r.startedAt,\n finishedAt: r.finishedAt,\n startedAtMs: isoToMs(r.startedAt),\n finishedAtMs: isoToMs(r.finishedAt),\n errorMessage: r.errorMessage,\n }));\n await writeJsonl(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.historyRecentRuns),\n rows,\n );\n};\n","/**\n * Workflow Definition Writer\n *\n * @module @chatsdet/diagnostic-workspace/workflow-writer\n * @description Writes `workflow/definition.json`, `workflow/snapshot.json`, and one\n * `workflow/nodes/<nodeId>.json` per node. The agent reads `workflow/nodes/<nodeId>.json`\n * for the full configJson when comparing what a step was supposed to do vs what actually\n * happened, and when proposing `configPatch` suggestions.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { topoOrderNodes } from '@chatsdet/workflow-diff';\nimport {\n resolveWorkspacePath,\n workflowNodeRelativePath,\n WORKSPACE_PATHS,\n} from './paths.js';\n\nexport interface WorkflowWriterNode {\n id: string;\n nodeType: string;\n configJson: unknown;\n orderIndex: number;\n /** Pre-resolved one-line summary (caller computes via getNodeSummary). */\n summary: string;\n}\n\nexport interface WorkflowWriterEdge {\n id: string;\n source: string;\n target: string;\n}\n\nexport interface WorkflowWriterInput {\n workspaceRoot: string;\n workflowId: string;\n workflowName: string;\n nodes: ReadonlyArray<WorkflowWriterNode>;\n edges: ReadonlyArray<WorkflowWriterEdge>;\n}\n\nexport const writeWorkflowDefinition = async (input: WorkflowWriterInput): Promise<void> => {\n // Order by flow (edge) order; orderIndex is deprecated. WorkflowWriterEdge\n // uses source/target, so map to the topo helper's sourceNodeId/targetNodeId.\n const sortedNodes = topoOrderNodes(\n [...input.nodes],\n input.edges.map((e) => ({ sourceNodeId: e.source, targetNodeId: e.target }))\n );\n\n const definition = {\n workflowId: input.workflowId,\n name: input.workflowName,\n nodes: sortedNodes.map((n) => ({\n id: n.id,\n nodeType: n.nodeType,\n orderIndex: n.orderIndex,\n summary: n.summary,\n })),\n edges: input.edges.map((e) => ({\n id: e.id,\n source: e.source,\n target: e.target,\n })),\n };\n\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.workflowDefinition),\n `${JSON.stringify(definition, null, 2)}\\n`,\n 'utf-8',\n );\n\n const snapshot = {\n workflowId: input.workflowId,\n name: input.workflowName,\n nodes: sortedNodes.map((n) => ({\n id: n.id,\n nodeType: n.nodeType,\n orderIndex: n.orderIndex,\n configJson: n.configJson,\n })),\n edges: input.edges.map((e) => ({ id: e.id, source: e.source, target: e.target })),\n };\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.workflowSnapshot),\n `${JSON.stringify(snapshot, null, 2)}\\n`,\n 'utf-8',\n );\n\n // Per-node files target distinct paths — write concurrently.\n await Promise.all(\n sortedNodes.map((node) => {\n const filePath = resolveWorkspacePath(\n input.workspaceRoot,\n workflowNodeRelativePath(node.id),\n );\n const body = {\n id: node.id,\n nodeType: node.nodeType,\n orderIndex: node.orderIndex,\n summary: node.summary,\n configJson: node.configJson,\n };\n return fs.writeFile(filePath, `${JSON.stringify(body, null, 2)}\\n`, 'utf-8');\n }),\n );\n};\n","/**\n * Sentry Logs + Spans Writer\n *\n * @module @chatsdet/diagnostic-workspace/sentry-writer\n * @description Pure-transform writer. Takes pre-fetched logs/spans (data-fetch\n * layer responsibility) and dumps them to `logs/sentry-logs.jsonl` /\n * `logs/sentry-spans.jsonl`. When the source was unavailable, the caller marks\n * the partial flag in `RunData.sentryLogs`/`sentrySpans`; we encode it as a\n * sentinel first line so the agent can detect via\n * `head -n 1 logs/sentry-logs.jsonl | jq '.partial'`.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { resolveWorkspacePath, WORKSPACE_PATHS } from './paths.js';\nimport type {\n RunDataPartial,\n RunDataSentryLog,\n RunDataSentrySpan,\n} from './run-data.js';\n\nexport interface SentryWriterInput {\n workspaceRoot: string;\n logs: { partial?: RunDataPartial; rows: ReadonlyArray<RunDataSentryLog> };\n spans: { partial?: RunDataPartial; spans: ReadonlyArray<RunDataSentrySpan> };\n}\n\nconst writeJsonlWithSentinel = async (\n absolutePath: string,\n partial: RunDataPartial | undefined,\n rows: ReadonlyArray<unknown>,\n): Promise<void> => {\n const lines: string[] = [];\n if (partial) lines.push(JSON.stringify(partial));\n for (const r of rows) lines.push(JSON.stringify(r));\n await fs.writeFile(\n absolutePath,\n lines.length === 0 ? '' : `${lines.join('\\n')}\\n`,\n 'utf-8',\n );\n};\n\n/** Returns true when either source was partial. */\nexport const writeSentryLogsAndSpans = async (input: SentryWriterInput): Promise<boolean> => {\n await writeJsonlWithSentinel(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.logsSentry),\n input.logs.partial,\n input.logs.rows,\n );\n await writeJsonlWithSentinel(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.logsSentrySpans),\n input.spans.partial,\n input.spans.spans,\n );\n return Boolean(input.logs.partial || input.spans.partial);\n};\n","/**\n * Trace Extractor\n *\n * @module @chatsdet/diagnostic-workspace/trace-extractor\n * @description Pure-transform side of trace handling. The data-fetch layer\n * (server) downloads trace.zip from S3 to a local path, then calls into here\n * with that path. The CLI does the same with a signed-URL download.\n *\n * Writes:\n * - `browser/trace.zip` — copied to the workspace as an escape hatch\n * - `browser/actions.jsonl` — parsed action list\n * - `browser/doms/<NNNN>-<absoluteTsMs>.html` — composed self-contained HTML\n * - `browser/frames/<NNNN>-<absoluteTsMs>.png` — screenshot per action\n * - `browser/a11y/<NNNN>-<absoluteTsMs>.yaml` — agent's accessibility view\n *\n * Reconstruction launches a headless Playwright browser via\n * `@chatsdet/trace-tools`'s `reconstructSnapshots`. Soft-fails if the browser\n * can't start; the workspace is marked partial.\n */\n\nimport * as fs from 'node:fs/promises';\nimport {\n parseTraceActions,\n reconstructSnapshots,\n type TraceAction,\n type SnapshotResult,\n} from '@chatsdet/trace-tools';\nimport {\n actionArtifactBasename,\n resolveWorkspacePath,\n WORKSPACE_PATHS,\n} from './paths.js';\nimport { makeTraceClock, type TraceClock } from './_shared.js';\nimport { writeScreencast, type KeptScreencastFrame } from './screencast-extractor-writer.js';\n\nexport interface TraceExtractorInput {\n workspaceRoot: string;\n /** Local path to the run's trace.zip. Caller is responsible for fetching it. */\n traceZipPath: string | null;\n /** Anchor for converting trace timestamps to the run-start axis. */\n runStartedAtMs: number | null;\n /** Absolute ms of every step-started/step-completed annotation (screencast keep-density). */\n stepBoundaryMs?: ReadonlyArray<number>;\n /** The failed step's work window (absolute ms) — screencast kept at full density here. */\n failureWindow?: { startMs: number; endMs: number } | null;\n}\n\nexport interface TraceWriteResult {\n /** True if anything failed (workspace marked partial). */\n partial: boolean;\n /** Kept screencast frames, for the step-rollup builder to interleave by timestamp. */\n screencastFrames: KeptScreencastFrame[];\n}\n\nexport const writeTrace = async (input: TraceExtractorInput): Promise<TraceWriteResult> => {\n if (!input.traceZipPath) {\n await writePartialMarker(input.workspaceRoot, 'no-trace');\n return { partial: true, screencastFrames: [] };\n }\n\n // Copy the trace.zip into the workspace as an escape hatch.\n const destTraceZip = resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.browserTraceZip);\n try {\n await fs.copyFile(input.traceZipPath, destTraceZip);\n } catch {\n await writePartialMarker(input.workspaceRoot, 'trace-copy-failed');\n return { partial: true, screencastFrames: [] };\n }\n\n let actions: TraceAction[];\n try {\n actions = parseTraceActions(input.traceZipPath);\n } catch {\n await writePartialMarker(input.workspaceRoot, 'trace-parse-failed');\n return { partial: true, screencastFrames: [] };\n }\n\n // One clock for both lanes — actions and screencast frames land on the same\n // absolute axis the ledger/rollups/inWindow already use.\n const clock = makeTraceClock(actions, input.runStartedAtMs);\n\n await writeActionsJsonl(input.workspaceRoot, actions, clock);\n\n // Screencast runs purely from the zip and MUST run even if DOM reconstruction\n // soft-fails — that's the exact case (evaluate-only steps) that left runs with\n // no visual evidence. Independent dirs → run both concurrently.\n const [reconPartial, screencast] = await Promise.all([\n reconstructAndWriteArtifacts({\n workspaceRoot: input.workspaceRoot,\n tracePath: input.traceZipPath,\n actions,\n clock,\n }),\n writeScreencast({\n workspaceRoot: input.workspaceRoot,\n tracePath: input.traceZipPath,\n actions,\n clock,\n stepBoundaryMs: input.stepBoundaryMs ?? [],\n failureWindow: input.failureWindow ?? null,\n }),\n ]);\n\n return {\n partial: reconPartial || screencast.partial,\n screencastFrames: screencast.frames,\n };\n};\n\nconst writePartialMarker = async (workspaceRoot: string, reason: string): Promise<void> => {\n await fs.writeFile(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.browserActions),\n `${JSON.stringify({ partial: true, reason })}\\n`,\n 'utf-8',\n );\n};\n\ninterface ReconstructInput {\n workspaceRoot: string;\n tracePath: string;\n actions: ReadonlyArray<TraceAction>;\n clock: TraceClock;\n}\n\nconst reconstructAndWriteArtifacts = async (input: ReconstructInput): Promise<boolean> => {\n const computeAbsoluteTs = (action: TraceAction): number => input.clock.absFromAction(action);\n\n let results: SnapshotResult[];\n try {\n results = await reconstructSnapshots({\n traceZipPath: input.tracePath,\n filter: 'after',\n includeScreenshots: true,\n includeHtml: true,\n raw: false,\n });\n } catch {\n return true;\n }\n\n const byActionIndex = new Map<number, SnapshotResult>();\n for (const result of results) {\n if (!byActionIndex.has(result.actionIndex)) {\n byActionIndex.set(result.actionIndex, result);\n }\n }\n\n const domsDir = resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.browserDoms);\n const framesDir = resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.browserFrames);\n const a11yDir = resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.browserA11y);\n\n // For each action, run the three writes (HTML/PNG/YAML) concurrently — distinct\n // paths, no contention. Then run the per-action work concurrently across all\n // actions. Per-action failures don't block siblings; we track partial-state.\n const writeAction = async (i: number): Promise<boolean> => {\n const action = input.actions[i]!;\n const result = byActionIndex.get(i);\n if (!result) return false;\n const tsMs = computeAbsoluteTs(action);\n try {\n await Promise.all([\n result.html\n ? fs.writeFile(\n `${domsDir}/${actionArtifactBasename(i, tsMs, 'html')}`,\n result.html,\n 'utf-8',\n )\n : Promise.resolve(),\n result.screenshotBuffer\n ? fs.writeFile(\n `${framesDir}/${actionArtifactBasename(i, tsMs, 'png')}`,\n result.screenshotBuffer,\n )\n : Promise.resolve(),\n result.yaml\n ? fs.writeFile(\n `${a11yDir}/${actionArtifactBasename(i, tsMs, 'yaml')}`,\n result.yaml,\n 'utf-8',\n )\n : Promise.resolve(),\n ]);\n return true;\n } catch {\n return false;\n }\n };\n\n const indexes = Array.from({ length: input.actions.length }, (_, i) => i);\n const missingResults = indexes.filter((i) => !byActionIndex.has(i)).length;\n const writeOutcomes = await Promise.all(indexes.map((i) => writeAction(i)));\n const writeFailures = writeOutcomes.filter((ok) => !ok).length;\n return missingResults > 0 || writeFailures > 0;\n};\n\nconst writeActionsJsonl = async (\n workspaceRoot: string,\n actions: ReadonlyArray<TraceAction>,\n clock: TraceClock,\n): Promise<void> => {\n const traceBase = actions.length > 0 ? actions[0]!.startTime : 0;\n const lines = actions.map((a, idx) => ({\n actionIndex: idx,\n callId: a.callId,\n title: a.title,\n startTimeRelativeMs: a.startTime - traceBase,\n endTimeRelativeMs: a.endTime - traceBase,\n // Absolute run-start axis — shared with the screencast filmstrip so frames\n // and actions correlate by `timestampMs` with no cross-clock math.\n timestampMs: clock.absFromAction(a),\n // Raw wall-clock epoch (the screencast frames' native clock) for auditability.\n wallTimeMs: a.wallTime ?? null,\n params: a.params ?? null,\n beforeSnapshot: a.beforeSnapshot ?? null,\n afterSnapshot: a.afterSnapshot ?? null,\n inputSnapshot: a.inputSnapshot ?? null,\n pageId: a.pageId,\n error: a.error ?? null,\n point: a.point ?? null,\n }));\n await fs.writeFile(\n resolveWorkspacePath(workspaceRoot, WORKSPACE_PATHS.browserActions),\n lines.length === 0 ? '' : `${lines.map((l) => JSON.stringify(l)).join('\\n')}\\n`,\n 'utf-8',\n );\n};\n","/**\n * Screencast filmstrip writer (workspace side).\n *\n * `@chatsdet/trace-tools`'s `extractScreencastFrames` is the pure, decimation-free\n * extractor. This module owns the workspace concerns it can't: aligning frames to\n * the run-start axis (via the shared `TraceClock`), bounding volume (dedup +\n * failure-window-aware decimation), and writing `browser/screencast/` + its index.\n *\n * Unlike the synthetic per-action frames (`reconstructAndWriteArtifacts`), this\n * runs purely from the zip — no headless browser — so it produces images even\n * when reconstruction soft-fails, and at evaluate/wait moments that have no\n * action snapshot at all.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { extractScreencastFrames, type TraceAction } from '@chatsdet/trace-tools';\nimport {\n resolveWorkspacePath,\n screencastFrameBasename,\n WORKSPACE_PATHS,\n} from './paths.js';\nimport type { TraceClock } from './_shared.js';\n\n/** Keep one frame every ~250ms in the idle stretches between always-keep frames. */\nconst DEFAULT_CADENCE_MS = 250;\n/** Hard ceiling on kept frames (disk + agent read budget). Always-keep frames are exempt. */\nconst DEFAULT_MAX_FRAMES = 400;\n/** Pad the failed step's bracket so the frames just before/after it survive at full density. */\nconst FAILURE_WINDOW_PAD_MS = 3000;\n\ntype KeptReason = 'failure-window' | 'action' | 'step-boundary' | 'cadence';\n\n/** A surviving filmstrip frame, projected for step rollups and the index. */\nexport interface KeptScreencastFrame {\n frameIndex: number;\n timestampMs: number;\n wallTimeMs: number;\n pageId: string;\n file: string;\n keptReason: KeptReason;\n /** True when raw frames were dropped between this frame and the prior kept one. */\n decimatedBefore: boolean;\n}\n\nexport interface ScreencastWriteInput {\n workspaceRoot: string;\n tracePath: string;\n /** Parsed trace actions — used to anchor frames near real interactions. */\n actions: ReadonlyArray<TraceAction>;\n /** Shared clock so frames land on the same axis as `actions.jsonl.timestampMs`. */\n clock: TraceClock;\n /** Absolute ms of every step-started/step-completed annotation. */\n stepBoundaryMs: ReadonlyArray<number>;\n /** The failed step's padded work window (absolute ms) — kept at full density. */\n failureWindow: { startMs: number; endMs: number } | null;\n cadenceMs?: number;\n maxFrames?: number;\n}\n\nexport interface ScreencastWriteResult {\n /** True if anything was missing/failed (workspace marked partial). */\n partial: boolean;\n /** The kept frames, for the step-rollup builder to interleave by timestamp. */\n frames: KeptScreencastFrame[];\n}\n\ninterface MappedFrame {\n absTs: number;\n wallTimeMs: number;\n pageId: string;\n jpeg: Buffer;\n}\n\n/** Index (into `sorted`) of the frame nearest `targetTs`. Assumes `sorted` ascending by `ts`. */\nconst nearestIndex = (sorted: ReadonlyArray<{ idx: number; ts: number }>, targetTs: number): number | null => {\n if (sorted.length === 0) return null;\n let lo = 0;\n let hi = sorted.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (sorted[mid]!.ts < targetTs) lo = mid + 1;\n else hi = mid;\n }\n // `lo` is the first frame at/after target; compare it with its predecessor.\n const after = sorted[lo]!;\n const before = lo > 0 ? sorted[lo - 1]! : null;\n if (before && Math.abs(before.ts - targetTs) <= Math.abs(after.ts - targetTs)) {\n return before.idx;\n }\n return after.idx;\n};\n\n/**\n * Extract, align, decimate, and write the screencast filmstrip. Returns\n * `{ partial, frames }`; `partial=true` (and an index marker) when there are no\n * screencast frames (older traces / `screenshots:false`) or writes fail.\n */\nexport const writeScreencast = async (\n input: ScreencastWriteInput,\n): Promise<ScreencastWriteResult> => {\n const cadenceMs = input.cadenceMs ?? DEFAULT_CADENCE_MS;\n const maxFrames = input.maxFrames ?? DEFAULT_MAX_FRAMES;\n const indexPath = resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.browserScreencastIndex);\n\n let rawFrames;\n try {\n rawFrames = extractScreencastFrames(input.tracePath, { dedupeConsecutive: true });\n } catch {\n await writeIndexMarker(indexPath, 'screencast-extract-failed');\n return { partial: true, frames: [] };\n }\n\n if (rawFrames.length === 0) {\n await writeIndexMarker(indexPath, 'no-screencast-frames');\n return { partial: true, frames: [] };\n }\n\n // Align every frame to the run-start axis. `extractScreencastFrames` already\n // sorted by wall time, and `absFromWall` is monotonic, so `mapped` stays sorted.\n // `frameSwapWallTime` carries sub-ms precision; round to integer ms so\n // timestamps format cleanly (T+S.mmm) and filenames stay `<NNNN>-<intMs>.jpg`.\n const mapped: MappedFrame[] = rawFrames.map((f) => ({\n absTs: Math.round(input.clock.absFromWall(f.frameSwapWallTimeMs)),\n wallTimeMs: f.frameSwapWallTimeMs,\n pageId: f.pageId,\n jpeg: f.jpeg,\n }));\n\n // Per-page sorted index for same-page nearest-frame lookups (popups have their\n // own stream — never match a main-page action to a popup frame).\n const globalSorted = mapped.map((m, idx) => ({ idx, ts: m.absTs }));\n const perPageSorted = new Map<string, Array<{ idx: number; ts: number }>>();\n mapped.forEach((m, idx) => {\n const list = perPageSorted.get(m.pageId) ?? [];\n list.push({ idx, ts: m.absTs });\n perPageSorted.set(m.pageId, list);\n });\n\n // Reason per kept frame, highest priority wins.\n const kept = new Map<number, KeptReason>();\n const setIfHigher = (idx: number | null, reason: KeptReason): void => {\n if (idx === null) return;\n const existing = kept.get(idx);\n if (existing === undefined || PRIORITY[reason] > PRIORITY[existing]) kept.set(idx, reason);\n };\n\n // 1. Failure window — keep every frame inside it (post-dedup).\n if (input.failureWindow) {\n const start = input.failureWindow.startMs - FAILURE_WINDOW_PAD_MS;\n const end = input.failureWindow.endMs + FAILURE_WINDOW_PAD_MS;\n mapped.forEach((m, idx) => {\n if (m.absTs >= start && m.absTs <= end) setIfHigher(idx, 'failure-window');\n });\n }\n\n // 2. Nearest same-page frame to every real action.\n for (const action of input.actions) {\n const list = perPageSorted.get(action.pageId);\n if (!list) continue;\n setIfHigher(nearestIndex(list, input.clock.absFromAction(action)), 'action');\n }\n\n // 3. Nearest frame (any page) to every step boundary.\n for (const ts of input.stepBoundaryMs) {\n setIfHigher(nearestIndex(globalSorted, ts), 'step-boundary');\n }\n\n // 4. Cadence fill across idle stretches, bounded by the frame cap.\n const cadenceBudget = Math.max(0, maxFrames - kept.size);\n if (cadenceBudget > 0) {\n let added = 0;\n let lastTs: number | null = null;\n for (let idx = 0; idx < mapped.length; idx++) {\n if (added >= cadenceBudget) break;\n const ts = mapped[idx]!.absTs;\n if (kept.has(idx)) {\n lastTs = ts;\n continue;\n }\n if (lastTs === null || ts - lastTs >= cadenceMs) {\n kept.set(idx, 'cadence');\n lastTs = ts;\n added++;\n }\n }\n }\n\n // Ordered kept frames (by time) → sequential frame index + honest gap marking.\n const keptIndexes = [...kept.keys()].sort((a, b) => mapped[a]!.absTs - mapped[b]!.absTs);\n const result: KeptScreencastFrame[] = [];\n let prevRawIdx = -1;\n keptIndexes.forEach((rawIdx, frameIndex) => {\n const m = mapped[rawIdx]!;\n result.push({\n frameIndex,\n timestampMs: m.absTs,\n wallTimeMs: m.wallTimeMs,\n pageId: m.pageId,\n file: `${WORKSPACE_PATHS.browserScreencast}/${screencastFrameBasename(frameIndex, m.absTs)}`,\n keptReason: kept.get(rawIdx)!,\n // Raw frames existed between the previous kept frame and this one.\n decimatedBefore: rawIdx - prevRawIdx > 1,\n });\n prevRawIdx = rawIdx;\n });\n\n // Write JPEGs + index. Per-file failures don't block siblings.\n const writeOutcomes = await Promise.all(\n result.map(async (frame, i) => {\n try {\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, frame.file),\n mapped[keptIndexes[i]!]!.jpeg,\n );\n return true;\n } catch {\n return false;\n }\n }),\n );\n const writeFailures = writeOutcomes.filter((ok) => !ok).length;\n\n const meta = {\n meta: true,\n rawFrameCount: rawFrames.length,\n keptFrameCount: result.length,\n deduped: true,\n decimationCadenceMs: cadenceMs,\n maxFrames,\n approxAlignment: input.clock.approxAlignment,\n };\n const lines = [JSON.stringify(meta), ...result.map((f) => JSON.stringify(f))];\n try {\n await fs.writeFile(indexPath, `${lines.join('\\n')}\\n`, 'utf-8');\n } catch {\n return { partial: true, frames: result };\n }\n\n return { partial: writeFailures > 0, frames: result };\n};\n\nconst PRIORITY: Record<KeptReason, number> = {\n 'failure-window': 3,\n action: 2,\n 'step-boundary': 1,\n cadence: 0,\n};\n\nconst writeIndexMarker = async (indexPath: string, reason: string): Promise<void> => {\n await fs.writeFile(indexPath, `${JSON.stringify({ meta: true, partial: true, reason })}\\n`, 'utf-8');\n};\n","/**\n * Ledger Builder\n *\n * @module workflows/diagnostics/materialize/ledger-builder\n * @description Composes `ledger.md` (full chronological narrative) and `ledger-index.md`\n * (step-heading TOC with line numbers) from in-memory event streams. The builder is the\n * single load-bearing artifact for the diagnostic agent: every event from steps, thoughts,\n * actions, navigation, network, console, and assertions appears as one timestamped line.\n *\n * Format invariants (verified by `materialize.test.ts`):\n * - Every line carries `[T+S.SSSs @ HH:MM:SS.mmm]` prefix when timestamps are known.\n * - Lines sort strictly by absolute timestamp (with relative time as tie-breaker).\n * - Step headings sit at the step start; per-step lines follow until the next heading.\n * - `ledger-index.md` lists each step heading with its `ledger.md` line number.\n *\n * Lines whose absolute timestamp is unknown (e.g. trace events when `runStartedAt` was\n * null on the run record) sort to the end with an `[unknown @ unknown]` prefix.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { resolveWorkspacePath, WORKSPACE_PATHS } from './paths.js';\nimport { computeStepWorkWindows, formatPrefix as formatTimestampPrefix, oneLine } from './_shared.js';\n\n// ============================================================================\n// Inputs\n// ============================================================================\n\nexport interface LedgerStep {\n id: string;\n nodeId: string;\n orderIndex: number;\n name: string | null;\n nodeType: string | null;\n status: string;\n startedAtMs: number | null;\n finishedAtMs: number | null;\n durationMs: number | null;\n errorMessage: string | null;\n cacheOutcome: string | null;\n cacheHitSource: string | null;\n}\n\nexport interface LedgerThought {\n stepId: string | null;\n timestampMs: number;\n toolName: string | null;\n content: string;\n}\n\nexport interface LedgerAction {\n action: string;\n target: string | null;\n url: string | null;\n timestampMs: number | null;\n success: boolean;\n isAnnotation: boolean;\n}\n\nexport interface LedgerNavigation {\n timestampMs: number | null;\n action: string;\n from: string | null;\n to: string | null;\n crossHost: boolean;\n}\n\nexport interface LedgerNetwork {\n timestampMs: number | null;\n url: string;\n method: string;\n status: number | null;\n}\n\nexport interface LedgerConsole {\n timestampMs: number | null;\n type: string;\n text: string;\n}\n\nexport interface LedgerAssertion {\n stepId: string;\n timestampMs: number | null;\n condition: string | null;\n severity: string | null;\n nonBlocking: boolean;\n passed: boolean;\n reason: string | null;\n}\n\nexport interface LedgerInput {\n workspaceRoot: string;\n runId: string;\n workflowId: string;\n workflowName: string;\n runStatus: string;\n /** ISO; canonical baseline for `T+...s` relative timestamps. */\n runStartedAt: string | null;\n reportedFailure: {\n failedStepName: string | null;\n failedStepOrderIndex: number | null;\n errorMessage: string | null;\n };\n steps: ReadonlyArray<LedgerStep>;\n thoughts: ReadonlyArray<LedgerThought>;\n actions: ReadonlyArray<LedgerAction>;\n navigation: ReadonlyArray<LedgerNavigation>;\n network: ReadonlyArray<LedgerNetwork>;\n consoleLogs: ReadonlyArray<LedgerConsole>;\n assertions: ReadonlyArray<LedgerAssertion>;\n}\n\n// ============================================================================\n// Internal event union\n// ============================================================================\n\ntype LedgerEvent =\n | { kind: 'step'; step: LedgerStep; timestampMs: number | null }\n | { kind: 'thought'; thought: LedgerThought; stepId: string | null }\n | { kind: 'action'; action: LedgerAction }\n | { kind: 'nav'; nav: LedgerNavigation }\n | { kind: 'network'; net: LedgerNetwork }\n | { kind: 'console'; con: LedgerConsole }\n | { kind: 'assertion'; assertion: LedgerAssertion };\n\n// ============================================================================\n// Builder\n// ============================================================================\n\nexport const writeLedger = async (input: LedgerInput): Promise<void> => {\n const baselineMs = input.runStartedAt ? Date.parse(input.runStartedAt) : null;\n\n // True execution windows from step-started/step-completed annotations. A\n // cache/playbook step's record `startedAt` is only its commit moment, so\n // anchoring the heading there would sort it *after* the live actions it owns\n // (they'd mis-group under the prior step). Anchor at the work-window start when\n // available so the heading precedes its own actions and `ledger-index.md`\n // ranges are correct; fall back to the record start otherwise.\n const workWindows = computeStepWorkWindows(input.steps, input.actions);\n\n // Build the event list. Steps anchor at their work-window start (or record\n // startedAt); everything else sorts in by timestamp.\n const events: LedgerEvent[] = [];\n for (const step of input.steps) {\n events.push({\n kind: 'step',\n step,\n timestampMs: workWindows.get(step.id)?.startMs ?? step.startedAtMs,\n });\n }\n for (const thought of input.thoughts) {\n events.push({ kind: 'thought', thought, stepId: thought.stepId });\n }\n for (const action of input.actions) {\n events.push({ kind: 'action', action });\n }\n for (const nav of input.navigation) {\n events.push({ kind: 'nav', nav });\n }\n for (const net of input.network) {\n events.push({ kind: 'network', net });\n }\n for (const con of input.consoleLogs) {\n events.push({ kind: 'console', con });\n }\n for (const assertion of input.assertions) {\n events.push({ kind: 'assertion', assertion });\n }\n\n events.sort((a, b) => {\n const ta = eventTimestamp(a);\n const tb = eventTimestamp(b);\n if (ta === null && tb === null) return 0;\n if (ta === null) return 1; // unknowns to the end\n if (tb === null) return -1;\n if (ta !== tb) return ta - tb;\n // Tie-break: step heading comes before the events inside it.\n const ra = eventRank(a);\n const rb = eventRank(b);\n return ra - rb;\n });\n\n // Render the markdown body. Track line numbers for the index.\n const lines: string[] = [];\n const indexEntries: Array<{ orderIndex: number; name: string | null; line: number }> = [];\n\n // Header.\n lines.push(`# Run Ledger — runId: ${input.runId} — workflow: ${input.workflowName} — status: ${input.runStatus}`);\n if (baselineMs !== null) {\n lines.push(`runStartedAt: ${input.runStartedAt!} (all T+ values are relative to this)`);\n } else {\n lines.push(`runStartedAt: (unknown — relative timestamps unavailable)`);\n }\n lines.push('');\n\n // Reported failure pseudo-section.\n if (input.runStatus === 'failed' && input.reportedFailure.failedStepName) {\n const ordinalPart =\n input.reportedFailure.failedStepOrderIndex !== null\n ? ` (step ${input.reportedFailure.failedStepOrderIndex})`\n : '';\n lines.push(`## ⚠ Reported failure`);\n lines.push(`Step${ordinalPart}: **${input.reportedFailure.failedStepName}**`);\n if (input.reportedFailure.errorMessage) {\n lines.push('');\n lines.push('```');\n lines.push(input.reportedFailure.errorMessage);\n lines.push('```');\n }\n lines.push('');\n lines.push('**Verify before trusting — root cause may be upstream.**');\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n for (const event of events) {\n const ts = eventTimestamp(event);\n const prefix = formatTimestampPrefix(ts, baselineMs);\n\n if (event.kind === 'step') {\n const s = event.step;\n const meta = [\n `status: ${s.status}`,\n s.durationMs !== null ? `dur ${s.durationMs}ms` : null,\n s.cacheOutcome ? `cache: ${s.cacheOutcome}${s.cacheHitSource ? `/${s.cacheHitSource}` : ''}` : null,\n ]\n .filter((x): x is string => x !== null)\n .join(', ');\n const heading = `## ${prefix} Step ${s.orderIndex}: ${s.name ?? s.nodeId} (${meta})`;\n // Insert a blank line before each step heading except the first.\n if (lines.length > 0 && lines[lines.length - 1] !== '') lines.push('');\n indexEntries.push({\n orderIndex: s.orderIndex,\n name: s.name,\n line: lines.length + 1, // 1-indexed\n });\n lines.push(heading);\n if (s.errorMessage) {\n lines.push(`${prefix} step.error: ${oneLine(s.errorMessage)}`);\n }\n continue;\n }\n\n if (event.kind === 'thought') {\n const t = event.thought;\n const tool = t.toolName ? ` [${t.toolName}]` : '';\n lines.push(`${prefix} thought${tool}: ${oneLine(t.content)}`);\n continue;\n }\n\n if (event.kind === 'action') {\n const a = event.action;\n const target = a.target ? ` ${oneLine(a.target)}` : '';\n const url = a.url ? ` → ${a.url}` : '';\n const status = a.success ? '' : ' (failed)';\n const annotation = a.isAnnotation ? ' [annotation]' : '';\n lines.push(`${prefix} action.${a.action}${annotation}:${target}${url}${status}`);\n continue;\n }\n\n if (event.kind === 'nav') {\n const n = event.nav;\n const cross = n.crossHost ? ' ⚠ cross-host' : '';\n lines.push(`${prefix} nav.${n.action}: ${n.from ?? '?'} → ${n.to ?? '?'}${cross}`);\n continue;\n }\n\n if (event.kind === 'network') {\n const n = event.net;\n const status = n.status !== null ? ` ${n.status}` : '';\n lines.push(`${prefix} network: ${n.method} ${n.url}${status}`);\n continue;\n }\n\n if (event.kind === 'console') {\n const c = event.con;\n lines.push(`${prefix} console.${c.type}: ${oneLine(c.text)}`);\n continue;\n }\n\n if (event.kind === 'assertion') {\n const a = event.assertion;\n const tag = a.passed ? 'assertion.passed' : 'assertion.failed';\n const severity = a.severity ? ` [${a.severity}${a.nonBlocking ? ' nonBlocking' : ''}]` : '';\n const cond = a.condition ? oneLine(a.condition) : '(no condition)';\n const reason = a.reason ? ` — ${oneLine(a.reason)}` : '';\n lines.push(`${prefix} ${tag}${severity}: ${cond}${reason}`);\n continue;\n }\n }\n\n if (lines[lines.length - 1] !== '') lines.push('');\n\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.ledger),\n `${lines.join('\\n')}`,\n 'utf-8',\n );\n\n // Build the index file.\n const indexLines: string[] = [];\n indexLines.push(`# Ledger Index — runId: ${input.runId}`);\n indexLines.push('');\n indexLines.push('Use `bash(\"sed -n \\'<a>,<b>p\\' ledger.md\")` to read a step\\'s window.');\n indexLines.push('');\n if (indexEntries.length === 0) {\n indexLines.push('(no steps recorded for this run)');\n } else {\n for (let i = 0; i < indexEntries.length; i++) {\n const entry = indexEntries[i]!;\n const next = indexEntries[i + 1];\n const startLine = entry.line;\n const endLine = next ? next.line - 1 : lines.length;\n const name = entry.name ?? '(unnamed step)';\n indexLines.push(`Step ${entry.orderIndex}: ${name} — lines ${startLine}-${endLine}`);\n }\n }\n indexLines.push('');\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.ledgerIndex),\n `${indexLines.join('\\n')}`,\n 'utf-8',\n );\n};\n\nconst eventTimestamp = (e: LedgerEvent): number | null => {\n switch (e.kind) {\n case 'step':\n return e.timestampMs;\n case 'thought':\n return e.thought.timestampMs;\n case 'action':\n return e.action.timestampMs;\n case 'nav':\n return e.nav.timestampMs;\n case 'network':\n return e.net.timestampMs;\n case 'console':\n return e.con.timestampMs;\n case 'assertion':\n return e.assertion.timestampMs;\n }\n};\n\n// Lower rank sorts earlier when timestamps tie. Step headings come before per-step events.\nconst eventRank = (e: LedgerEvent): number => {\n switch (e.kind) {\n case 'step':\n return 0;\n case 'nav':\n return 1;\n case 'action':\n return 2;\n case 'thought':\n return 3;\n case 'network':\n return 4;\n case 'console':\n return 5;\n case 'assertion':\n return 6;\n }\n};\n","/**\n * Per-Step Rollup Builder\n *\n * @module workflows/diagnostics/materialize/step-rollup-builder\n * @description Writes one `steps/<NNN>-<stepId>.md` per workflow step. Each rollup is\n * self-contained: metadata, thoughts, in-window network/console events, navigation\n * transitions, assertion outcomes, and links to artifact paths.\n *\n * The agent reads the failed step's rollup *second* (after `summary.md`), then walks\n * backwards through prior rollups. Rollups are bounded by step duration, so they fit\n * in context even for long runs.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { computeStepWorkWindows, formatPrefix, formatRelative, oneLine } from './_shared.js';\nimport {\n resolveWorkspacePath,\n stepRollupRelativePath,\n thoughtsByStepRelativePath,\n workflowNodeRelativePath,\n WORKSPACE_PATHS,\n} from './paths.js';\n\n// ============================================================================\n// Inputs (subset of LedgerInput; reuses the same in-memory shape from materialize.ts)\n// ============================================================================\n\nexport interface StepRollupStep {\n id: string;\n nodeId: string;\n orderIndex: number;\n name: string | null;\n nodeType: string | null;\n status: string;\n startedAtMs: number | null;\n finishedAtMs: number | null;\n durationMs: number | null;\n errorMessage: string | null;\n cacheOutcome: string | null;\n cacheHitSource: string | null;\n}\n\nexport interface StepRollupThought {\n stepId: string | null;\n timestampMs: number;\n toolName: string | null;\n content: string;\n}\n\nexport interface StepRollupAction {\n action: string;\n target: string | null;\n url: string | null;\n timestampMs: number | null;\n success: boolean;\n isAnnotation: boolean;\n}\n\nexport interface StepRollupNavigation {\n timestampMs: number | null;\n action: string;\n from: string | null;\n to: string | null;\n crossHost: boolean;\n}\n\nexport interface StepRollupNetwork {\n timestampMs: number | null;\n url: string;\n method: string;\n status: number | null;\n}\n\nexport interface StepRollupConsole {\n timestampMs: number | null;\n type: string;\n text: string;\n}\n\nexport interface StepRollupAssertion {\n stepId: string;\n timestampMs: number | null;\n condition: string | null;\n severity: string | null;\n nonBlocking: boolean;\n passed: boolean;\n reason: string | null;\n}\n\n/** A kept screencast frame, projected onto the run-start axis. */\nexport interface StepRollupScreencastFrame {\n timestampMs: number;\n pageId: string;\n /** Workspace-relative path to the `.jpg`. */\n file: string;\n keptReason: string;\n}\n\nexport interface StepRollupInput {\n workspaceRoot: string;\n /** ISO. */\n runStartedAt: string | null;\n steps: ReadonlyArray<StepRollupStep>;\n thoughts: ReadonlyArray<StepRollupThought>;\n actions: ReadonlyArray<StepRollupAction>;\n navigation: ReadonlyArray<StepRollupNavigation>;\n network: ReadonlyArray<StepRollupNetwork>;\n consoleLogs: ReadonlyArray<StepRollupConsole>;\n assertions: ReadonlyArray<StepRollupAssertion>;\n /** Continuous screencast frames (real pixels), interleaved into each step's window. */\n screencastFrames?: ReadonlyArray<StepRollupScreencastFrame>;\n}\n\n// ============================================================================\n// Builder\n// ============================================================================\n\nexport const writeStepRollups = async (input: StepRollupInput): Promise<void> => {\n const baselineMs = input.runStartedAt ? Date.parse(input.runStartedAt) : null;\n const sortedSteps = input.steps.slice().sort((a, b) => a.orderIndex - b.orderIndex);\n\n // Pre-bucket time-stamped events for fast window assignment.\n const thoughtsByStepId = new Map<string, StepRollupThought[]>();\n for (const t of input.thoughts) {\n if (!t.stepId) continue;\n const list = thoughtsByStepId.get(t.stepId) ?? [];\n list.push(t);\n thoughtsByStepId.set(t.stepId, list);\n }\n\n const assertionsByStepId = new Map<string, StepRollupAssertion[]>();\n for (const a of input.assertions) {\n const list = assertionsByStepId.get(a.stepId) ?? [];\n list.push(a);\n assertionsByStepId.set(a.stepId, list);\n }\n\n // Step bounds for windowing untyped events (network, console, actions, nav).\n // For each step we use [startedAtMs, endMs) where endMs is finishedAtMs or\n // (next step's startedAtMs) — whichever fires first. This avoids gaps and\n // lets the agent attribute events that happened in the gap to the prior step.\n const bounds = computeStepBounds(sortedSteps);\n\n // True execution windows derived from step-started/step-completed annotations.\n // When present, these override the record bounds so a cache/playbook step whose\n // record timing is only the commit moment still surfaces the live work (clicks,\n // mutations) that ran under its playbook bracket. Steps without a matching\n // bracket fall back to `bounds` above.\n const workWindows = computeStepWorkWindows(sortedSteps, input.actions);\n\n // Build all rollup contents in-memory, then flush concurrently — distinct paths,\n // no contention.\n const writes: Array<{ relativePath: string; body: string }> = [];\n\n for (let i = 0; i < sortedSteps.length; i++) {\n const step = sortedSteps[i]!;\n const workWindow = workWindows.get(step.id);\n const window = workWindow ?? bounds[i]!;\n const lines: string[] = [];\n\n const startPrefix = formatPrefix(step.startedAtMs, baselineMs);\n const finishPrefix = formatPrefix(step.finishedAtMs, baselineMs);\n\n lines.push(\n `# Step ${step.orderIndex}: ${step.name ?? step.nodeId}`,\n );\n lines.push('');\n lines.push(`- nodeId: \\`${step.nodeId}\\``);\n if (step.nodeType) lines.push(`- nodeType: \\`${step.nodeType}\\``);\n lines.push(`- status: **${step.status}**`);\n lines.push(`- started: ${startPrefix}`);\n lines.push(`- finished: ${finishPrefix}`);\n if (step.durationMs !== null) lines.push(`- duration: ${step.durationMs}ms`);\n // When the live playbook bracket runs wider than the recorded step row (a\n // cache/playbook step whose row is the commit moment), call it out so the\n // action timeline below — which spans the real work — isn't read as a\n // contradiction of the 254ms-style record duration.\n if (\n workWindow &&\n baselineMs !== null &&\n (step.startedAtMs === null ||\n workWindow.startMs < step.startedAtMs ||\n (step.finishedAtMs !== null && workWindow.endMs > step.finishedAtMs))\n ) {\n const a = formatRelative(workWindow.startMs - baselineMs);\n const b = formatRelative(workWindow.endMs - baselineMs);\n lines.push(`- work window: ${a} → ${b} (live playbook run; events below span this, not the record duration)`);\n }\n if (step.cacheOutcome) {\n const src = step.cacheHitSource ? `/${step.cacheHitSource}` : '';\n lines.push(`- cache: ${step.cacheOutcome}${src}`);\n }\n if (step.errorMessage) {\n lines.push('');\n lines.push('## Error message');\n lines.push('');\n lines.push('```');\n lines.push(step.errorMessage);\n lines.push('```');\n }\n\n // Thoughts.\n const stepThoughts = (thoughtsByStepId.get(step.id) ?? []).slice().sort(\n (a, b) => a.timestampMs - b.timestampMs,\n );\n if (stepThoughts.length > 0) {\n lines.push('');\n lines.push('## Agent thoughts');\n lines.push('');\n for (const t of stepThoughts) {\n const tool = t.toolName ? ` [${t.toolName}]` : '';\n lines.push(`${formatPrefix(t.timestampMs, baselineMs)} thought${tool}: ${oneLine(t.content)}`);\n }\n }\n\n // Assertions.\n const stepAssertions = (assertionsByStepId.get(step.id) ?? []).slice();\n if (stepAssertions.length > 0) {\n lines.push('');\n lines.push('## Assertions');\n lines.push('');\n for (const a of stepAssertions) {\n const tag = a.passed ? 'passed' : 'FAILED';\n const severity = a.severity ? ` [${a.severity}${a.nonBlocking ? ' nonBlocking' : ''}]` : '';\n const cond = a.condition ?? '(no condition)';\n const reason = a.reason ? ` — ${oneLine(a.reason)}` : '';\n lines.push(`- ${tag}${severity}: ${oneLine(cond)}${reason}`);\n }\n }\n\n // Window-bound events.\n const inWindow = (ts: number | null): boolean => {\n if (ts === null) return false;\n if (window.startMs !== null && ts < window.startMs) return false;\n if (window.endMs !== null && ts >= window.endMs) return false;\n return true;\n };\n\n const windowActions = input.actions.filter((a) => inWindow(a.timestampMs)).slice().sort(byTs);\n if (windowActions.length > 0) {\n lines.push('');\n lines.push('## Action timeline (in step window)');\n lines.push('');\n for (const a of windowActions) {\n const target = a.target ? ` ${oneLine(a.target)}` : '';\n const url = a.url ? ` → ${a.url}` : '';\n const fail = a.success ? '' : ' (failed)';\n lines.push(`${formatPrefix(a.timestampMs, baselineMs)} action.${a.action}:${target}${url}${fail}`);\n }\n }\n\n const windowNav = input.navigation\n .filter((n) => inWindow(n.timestampMs))\n .slice()\n .sort(byTs);\n if (windowNav.length > 0) {\n lines.push('');\n lines.push('## Navigation (in step window)');\n lines.push('');\n for (const n of windowNav) {\n const cross = n.crossHost ? ' ⚠ cross-host' : '';\n lines.push(\n `${formatPrefix(n.timestampMs, baselineMs)} nav.${n.action}: ${n.from ?? '?'} → ${n.to ?? '?'}${cross}`,\n );\n }\n }\n\n const windowNet = input.network.filter((n) => inWindow(n.timestampMs)).slice().sort(byTs);\n if (windowNet.length > 0) {\n lines.push('');\n lines.push('## Network (in step window)');\n lines.push('');\n for (const n of windowNet) {\n const status = n.status !== null ? ` ${n.status}` : '';\n lines.push(`${formatPrefix(n.timestampMs, baselineMs)} ${n.method} ${n.url}${status}`);\n }\n }\n\n const windowCon = input.consoleLogs\n .filter((c) => inWindow(c.timestampMs))\n .slice()\n .sort(byTs);\n if (windowCon.length > 0) {\n lines.push('');\n lines.push('## Console (in step window)');\n lines.push('');\n for (const c of windowCon) {\n lines.push(`${formatPrefix(c.timestampMs, baselineMs)} console.${c.type}: ${oneLine(c.text)}`);\n }\n }\n\n // Continuous screencast — real pixels covering EVERY moment in the window,\n // including evaluate/wait moments where no action-snapshot frame exists. Cap\n // the listing but always keep the boundary + any failure-window frames so the\n // agent can confirm a step's *effect*, not just that an action fired.\n const windowFrames = (input.screencastFrames ?? [])\n .filter((f) => inWindow(f.timestampMs))\n .slice()\n .sort(byTs);\n if (windowFrames.length > 0) {\n const shown = capScreencastFrames(windowFrames, SCREENCAST_ROLLUP_CAP);\n lines.push('');\n lines.push('## Screencast frames (in step window)');\n lines.push('');\n for (const f of shown) {\n const page = f.pageId ? ` [page ${f.pageId}]` : '';\n lines.push(`${formatPrefix(f.timestampMs, baselineMs)} \\`${f.file}\\` (${f.keptReason})${page}`);\n }\n if (windowFrames.length > shown.length) {\n lines.push(\n `- …${windowFrames.length - shown.length} more in \\`${WORKSPACE_PATHS.browserScreencastIndex}\\``,\n );\n }\n }\n\n // Artifact references — paths to evidence files.\n lines.push('');\n lines.push('## Evidence files');\n lines.push('');\n lines.push(`- Thoughts: \\`${thoughtsByStepRelativePath(step.id)}\\``);\n lines.push(`- Workflow node: \\`${workflowNodeRelativePath(step.nodeId)}\\``);\n lines.push(\n `- Browser snapshots (if available): grep this step's timestamp in \\`${WORKSPACE_PATHS.browserActions}\\`, then \\`browser/doms/...\\` / \\`browser/frames/...\\` / \\`browser/a11y/...\\``,\n );\n lines.push(\n `- Continuous screencast (real pixels; covers evaluate/wait moments with no action frame): \\`${WORKSPACE_PATHS.browserScreencastIndex}\\` — read the \\`.jpg\\` nearest the moment to confirm a step's effect.`,\n );\n lines.push('');\n\n writes.push({\n relativePath: stepRollupRelativePath(step.orderIndex, step.id),\n body: lines.join('\\n'),\n });\n }\n\n await Promise.all(\n writes.map(({ relativePath, body }) =>\n fs.writeFile(resolveWorkspacePath(input.workspaceRoot, relativePath), body, 'utf-8'),\n ),\n );\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\ninterface StepBounds {\n startMs: number | null;\n endMs: number | null;\n}\n\nconst computeStepBounds = (sorted: ReadonlyArray<StepRollupStep>): StepBounds[] => {\n const bounds: StepBounds[] = [];\n for (let i = 0; i < sorted.length; i++) {\n const step = sorted[i]!;\n const next = sorted[i + 1];\n const startMs = step.startedAtMs;\n let endMs: number | null = step.finishedAtMs;\n if (endMs === null && next?.startedAtMs !== undefined) endMs = next.startedAtMs;\n bounds.push({ startMs, endMs });\n }\n return bounds;\n};\n\nconst byTs = <T extends { timestampMs: number | null }>(a: T, b: T): number => {\n if (a.timestampMs === null && b.timestampMs === null) return 0;\n if (a.timestampMs === null) return 1;\n if (b.timestampMs === null) return -1;\n return a.timestampMs - b.timestampMs;\n};\n\n/** Max screencast frames listed inline per step rollup (the rest stay in the index). */\nconst SCREENCAST_ROLLUP_CAP = 8;\n\n/**\n * Cap the inline screencast listing while preserving signal: always keep the\n * first and last frame and any non-`cadence` frame (action/step-boundary/\n * failure-window — the diagnostically meaningful ones); fill the remaining\n * budget with evenly-spaced cadence frames. Input is assumed sorted by time.\n */\nconst capScreencastFrames = <T extends { keptReason: string }>(\n frames: ReadonlyArray<T>,\n cap: number,\n): T[] => {\n if (frames.length <= cap) return frames.slice();\n const meaningful: number[] = [0, frames.length - 1];\n frames.forEach((f, i) => {\n if (f.keptReason !== 'cadence') meaningful.push(i);\n });\n const keep = new Set<number>(meaningful);\n\n if (keep.size >= cap) {\n // Meaningful frames already fill the budget — evenly subsample them.\n const sorted = [...keep].sort((a, b) => a - b);\n const stride = (sorted.length - 1) / (cap - 1);\n const picked = new Set<number>();\n for (let k = 0; k < cap; k++) picked.add(sorted[Math.round(k * stride)]!);\n return [...picked].sort((a, b) => a - b).map((i) => frames[i]!);\n }\n\n // Backfill the remaining budget with cadence frames spread evenly across time.\n const cadenceIdx = frames.map((_, i) => i).filter((i) => !keep.has(i));\n const need = cap - keep.size;\n if (cadenceIdx.length > 0 && need > 0) {\n const stride = cadenceIdx.length / need;\n for (let k = 0; k < need; k++) keep.add(cadenceIdx[Math.floor(k * stride)]!);\n }\n return [...keep].sort((a, b) => a - b).map((i) => frames[i]!);\n};\n\n","/**\n * Summary Builder\n *\n * @module workflows/diagnostics/materialize/summary-builder\n * @description Writes `summary.md` — the always-fits one-pager that's the agent's primary\n * entry point. Size-bounded by construction (counts and rollups, never per-event detail);\n * test asserts ≤80 lines for any input.\n */\n\nimport * as fs from 'node:fs/promises';\nimport { formatRelative, oneLine, truncate } from './_shared.js';\nimport {\n resolveWorkspacePath,\n stepRollupRelativePath,\n WORKSPACE_PATHS,\n} from './paths.js';\n\nconst MAX_NOTABLE_EVENTS = 5;\nconst MAX_HISTORY_LOOKBACK = 10;\n\n// Upstream-divergence heuristic thresholds. Deliberately conservative — these surface\n// *candidates to investigate*, not verdicts, so a false positive only costs the agent a\n// glance. Tunable from here.\nconst MAX_DIVERGENCE_CANDIDATES = 5;\nconst MAX_INTENDED_INPUTS = 4;\n/** Churn outlier (heuristic B): a non-failed step must clear BOTH to flag. */\nconst CHURN_MIN_THOUGHTS = 8;\nconst CHURN_MEDIAN_MULTIPLE = 1.5;\nconst CHURN_MIN_DOM_PROBES = 2;\n\nexport interface SummaryStepVariable {\n key: string;\n value: string | null;\n source: string | null;\n /** True when extracted from the live page (carries an extractor expression). */\n extracted: boolean;\n}\n\nexport interface SummaryStep {\n id: string;\n orderIndex: number;\n name: string | null;\n status: string;\n startedAtMs: number | null;\n durationMs: number | null;\n cacheOutcome: string | null;\n cacheHitSource: string | null;\n errorMessage: string | null;\n /** Why a cache replay ended the way it did (e.g. 'replay_failed'). For divergence hints. */\n cacheOutcomeReason?: string | null;\n /** Cache replay failure bucket (e.g. 'element_absent'). For divergence hints. */\n cacheFailureCategory?: string | null;\n /** Variables this step set (configured inputs + extracted values). For divergence hints. */\n variablesSet?: ReadonlyArray<SummaryStepVariable>;\n /** Total agent thoughts attributed to this step. For the churn heuristic. */\n thoughtCount?: number;\n /** Thoughts that were direct DOM probes (run_code/evaluate). For the churn heuristic. */\n domProbeCount?: number;\n}\n\nexport interface SummaryNetwork {\n timestampMs: number | null;\n url: string;\n method: string;\n status: number | null;\n}\n\nexport interface SummaryConsole {\n timestampMs: number | null;\n type: string;\n text: string;\n}\n\nexport interface SummaryNavigation {\n timestampMs: number | null;\n from: string | null;\n to: string | null;\n crossHost: boolean;\n}\n\nexport interface SummaryRecentRun {\n testRunId: string;\n workflowRunId: string | null;\n status: string;\n /** ISO. */\n startedAt: string | null;\n /** ISO. */\n finishedAt: string | null;\n errorMessage?: string | null;\n}\n\nexport interface SummaryLastGreenComparison {\n greenRunId: string;\n greenTestRunId: string;\n greenStartedAt: string | null;\n /** True/false when computed, null when the comparison could not be made. */\n authoredUnchanged: boolean | null;\n}\n\nexport interface SummarySeedRun {\n seedWorkflowId: string | null;\n seedWorkflowName: string | null;\n seedRunId: string | null;\n status: string;\n errorMessage: string | null;\n failedStepName: string | null;\n failedStepError: string | null;\n}\n\n/**\n * Classification of the recent-history pattern leading into this failure. Gates the\n * regression steer: a single green→red is trustworthy evidence of an app change only in\n * `STABLE_REGRESSION`. `FLAKY` histories must NOT be read as app changes.\n */\nexport type HistoryRegime = 'STABLE_REGRESSION' | 'FLAKY' | 'NEW' | 'PERSISTENT_FAIL';\n\n// Test-run status vocabulary: a clean pass is `success` (`passed` kept for legacy/fixtures);\n// `flaky_success` passed only after a retry — it counts as a pass but is itself a flakiness\n// signal. Failure-ish terminal states are `failed`/`timeout`/`degraded`; everything else\n// (canceled, skipped, queued, waiting, running) carries no pass/fail signal.\nconst isCleanPassStatus = (s: string): boolean => s === 'passed' || s === 'success';\nconst isFlakyPassStatus = (s: string): boolean => s === 'flaky_success';\nconst isPassStatus = (s: string): boolean => isCleanPassStatus(s) || isFlakyPassStatus(s);\nconst isFailStatus = (s: string): boolean =>\n s === 'failed' || s === 'timeout' || s === 'degraded';\n\n/**\n * Classify the recent history (most-recent-first, current run excluded) into a regime.\n *\n * - `NEW` — fewer than 2 prior pass/fail runs; not enough signal.\n * - `PERSISTENT_FAIL` — no passes in the window; consistently failing.\n * - `STABLE_REGRESSION` — the window was clean-green (no fails, no flaky passes) or a solid\n * clean-green streak (≥3 consecutive `success` immediately before the break). A pass→fail\n * here is a real break.\n * - `FLAKY` — passes and fails interleave, or any `flaky_success` appears, without a solid\n * recent clean-green streak; a single green→red is not trustworthy evidence of an app change.\n */\nexport const classifyHistoryRegime = (\n others: ReadonlyArray<{ status: string }>,\n): HistoryRegime => {\n const seq = others.map((r) => r.status).filter((s) => isPassStatus(s) || isFailStatus(s));\n if (seq.length < 2) return 'NEW';\n const passes = seq.filter(isPassStatus).length;\n if (passes === 0) return 'PERSISTENT_FAIL';\n const fails = seq.filter(isFailStatus).length;\n const hasFlaky = seq.some(isFlakyPassStatus);\n // Clean-green streak immediately before the break (flaky passes do not extend it).\n let cleanGreenStreak = 0;\n for (const s of seq) {\n if (isCleanPassStatus(s)) cleanGreenStreak++;\n else break;\n }\n if ((fails === 0 && !hasFlaky) || cleanGreenStreak >= 3) return 'STABLE_REGRESSION';\n return 'FLAKY';\n};\n\n/**\n * How the workspace's consumer materializes a comparison run.\n *\n * - `'cli'` — a human (or CLI skill) reading a locally materialized workspace;\n * the history hint prints the `canary workflow debug materialize` command.\n * - `'agent-tool'` — the in-process v2 diagnostic agent, whose sandboxed bash\n * cannot run the CLI; the history hint points at its `materialize_run` tool.\n * - `'none'` — a comparison-leaf workspace (itself materialized as a baseline);\n * the history hint reports stats only — no materialization instruction and no\n * regime steer, since nobody investigates *from* this workspace.\n */\nexport type GreenRunAccess = 'agent-tool' | 'cli' | 'none';\n\nexport interface SummaryInput {\n workspaceRoot: string;\n runId: string;\n workflowName: string;\n runStatus: string;\n /** ISO. */\n runStartedAt: string | null;\n /** ISO. */\n runFinishedAt: string | null;\n reportedFailure: {\n failedStepId: string | null;\n failedStepName: string | null;\n failedStepOrderIndex: number | null;\n errorMessage: string | null;\n };\n steps: ReadonlyArray<SummaryStep>;\n network: ReadonlyArray<SummaryNetwork>;\n consoleLogs: ReadonlyArray<SummaryConsole>;\n navigation: ReadonlyArray<SummaryNavigation>;\n /**\n * Mid-run browser crashes (page crash / context closed / disconnect) that were\n * auto-recovered. Surfaced under \"Notable events\" so the diagnostic agent can\n * weigh whether a crash — not the test — caused the failure.\n */\n crashes?: ReadonlyArray<{ label: string; relativeTimestampMs: number }>;\n recentRuns: ReadonlyArray<SummaryRecentRun>;\n /** Seed flows this run provisioned; a seed failure is a common upstream cause. */\n seedRuns?: ReadonlyArray<SummarySeedRun>;\n /**\n * Variable keys (`$var.X`) the failing step's node config references. When one was\n * produced by an earlier extractor step, that producer becomes an upstream-divergence\n * candidate (the lineage heuristic). Empty when unknown.\n */\n failedStepReferencedVars?: ReadonlyArray<string>;\n /** Authored-definition comparison vs the most recent green run; null when none. */\n lastGreenComparison?: SummaryLastGreenComparison | null;\n /** How this workspace's consumer materializes comparison runs. Defaults to `'cli'`. */\n greenRunAccess?: GreenRunAccess;\n}\n\nexport const writeSummary = async (input: SummaryInput): Promise<void> => {\n const baselineMs = input.runStartedAt ? Date.parse(input.runStartedAt) : null;\n const finishedMs = input.runFinishedAt ? Date.parse(input.runFinishedAt) : null;\n const durationMs =\n baselineMs !== null && finishedMs !== null ? finishedMs - baselineMs : null;\n\n const lines: string[] = [];\n\n // Header.\n lines.push(\n `# Run ${input.runId} — workflow \"${input.workflowName}\" — status: ${input.runStatus}`,\n );\n const durationStr = durationMs !== null ? `${(durationMs / 1000).toFixed(3)}s` : 'unknown';\n lines.push(\n `runStartedAt: ${input.runStartedAt ?? 'unknown'} duration: ${durationStr}`,\n );\n lines.push('');\n\n // Reported failure.\n if (input.runStatus === 'failed') {\n lines.push('## Reported failure');\n if (input.reportedFailure.failedStepName) {\n const ordinal =\n input.reportedFailure.failedStepOrderIndex !== null\n ? ` (step ${input.reportedFailure.failedStepOrderIndex})`\n : '';\n const err = input.reportedFailure.errorMessage\n ? ` — ${oneLine(input.reportedFailure.errorMessage)}`\n : '';\n lines.push(\n `Step${ordinal}: **${input.reportedFailure.failedStepName}**${err}`,\n );\n } else if (input.reportedFailure.errorMessage) {\n lines.push(`Run-level error: ${oneLine(input.reportedFailure.errorMessage)}`);\n } else {\n lines.push('(no failed step identified — investigate run-level state)');\n }\n lines.push('**Hypothesis. Verify before trusting — root cause may be upstream.**');\n lines.push('');\n }\n\n // Candidate upstream divergences — heuristic hints (NOT verdicts) that point the\n // walk-backwards scan at non-failed steps worth confirming first. Omitted when empty.\n for (const l of buildDivergenceSection(input)) lines.push(l);\n\n // Seed flows — a seed runs as its own workflow run, so its failure won't appear\n // in the step table below. A failed seed is a frequent upstream root cause.\n const seedRuns = input.seedRuns ?? [];\n if (seedRuns.length > 0) {\n lines.push('## Seed flows');\n for (const seed of seedRuns.slice(0, MAX_NOTABLE_EVENTS)) {\n const label = seed.seedWorkflowName ?? seed.seedWorkflowId ?? 'seed flow';\n const glyph = STATUS_GLYPH[seed.status] ?? '?';\n const detail =\n seed.status === 'failed'\n ? seed.failedStepName\n ? ` — failed at \"${seed.failedStepName}\"${seed.failedStepError ? `: ${truncate(oneLine(seed.failedStepError), 80)}` : ''}`\n : seed.errorMessage\n ? ` — ${truncate(oneLine(seed.errorMessage), 80)}`\n : ' — failed'\n : '';\n const ref = seed.seedRunId ? ` (seed run ${seed.seedRunId})` : '';\n lines.push(`- ${glyph} ${label}${detail}${ref}`);\n }\n if (seedRuns.some((s) => s.status === 'failed')) {\n lines.push('A failed seed often IS the root cause — inspect the seed run before the steps below.');\n }\n lines.push('');\n }\n\n // Step table.\n const sortedSteps = input.steps.slice().sort((a, b) => a.orderIndex - b.orderIndex);\n const counts = countByStatus(sortedSteps);\n const summaryLine = `${sortedSteps.length} total — ${formatCounts(counts)}`;\n lines.push(`## Steps (${summaryLine})`);\n const renderedSteps = sortedSteps.map((s) => formatStepRow(s, baselineMs));\n // Cap to first 30 + last failed/error steps if a run is huge — but normally\n // every step gets a row. Test pins ≤80 total lines so giant runs degrade gracefully.\n const visibleSteps = renderedSteps.length > 30\n ? [\n ...renderedSteps.slice(0, 25),\n ` … (${renderedSteps.length - 30} more steps elided — see ledger.md)`,\n ...renderedSteps.slice(-5),\n ]\n : renderedSteps;\n for (const row of visibleSteps) lines.push(row);\n lines.push('');\n\n // Errors observed (capped).\n const networkErrors = input.network.filter(\n (n) => typeof n.status === 'number' && n.status >= 400,\n );\n const consoleErrors = input.consoleLogs.filter(\n (c) => c.type === 'error' || c.type === 'warning',\n );\n if (networkErrors.length > 0 || consoleErrors.length > 0) {\n lines.push('## Errors observed');\n const ne = networkErrors.length;\n const ce = consoleErrors.length;\n if (ne > 0) {\n const sample = networkErrors[0]!;\n lines.push(\n `- ${ne}× network ${sample.status ?? '?'}: ${sample.method} ${sample.url}${\n sample.timestampMs !== null\n ? ` ${formatRelativePrefix(sample.timestampMs, baselineMs)}`\n : ''\n }${ne > 1 ? ` (+${ne - 1} more — see logs/network-errors.jsonl)` : ''}`,\n );\n }\n if (ce > 0) {\n const sample = consoleErrors[0]!;\n lines.push(\n `- ${ce}× console.${sample.type}: ${truncate(oneLine(sample.text), 100)}${\n sample.timestampMs !== null\n ? ` ${formatRelativePrefix(sample.timestampMs, baselineMs)}`\n : ''\n }${ce > 1 ? ` (+${ce - 1} more — see logs/console-errors.jsonl)` : ''}`,\n );\n }\n lines.push('');\n }\n\n // Notable events: browser crashes, cross-host navigations, cache misses on the failed step.\n const notables: string[] = [];\n for (const c of (input.crashes ?? []).slice(0, MAX_NOTABLE_EVENTS)) {\n notables.push(`- browser crash auto-recovered: ${c.label} [T+${formatRelative(c.relativeTimestampMs)}]`);\n }\n const crossHost = input.navigation.filter((n) => n.crossHost);\n for (const n of crossHost.slice(0, MAX_NOTABLE_EVENTS)) {\n notables.push(\n `- cross-host nav: ${n.from ?? '?'} → ${n.to ?? '?'}${\n n.timestampMs !== null\n ? ` ${formatRelativePrefix(n.timestampMs, baselineMs)}`\n : ''\n }`,\n );\n }\n const failedStep = sortedSteps.find((s) => s.status === 'failed');\n if (failedStep && failedStep.cacheOutcome) {\n notables.push(\n `- failed step cache outcome: ${failedStep.cacheOutcome}${failedStep.cacheHitSource ? `/${failedStep.cacheHitSource}` : ''}`,\n );\n }\n if (notables.length > 0) {\n lines.push('## Notable events');\n for (const n of notables) lines.push(n);\n lines.push('');\n }\n\n // History hint.\n const historyHint = buildHistoryHint(\n input.recentRuns,\n input.runId,\n input.lastGreenComparison ?? null,\n input.greenRunAccess ?? 'cli',\n );\n if (historyHint.length > 0) {\n lines.push('## History');\n for (const h of historyHint) lines.push(h);\n lines.push('');\n }\n\n // Drill-down pointers.\n lines.push('## Drill-down');\n const failedRollup =\n input.reportedFailure.failedStepId && failedStep\n ? stepRollupRelativePath(failedStep.orderIndex, failedStep.id)\n : null;\n if (failedRollup) {\n lines.push(`- Failed step rollup: \\`${failedRollup}\\``);\n }\n lines.push(`- Per-step rollups: \\`${WORKSPACE_PATHS.steps}/*.md\\` (ls steps/ for the full list)`);\n lines.push(`- Full ledger TOC: \\`${WORKSPACE_PATHS.ledgerIndex}\\` (read before windowing into ledger.md)`);\n lines.push(`- Screenshots: \\`${WORKSPACE_PATHS.browserFrames}/<NNNN>-...png\\` (read with vision)`);\n lines.push(`- Workflow nodes: \\`${WORKSPACE_PATHS.workflowNodes}/<nodeId>.json\\``);\n lines.push('');\n\n await fs.writeFile(\n resolveWorkspacePath(input.workspaceRoot, WORKSPACE_PATHS.summary),\n lines.join('\\n'),\n 'utf-8',\n );\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nconst STATUS_GLYPH: Record<string, string> = {\n success: '✓',\n passed: '✓',\n failed: '✗',\n skipped: '-',\n pending: '·',\n running: '⋯',\n waiting: '⋯',\n canceled: '⊘',\n};\n\nconst formatStepRow = (s: SummaryStep, baselineMs: number | null): string => {\n const glyph = STATUS_GLYPH[s.status] ?? '?';\n const ord = String(s.orderIndex).padStart(3, ' ');\n const tplus =\n s.startedAtMs !== null && baselineMs !== null\n ? formatRelative(s.startedAtMs - baselineMs).padStart(11, ' ')\n : ' ?';\n const name = s.name ?? '(unnamed)';\n const namePadded = truncate(name, 35).padEnd(35, ' ');\n const dur =\n s.status === 'failed'\n ? `FAILED${s.errorMessage ? ` — ${truncate(oneLine(s.errorMessage), 40)}` : ''}`\n : s.status === 'skipped'\n ? 'skipped'\n : s.durationMs !== null\n ? `${s.durationMs}ms`\n : '?';\n const cache = s.cacheOutcome\n ? ` cache: ${s.cacheOutcome}${s.cacheHitSource ? `/${s.cacheHitSource}` : ''}`\n : '';\n return ` ${ord} ${glyph} ${tplus} ${namePadded} ${dur}${cache}`;\n};\n\nconst countByStatus = (steps: ReadonlyArray<SummaryStep>): Map<string, number> => {\n const m = new Map<string, number>();\n for (const s of steps) m.set(s.status, (m.get(s.status) ?? 0) + 1);\n return m;\n};\n\nconst formatCounts = (counts: Map<string, number>): string => {\n const order = ['success', 'passed', 'failed', 'skipped', 'pending', 'running', 'waiting', 'canceled'];\n const parts: string[] = [];\n const seen = new Set<string>();\n for (const key of order) {\n if (counts.has(key)) {\n const count = counts.get(key)!;\n const emphasis = key === 'failed' && count > 0 ? `**${count} ${key.toUpperCase()}**` : `${count} ${key}`;\n parts.push(emphasis);\n seen.add(key);\n }\n }\n for (const [k, v] of counts) {\n if (!seen.has(k)) parts.push(`${v} ${k}`);\n }\n return parts.join(', ');\n};\n\nconst buildHistoryHint = (\n runs: ReadonlyArray<SummaryRecentRun>,\n currentRunId: string,\n lastGreenComparison: SummaryLastGreenComparison | null,\n greenRunAccess: GreenRunAccess,\n): string[] => {\n const lookback = runs.slice(0, MAX_HISTORY_LOOKBACK);\n if (lookback.length <= 1) return [];\n // Exclude the current run from the comparison if it's in the list.\n const others = lookback.filter((r) => r.workflowRunId !== currentRunId);\n if (others.length === 0) return [];\n const passed = others.filter((r) => isPassStatus(r.status)).length;\n const failed = others.filter((r) => isFailStatus(r.status)).length;\n const lastGreen = others.find((r) => isPassStatus(r.status));\n const regime = classifyHistoryRegime(others);\n const out: string[] = [];\n out.push(\n `${passed} of last ${others.length} ran passed; ${failed} failed. Regime: ${regime}.`,\n );\n if (lastGreen) {\n out.push(\n `Most recent green: testRunId=${lastGreen.testRunId}${\n lastGreen.startedAt ? ` (${lastGreen.startedAt.slice(0, 10)})` : ''\n }`,\n );\n // Comparison-leaf workspaces report stats only — no instruction, no steer.\n if (greenRunAccess === 'none') return out;\n // Single source of truth for the printed id: prefer the data layer's\n // lastGreenComparison.greenRunId — the SAME id the orchestrator's comparison\n // gate keys on — so the agent is never steered to an id the gate (and\n // findRunById) won't accept. The recentRuns-derived fallback only applies\n // when the comparison metadata is absent entirely.\n const greenRunId =\n lastGreenComparison?.greenRunId ?? lastGreen.workflowRunId ?? lastGreen.testRunId;\n out.push(\n greenRunAccess === 'agent-tool'\n ? `Comparison is REQUIRED — call the materialize_run tool with runId=${greenRunId}, then read the returned workspace under history/runs/${greenRunId}/.`\n : `Comparison is REQUIRED — materialize via: canary workflow debug materialize ${greenRunId} --out history/last-green/`,\n );\n }\n\n // Regime-gated steer. The regime narrows the hypothesis space but never forces a\n // verdict: an unchanged authored test eliminates only test_underspecified — a legit\n // app change, an app regression, an agent error, or a platform error all remain live\n // until the comparison discriminates between them.\n const authoredUnchanged = lastGreenComparison?.authoredUnchanged ?? null;\n const greenDate = lastGreen?.startedAt ? ` (${lastGreen.startedAt.slice(0, 10)})` : '';\n if (regime === 'STABLE_REGRESSION' && lastGreen) {\n if (authoredUnchanged === true) {\n out.push(\n `AUTHORED TEST UNCHANGED since last green${greenDate} — the authored workflow is byte-identical across this pass→fail boundary, so test_underspecified is off the table. That leaves FOUR live hypotheses: a legitimate app change (app_changed), an app regression (software_bug), an agent error (agent_confusion — e.g. verification/interpretation drift), or a platform error (platform_error — cache/replay/sandbox machinery). Do NOT default to app_changed. Follow the green→red methodology: establish HOW each side of the boundary executed (cache replay vs live agent), then compare. Only classify app_changed after confirming a concrete behavior delta against the materialized green run, and note in openQuestions that intent could not be verified from the sandbox.`,\n );\n } else if (authoredUnchanged === false) {\n out.push(\n `AUTHORED TEST CHANGED since last green${greenDate} — the test definition was edited. Compare to judge whether the new instructions are ambiguous (test_underspecified) before blaming the app.`,\n );\n } else {\n out.push(\n `Stably green before this break — comparison REQUIRED. The pass→fail boundary alone does not discriminate between app_changed, software_bug, agent_confusion, and platform_error; materialize the green run and follow the green→red methodology before classifying.`,\n );\n }\n } else if (regime === 'FLAKY') {\n out.push(\n `This test is FLAKY (pass/fail oscillated over the window) — a single green→red does NOT imply an app change. Weigh agent_confusion / intermittent dependency_issue / data_collision. Comparison may still help, but do not force an app_changed verdict without a clear, persistent behavior delta.`,\n );\n }\n return out;\n};\n\nconst formatRelativePrefix = (timestampMs: number, baselineMs: number | null): string =>\n baselineMs !== null ? `[${formatRelative(timestampMs - baselineMs)}]` : '[T+?]';\n\n// ============================================================================\n// Candidate upstream divergences (heuristic hints)\n// ============================================================================\n\ninterface DivergenceCandidate {\n step: SummaryStep;\n /** One short clause per fired heuristic. */\n reasons: string[];\n /** Configured input values (heuristic C enrichment) — annotation only. */\n intendedInputs: SummaryStepVariable[];\n /** True when a higher-precision heuristic (B churn or D lineage) fired, vs A-only. */\n highSignal: boolean;\n}\n\n/**\n * Compute non-failed upstream steps worth investigating first. Domain-agnostic,\n * structural/statistical signals only — never app-specific. A step is a candidate when\n * ANY heuristic fires:\n *\n * A. it ejected from cache replay to the live agent (`cacheOutcome === 'fallback'`),\n * so its post-state was never cache-verified;\n * B. its agent churn is a high outlier (many thoughts + repeated DOM probes) yet it\n * reported success — a confused-but-green step;\n * D. it produced (via an extractor) a `$var.X` the failing step depends on — confirm\n * that value is valid before reading the current page state as external behavior.\n *\n * C is enrichment, not a trigger: flagged steps get their configured input values\n * appended so the agent can compare intent against the live UI.\n */\nconst computeCandidateUpstreamDivergences = (input: SummaryInput): DivergenceCandidate[] => {\n // Failure investigations only — a clean pass has no \"failure\" to walk back from.\n if (isCleanPassStatus(input.runStatus)) return [];\n const steps = input.steps;\n if (steps.length === 0) return [];\n\n // Failure anchor: only steps strictly before it are \"upstream\". Null when the failure\n // is run-level with no failed-step index — then every non-failed step is eligible.\n const anchor = input.reportedFailure.failedStepOrderIndex;\n const referencedVars = new Set(input.failedStepReferencedVars ?? []);\n\n // Churn outlier threshold (heuristic B): scale to the run's distribution but floor at\n // an absolute minimum. Median is taken over ALL steps (zero-churn steps included) so a\n // lone churny step still reads as an outlier against its quiet neighbors; in a uniformly\n // churny run the median rises and suppresses the noise. The CHURN_MIN_THOUGHTS floor is\n // the effective bar in the common case where most steps have little churn.\n const allCounts = steps.map((s) => s.thoughtCount ?? 0).sort((a, b) => a - b);\n const median = allCounts.length === 0 ? 0 : allCounts[Math.floor((allCounts.length - 1) / 2)]!;\n const churnThreshold = Math.max(CHURN_MIN_THOUGHTS, median * CHURN_MEDIAN_MULTIPLE);\n const maxThoughts = allCounts.length > 0 ? allCounts[allCounts.length - 1]! : 0;\n\n const candidates: DivergenceCandidate[] = [];\n for (const s of steps) {\n if (s.status === 'failed') continue;\n if (anchor !== null && s.orderIndex >= anchor) continue;\n\n const reasons: string[] = [];\n let highSignal = false;\n\n // A — cache eject on a non-failed step. Lower precision: in a run where an app change\n // broke many recipes, most steps eject, so A alone is ranked below B/D below.\n if (s.cacheOutcome === 'fallback') {\n const why = s.cacheFailureCategory ?? s.cacheOutcomeReason;\n reasons.push(`ejected cache→live${why ? ` (${why})` : ''}; post-state never cache-verified`);\n }\n\n // B — agent-churn outlier yet marked success.\n const thoughts = s.thoughtCount ?? 0;\n const probes = s.domProbeCount ?? 0;\n if (thoughts >= churnThreshold && probes >= CHURN_MIN_DOM_PROBES) {\n const lead = thoughts === maxThoughts ? 'highest churn in run' : 'high agent churn';\n reasons.push(`${lead} (${thoughts} thoughts, ${probes} DOM probes) yet marked ${s.status}`);\n highSignal = true;\n }\n\n // D — self-created-artifact lineage: this step extracted a $var the failing step uses.\n for (const v of s.variablesSet ?? []) {\n if (v.extracted && referencedVars.has(v.key)) {\n reasons.push(\n `produced $var.${v.key} (extracted), which the failing step depends on — confirm that ` +\n 'value is valid before treating the current page state as external behavior',\n );\n highSignal = true;\n }\n }\n\n if (reasons.length === 0) continue;\n\n // C — enrichment: configured inputs on the flagged step (annotation, not a trigger).\n const intendedInputs = (s.variablesSet ?? [])\n .filter((v) => v.source === 'inputValue' && v.value !== null)\n .slice(0, MAX_INTENDED_INPUTS);\n\n candidates.push({ step: s, reasons, intendedInputs, highSignal });\n }\n\n // Rank high-signal (B/D) candidates ahead of A-only before the cap, so a run where many\n // steps merely ejected cache can't crowd the higher-precision churn/lineage hints out of\n // the list. Then restore order-index order so the displayed block reads chronologically.\n candidates.sort((a, b) =>\n a.highSignal !== b.highSignal\n ? a.highSignal\n ? -1\n : 1\n : a.step.orderIndex - b.step.orderIndex,\n );\n const selected = candidates.slice(0, MAX_DIVERGENCE_CANDIDATES);\n selected.sort((a, b) => a.step.orderIndex - b.step.orderIndex);\n return selected;\n};\n\n/** Render the \"⚠ Candidate upstream divergences\" section, or [] when there are none. */\nconst buildDivergenceSection = (input: SummaryInput): string[] => {\n const candidates = computeCandidateUpstreamDivergences(input);\n if (candidates.length === 0) return [];\n const out: string[] = [];\n out.push('## ⚠ Candidate upstream divergences');\n out.push(\n 'Heuristic candidates only — each is a place to START, not a root cause. Confirm or rule out ' +\n \"every one by walking backwards and verifying the step's EFFECT (the value selected, the field \" +\n 'populated, the record created) from its screenshot/DOM — not its success flag. This list is NOT ' +\n 'exhaustive; an upstream cause can exist with no hint here.',\n );\n for (const c of candidates) {\n const name = c.step.name ?? '(unnamed)';\n const reasons = c.reasons.join('; ');\n const inputs =\n c.intendedInputs.length > 0\n ? ` [configured inputs: ${c.intendedInputs\n .map((v) => `${v.key}=${truncate(oneLine(String(v.value)), 40)}`)\n .join(', ')}]`\n : '';\n const ref = ` \\`${stepRollupRelativePath(c.step.orderIndex, c.step.id)}\\``;\n out.push(`- Step ${c.step.orderIndex} \"${name}\": ${reasons}.${inputs}${ref}`);\n }\n out.push('');\n return out;\n};\n"],"mappings":"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","names":["fs","step","fs","fs","fs","fs","fs","fs","fs","fs","fs","path"]}
|
|
@@ -12,14 +12,14 @@ import {
|
|
|
12
12
|
captureSubstrateV2,
|
|
13
13
|
consoleLogger,
|
|
14
14
|
parseSnapshot
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-EPMDUCEA.js";
|
|
16
16
|
import "./chunk-S3Q7MDCS.js";
|
|
17
17
|
import {
|
|
18
18
|
MACRO_PATTERN,
|
|
19
19
|
isVolatileIdentifier,
|
|
20
20
|
stableAttrSelector,
|
|
21
21
|
stableIdentifierPrefix
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-QX7RZ5CZ.js";
|
|
23
23
|
import "./chunk-2EHYDUHX.js";
|
|
24
24
|
import "./chunk-ICKB3EOT.js";
|
|
25
25
|
|
|
@@ -6002,4 +6002,4 @@ export {
|
|
|
6002
6002
|
verifySelectorAgainstRef,
|
|
6003
6003
|
waitForTraceDomHydration
|
|
6004
6004
|
};
|
|
6005
|
-
//# sourceMappingURL=src-
|
|
6005
|
+
//# sourceMappingURL=src-FW7TIXEQ.js.map
|
|
@@ -7,14 +7,14 @@ import {
|
|
|
7
7
|
fetchList,
|
|
8
8
|
promptChoice,
|
|
9
9
|
selectProperty
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SZOPRIBA.js";
|
|
11
11
|
import "./chunk-H3LWYSKY.js";
|
|
12
12
|
import {
|
|
13
13
|
getArgValue,
|
|
14
14
|
resolveConfig
|
|
15
15
|
} from "./chunk-ZPPG4MGR.js";
|
|
16
16
|
import "./chunk-S3Q7MDCS.js";
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-QX7RZ5CZ.js";
|
|
18
18
|
import "./chunk-ZSOAFMES.js";
|
|
19
19
|
import "./chunk-ICKB3EOT.js";
|
|
20
20
|
|
|
@@ -149,4 +149,4 @@ Use \`canary session\` commands to interact with the browser.`);
|
|
|
149
149
|
export {
|
|
150
150
|
runLocalStart
|
|
151
151
|
};
|
|
152
|
-
//# sourceMappingURL=start-
|
|
152
|
+
//# sourceMappingURL=start-IEUE53KY.js.map
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
formatUnknownTagsError,
|
|
6
6
|
resolveTagNames,
|
|
7
7
|
runTag
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-OCT6HQZK.js";
|
|
9
|
+
import "./chunk-SZOPRIBA.js";
|
|
10
10
|
import "./chunk-H3LWYSKY.js";
|
|
11
11
|
import "./chunk-ZPPG4MGR.js";
|
|
12
12
|
import "./chunk-S3Q7MDCS.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-QX7RZ5CZ.js";
|
|
14
14
|
import "./chunk-ZSOAFMES.js";
|
|
15
15
|
import "./chunk-ICKB3EOT.js";
|
|
16
16
|
export {
|
|
@@ -20,4 +20,4 @@ export {
|
|
|
20
20
|
resolveTagNames,
|
|
21
21
|
runTag
|
|
22
22
|
};
|
|
23
|
-
//# sourceMappingURL=tag-
|
|
23
|
+
//# sourceMappingURL=tag-J5SX224K.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __cr } from "module"; import { fileURLToPath as __fup } from "url"; import { dirname as __dn } from "path"; const require = __cr(import.meta.url); const __filename = __fup(import.meta.url); const __dirname = __dn(__filename);
|
|
2
2
|
import {
|
|
3
3
|
apiRequest
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SZOPRIBA.js";
|
|
5
5
|
import "./chunk-H3LWYSKY.js";
|
|
6
6
|
import {
|
|
7
7
|
getArgValue,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
resolveConfig
|
|
10
10
|
} from "./chunk-ZPPG4MGR.js";
|
|
11
11
|
import "./chunk-S3Q7MDCS.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-QX7RZ5CZ.js";
|
|
13
13
|
import "./chunk-ZSOAFMES.js";
|
|
14
14
|
import "./chunk-ICKB3EOT.js";
|
|
15
15
|
|
|
@@ -920,4 +920,4 @@ async function runTask(argv) {
|
|
|
920
920
|
export {
|
|
921
921
|
runTask
|
|
922
922
|
};
|
|
923
|
-
//# sourceMappingURL=task-
|
|
923
|
+
//# sourceMappingURL=task-ONZVZQAQ.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createRequire as __cr } from "module"; import { fileURLToPath as __fup } from "url"; import { dirname as __dn } from "path"; const require = __cr(import.meta.url); const __filename = __fup(import.meta.url); const __dirname = __dn(__filename);
|
|
2
2
|
import {
|
|
3
3
|
runRemoteTest
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LNX22N2L.js";
|
|
5
5
|
import {
|
|
6
6
|
isTriageEnabledForExecution
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-IC3HQSRW.js";
|
|
8
8
|
import {
|
|
9
9
|
apiRequest
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SZOPRIBA.js";
|
|
11
11
|
import "./chunk-H3LWYSKY.js";
|
|
12
12
|
import {
|
|
13
13
|
getArgValue,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
resolveConfig
|
|
16
16
|
} from "./chunk-ZPPG4MGR.js";
|
|
17
17
|
import "./chunk-S3Q7MDCS.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-QX7RZ5CZ.js";
|
|
19
19
|
import "./chunk-ZSOAFMES.js";
|
|
20
20
|
import "./chunk-ICKB3EOT.js";
|
|
21
21
|
|
|
@@ -395,4 +395,4 @@ async function runTestSuite(argv) {
|
|
|
395
395
|
export {
|
|
396
396
|
runTestSuite
|
|
397
397
|
};
|
|
398
|
-
//# sourceMappingURL=test-suite-
|
|
398
|
+
//# sourceMappingURL=test-suite-STGE6IAV.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { createRequire as __cr } from "module"; import { fileURLToPath as __fup } from "url"; import { dirname as __dn } from "path"; const require = __cr(import.meta.url); const __filename = __fup(import.meta.url); const __dirname = __dn(__filename);
|
|
2
2
|
import {
|
|
3
3
|
runTrace
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-4O7KUIYE.js";
|
|
5
5
|
import "./chunk-ZPPG4MGR.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-EPMDUCEA.js";
|
|
7
7
|
import "./chunk-S3Q7MDCS.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-QX7RZ5CZ.js";
|
|
9
9
|
import "./chunk-2EHYDUHX.js";
|
|
10
10
|
import "./chunk-ZSOAFMES.js";
|
|
11
11
|
import "./chunk-ICKB3EOT.js";
|
|
12
12
|
export {
|
|
13
13
|
runTrace
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=trace-
|
|
15
|
+
//# sourceMappingURL=trace-O5BVV7ZU.js.map
|