From 9a3cf2473ca706c0ac89b66700a539a6ca368908 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Fri, 11 Sep 2026 08:19:46 -0400 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=85=20Prove=20one=20session=20view=20?= =?UTF-8?q?renders=20from=20source=20and=20a=20binary=20(#799)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A terminal session was the one part of this system nothing could test. The rendering path existed only inside a running agent UI, so a regression in how a message is selected, replaced, coalesced, scrolled or repainted reached a person rather than a suite. This drives the whole path headlessly. `@bomb.sh/tty` 0.9.0 does layout, input decoding and ANSI as pure computation with no terminal attached, so one deterministic journey can ask the questions a reader would notice: seven named Markdown presentations render, a repository-local `Tool.md` outranks the default beside it, a streaming replacement lands in the same place, a backlog collapses to its latest completed revision, the view stays where the reader put it across an append and a resize, and an update costs fewer bytes than a repaint. Every claim carries a control that breaks it. The nine controls are a closed enum, each run in a process of its own, and the same invariant checker that admits the positive journey has to reject each one by the category of the claim it broke — so a claim that quietly stopped being checked fails here instead of passing. The journey runs twice: from TypeScript under Deno, and from a `deno compile` executable started outside the checkout with the proof Markdown explicitly embedded. A binary that lost a component has nothing to fall back on, so the two records are required to be equal in whole. Neither run may reach the network, spawn a process, write, read the host beyond the proof's own component roots, or use system or FFI authority. Environment is the exception and cannot be otherwise: the module graph an execution loads probes `process.env` while it is still being imported, so a process that denied it could not reach this proof's own code. That authority is withheld where a document can see it instead, and the document filesystem ledger records every path either journey asked for. The proof is disposable test infrastructure. It adds no production type, no component props, and no export; the `@bomb.sh/tty` pin is an exact root devDependency, and the test asserts that no shipped package adopted either it or these modules. --- deno.lock | 5 + package.json | 1 + pnpm-lock.yaml | 9 + scripts/runtime-test-exclusions.ts | 6 + scripts/tests/session-rendering.test.ts | 363 +++++++ .../defaults/Session/Message/Assistant.md | 3 + .../defaults/Session/Message/Permission.md | 3 + .../defaults/Session/Message/Status.md | 3 + .../defaults/Session/Message/Thought.md | 5 + .../defaults/Session/Message/Tool.md | 3 + .../defaults/Session/Message/Unknown.md | 3 + .../defaults/Session/Message/User.md | 3 + scripts/tests/session-rendering/entrypoint.ts | 103 ++ scripts/tests/session-rendering/evidence.ts | 764 ++++++++++++++ scripts/tests/session-rendering/journey.ts | 964 ++++++++++++++++++ .../session-rendering/markdown-projection.ts | 251 +++++ .../components/Session/Message/Tool.md | 3 + 17 files changed, 2492 insertions(+) create mode 100644 scripts/tests/session-rendering.test.ts create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/Assistant.md create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/Permission.md create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/Status.md create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/Thought.md create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/Tool.md create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/Unknown.md create mode 100644 scripts/tests/session-rendering/defaults/Session/Message/User.md create mode 100644 scripts/tests/session-rendering/entrypoint.ts create mode 100644 scripts/tests/session-rendering/evidence.ts create mode 100644 scripts/tests/session-rendering/journey.ts create mode 100644 scripts/tests/session-rendering/markdown-projection.ts create mode 100644 scripts/tests/session-rendering/repository/components/Session/Message/Tool.md diff --git a/deno.lock b/deno.lock index 7772922ea..6c41800e6 100644 --- a/deno.lock +++ b/deno.lock @@ -41,6 +41,7 @@ "npm:@agentclientprotocol/sdk@1.3.0": "1.3.0_zod@4.4.3", "npm:@babel/core@^7.28.0": "7.29.7", "npm:@babel/preset-react@^7.27.1": "7.29.7_@babel+core@7.29.7", + "npm:@bomb.sh/tty@0.9.0": "0.9.0", "npm:@durable-streams/client@~0.2.2": "0.2.6", "npm:@durable-streams/server@~0.3.8": "0.3.8", "npm:@effectionx/context-api@0.6.0": "0.6.0_effection@4.1.0", @@ -467,6 +468,9 @@ "@babel/helper-validator-identifier" ] }, + "@bomb.sh/tty@0.9.0": { + "integrity": "sha512-1fX9lgwdc+kGRQeVEYwv7cJb5i855ysvB/TMCC3/wnnjMiKLZjWew6LLnsAMq4pLzkweivYw+zwYNZRUVhjoBA==" + }, "@clack/core@1.4.3": { "integrity": "sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==", "dependencies": [ @@ -3996,6 +4000,7 @@ ], "packageJson": { "dependencies": [ + "npm:@bomb.sh/tty@0.9.0", "npm:@durable-streams/client@~0.2.2", "npm:@durable-streams/server@~0.3.8", "npm:@effectionx/context-api@0.6.0", diff --git a/package.json b/package.json index d17b1b1fe..453df3984 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "mdast-util-to-string": "^4" }, "devDependencies": { + "@bomb.sh/tty": "0.9.0", "@durable-streams/server": "^0.3.8", "@executablemd/acp": "workspace:*", "@executablemd/cli": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5ea97ff75..c39c69a52 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -84,6 +84,9 @@ importers: specifier: ^4.3.6 version: 4.3.6 devDependencies: + '@bomb.sh/tty': + specifier: 0.9.0 + version: 0.9.0 '@durable-streams/server': specifier: ^0.3.8 version: 0.3.8 @@ -502,6 +505,10 @@ packages: resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} + '@bomb.sh/tty@0.9.0': + resolution: {integrity: sha512-1fX9lgwdc+kGRQeVEYwv7cJb5i855ysvB/TMCC3/wnnjMiKLZjWew6LLnsAMq4pLzkweivYw+zwYNZRUVhjoBA==} + engines: {node: '>= 22'} + '@clack/core@1.4.3': resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} engines: {node: '>= 20.12.0'} @@ -2673,6 +2680,8 @@ snapshots: '@babel/helper-validator-identifier@7.28.5': {} + '@bomb.sh/tty@0.9.0': {} + '@clack/core@1.4.3': dependencies: fast-wrap-ansi: 0.2.2 diff --git a/scripts/runtime-test-exclusions.ts b/scripts/runtime-test-exclusions.ts index c254f2067..d24e22f95 100644 --- a/scripts/runtime-test-exclusions.ts +++ b/scripts/runtime-test-exclusions.ts @@ -77,6 +77,12 @@ const DENO_ONLY_TOOLING: RuntimeExclusion[] = [ "runs the no-network vendored-source verifier under the Deno executable against altered temporary snapshots", issue: "https://github.com/taras/executable.md/issues/365", }, + { + path: "scripts/tests/session-rendering.test.ts", + reason: + "its subject is a `deno compile` executable and the source run it has to match: it spawns ` run` and ` compile` with Deno's own resolution, permission and `--include` flags, and reads `Deno.permissions` to record what each journey was refused. Under Node and Bun that argument vector names a file called `run`, and the claim — that a binary carries the components it renders — is a claim about Deno's build output", + issue: "https://github.com/taras/executable.md/issues/799", + }, { path: "scripts/tests/build-web-client.test.ts", reason: diff --git a/scripts/tests/session-rendering.test.ts b/scripts/tests/session-rendering.test.ts new file mode 100644 index 000000000..cb2042d19 --- /dev/null +++ b/scripts/tests/session-rendering.test.ts @@ -0,0 +1,363 @@ +/** + * One session view, proved from source and from a binary. + * + * A terminal session is the one part of this system nothing could test: the + * rendering path only existed inside a running agent UI, so a regression in how + * a message is selected, replaced, coalesced, scrolled or repainted showed up + * to a person rather than to a suite. This drives the whole path headlessly — + * `@bomb.sh/tty` does layout, input decoding and ANSI in pure computation with + * no terminal attached — and asks it the questions a person would notice: + * does the right presentation render, does a streaming replacement land in + * place, does a backlog collapse to its latest revision, does the view stay + * where the reader put it across an append and a resize, and does an update + * cost less than a repaint. + * + * Every claim has a control that breaks it. Each control is one value from a + * closed enum, run in a process of its own, and the same invariant checker that + * admits the positive journey has to reject it by name — so a claim that had + * stopped being checked fails here instead of passing quietly. + * + * The journey runs twice: once from TypeScript under Deno, once from a + * `deno compile` executable started outside this checkout. A binary that lost + * an embedded component has nothing to fall back on, so the two records are + * required to be equal in whole. Neither run may reach the network, spawn a + * process, write, or read the host beyond the proof's own component roots. + */ + +import { describe, it } from "@executablemd/test-support/bdd"; +import { expect } from "@executablemd/test-support/expect"; +import { useTempDirectory } from "@executablemd/test-support/temp"; +import { exec } from "@effectionx/process"; +import type { ProcessResult } from "@effectionx/process"; +import { readTextFile } from "@effectionx/fs"; +import { useQuietProcessOutput } from "@executablemd/runtime"; +import { scoped } from "effection"; +import type { Operation } from "effection"; +import { join } from "node:path"; +import { fileURLToPath } from "node:url"; + +import { + categoriesOf, + checkJourney, + checkProductionBoundary, + compareRecords, + parseJourneyReport, + PRESENTATION_COMPONENTS, +} from "./session-rendering/evidence.ts"; +import type { InvariantCategory } from "./session-rendering/evidence.ts"; +import { + JOURNEY_MUTATIONS, + REPORT_SCHEMA, + TTY_PACKAGE, + TTY_VERSION, +} from "./session-rendering/journey.ts"; +import { listWorkspacePaths } from "../lib/workspace.ts"; + +const ROOT = fileURLToPath(new URL("../../", import.meta.url)); +const PROOF = "scripts/tests/session-rendering"; +const ENTRYPOINT = `${PROOF}/entrypoint.ts`; +/** The one asset outside the proof directory an execution reads: core's own catalog. */ +const CORE_DOCUMENTATION = "packages/core/src/components/components.md"; + +/** + * What neither journey may do. + * + * Five of the six are refused outright. Environment is not, and cannot be: the + * module graph an execution loads probes `process.env` while it is still being + * imported — `which` reads `OSTYPE`, and `debug` enumerates the whole + * environment — so a process that denied it could not reach this proof's own + * code at all. Environment authority is therefore withheld where a document can + * see it instead: nothing installs a host `Env` provider, and the document + * filesystem ledger below records every path either journey asked for. + */ +const DENIED = ["--deny-net", "--deny-write", "--deny-run", "--deny-sys", "--deny-ffi"]; + +/** The smallest read grant either journey needs, spelled the same way for both. */ +const READABLE = `${PROOF},packages/core/src`; + +const RESOLUTION = ["--frozen", "--cached-only", "--node-modules-dir=none"]; + +const EMBEDDED = [PROOF + "/defaults", PROOF + "/repository", CORE_DOCUMENTATION]; + +/** + * One child process, with its standard output collected rather than echoed. + * + * A journey's stdout *is* the answer these cases read, so displaying it as well + * would put a whole evidence record into the suite's own output for every run. + * `stderr` is left alone: that is where a failing child explains itself. + */ +function quietly(command: string, argv: string[], cwd: string): Operation { + return scoped(function* () { + yield* useQuietProcessOutput(); + return yield* exec(command, { arguments: argv, cwd }).join(); + }); +} + +/** The journey under Deno, reading its components out of the checkout. */ +function sourceRun(mutation?: string): Operation { + return quietly( + Deno.execPath(), + [ + "run", + ...RESOLUTION, + `--allow-read=${READABLE}`, + "--allow-env", + ...DENIED, + ENTRYPOINT, + ...(mutation === undefined ? [] : [mutation]), + ], + ROOT, + ); +} + +/** `run`, having exited zero, or a failure carrying what it printed. */ +function succeeded(run: ProcessResult, what: string): ProcessResult { + if (run.code !== 0) { + throw new Error(`${what} exited ${run.code}\n${run.stdout}\n${run.stderr}`); + } + return run; +} + +/** Exactly one JSON record, or a failure that says what the process printed. */ +function recordOf(run: ProcessResult, what: string): unknown { + const lines = run.stdout.split("\n").filter((line) => line.trim().length > 0); + if (lines.length !== 1) { + throw new Error( + `${what} printed ${lines.length} stdout records, not one\n${run.stdout}\n${run.stderr}`, + ); + } + return JSON.parse(lines[0]); +} + +function outcomeOf(record: unknown): string { + if (typeof record === "object" && record !== null && "outcome" in record) { + const outcome = Reflect.get(record, "outcome"); + return typeof outcome === "string" ? outcome : "unknown"; + } + return "report"; +} + +function categoriesIn(record: unknown): string[] { + if (typeof record === "object" && record !== null && "categories" in record) { + const categories = Reflect.get(record, "categories"); + if (Array.isArray(categories)) { + return categories.map((category) => String(category)); + } + } + return []; +} + +function detailOf(record: unknown): string { + return JSON.stringify(record).slice(0, 2000); +} + +describe("the session rendering proof", { sanitizeOps: false, sanitizeResources: false }, () => { + it("renders the same versioned journey from source and from a compiled executable", function* () { + const source = succeeded(yield* sourceRun(), "the source journey"); + const sourceRecord = recordOf(source, "the source journey"); + expect(outcomeOf(sourceRecord)).toBe("report"); + + const build = yield* useTempDirectory("xmd-session-rendering-build-"); + const binary = join(build, "session-rendering"); + const compiled = yield* quietly( + Deno.execPath(), + [ + "compile", + ...RESOLUTION, + "--exclude-unused-npm", + `--allow-read=${READABLE}`, + "--allow-env", + ...DENIED, + ...EMBEDDED.flatMap((asset) => ["--include", asset]), + "--output", + binary, + ENTRYPOINT, + ], + ROOT, + ); + succeeded(compiled, "the compile"); + + // Somewhere that is not the checkout: a binary that resolved a component + // through the working directory would find nothing here, so what it + // renders is what `--include` embedded and nothing else. + const elsewhere = yield* useTempDirectory("xmd-session-rendering-run-"); + const binaryRun = yield* quietly(binary, [], elsewhere); + succeeded(binaryRun, "the compiled journey"); + const compiledRecord = recordOf(binaryRun, "the compiled journey"); + + expect(compareRecords(sourceRecord, compiledRecord)).toEqual([]); + + const parsed = parseJourneyReport(sourceRecord); + expect(parsed.schema).toBe(REPORT_SCHEMA); + expect(parsed.dependency).toEqual({ name: TTY_PACKAGE, version: TTY_VERSION }); + expect(checkJourney(parsed)).toEqual([]); + + // The seven names, where each resolved, and the one that came from the + // repository root rather than from the defaults beneath it. + expect(parsed.presentations.map((one) => one.component)).toEqual(PRESENTATION_COMPONENTS); + expect( + parsed.presentations + .filter((one) => one.root === "repository/components") + .map((one) => one.component), + ).toEqual(["Session.Message.Tool"]); + + // An incremental update that is cheaper than a repaint, measured rather + // than spelled: neither the bytes nor the escape sequence is written down + // anywhere here. + expect(parsed.diff.incrementalBytes).toBeGreaterThan(0); + expect(parsed.diff.incrementalBytes).toBeLessThan(parsed.diff.freshBytes); + + // Nothing either journey asked the document filesystem for was outside + // the proof's own roots, and five authorities were refused outright. + expect(parsed.files.filter((request) => !request.admitted)).toEqual([]); + for (const authority of ["net", "write", "run", "sys", "ffi"]) { + expect(parsed.authorities[authority]).toBe("denied"); + } + }); + + describe("every claim has a control that breaks it", () => { + const EXPECTED: Record = { + "omit-component": "presentation-selection", + "default-before-repository": "override-precedence", + "plain-markdown": "structured-markdown", + "unstable-regions": "stable-replacement", + "no-coalescing": "coalescing", + "forced-follow": "follow-unread", + "row-offset-viewport": "resize-preservation", + "whole-history-repaint": "bounded-diff", + "forbidden-read": "forbidden-integration", + }; + + it("names every mutation exactly once", function* () { + expect([...JOURNEY_MUTATIONS].sort()).toEqual(Object.keys(EXPECTED).sort()); + }); + + for (const mutation of JOURNEY_MUTATIONS) { + it(`rejects ${mutation} as ${EXPECTED[mutation]}`, function* () { + const run = yield* sourceRun(mutation); + const record = recordOf(run, `the ${mutation} control`); + // Exit status separates a named rejection from an accident: a control + // that crashed, or one nobody caught, is not a control. + succeeded(run, `the ${mutation} control`); + expect(outcomeOf(record)).toBe("rejected"); + expect(categoriesIn(record)).toContain(EXPECTED[mutation]); + }); + } + + it("proves the scroll transition is necessary, not incidental", function* () { + const run = yield* sourceRun("forced-follow"); + const record = recordOf(run, "the forced-follow control"); + expect(categoriesIn(record)).toContain("history-and-newest"); + expect(categoriesIn(record)).toContain("follow-unread"); + }); + }); + + describe("the host pair and the private boundary", () => { + it("rejects a compiled record that lost or changed a member", function* () { + const source = succeeded(yield* sourceRun(), "the source journey"); + const record = recordOf(source, "the source journey"); + expect(typeof record).toBe("object"); + if (typeof record !== "object" || record === null) { + throw new Error("the source journey printed no record to compare against"); + } + + const withoutMember = { ...record }; + Reflect.deleteProperty(withoutMember, "presentations"); + expect(compareRecords(record, withoutMember).join("; ")).toContain("presentations"); + + const mismatched = { ...record, dependency: { name: TTY_PACKAGE, version: "0.8.0" } }; + expect(compareRecords(record, mismatched).join("; ")).toContain("0.8.0"); + + // And a record identical to itself names no difference at all, so the + // comparison above is not passing because everything differs. + expect(compareRecords(record, record)).toEqual([]); + }); + + it("keeps the proof and its dependency out of every production package", function* () { + const surface = yield* productionSurface(); + expect(Object.keys(surface.dependencies).length).toBeGreaterThan(0); + expect(checkProductionBoundary(surface)).toEqual([]); + + expect( + checkProductionBoundary({ + dependencies: { "packages/core/package.json": ["@bomb.sh/tty"] }, + exports: {}, + }), + ).toEqual(["packages/core/package.json depends on @bomb.sh/tty"]); + expect( + checkProductionBoundary({ + dependencies: {}, + exports: { "packages/core/deno.json": ["./scripts/tests/session-rendering/journey.ts"] }, + }), + ).toHaveLength(1); + }); + }); + + it("is admitted by the checker only when nothing is wrong with it", function* () { + const source = succeeded(yield* sourceRun(), "the source journey"); + const parsed = parseJourneyReport(recordOf(source, "the source journey")); + expect(categoriesOf(checkJourney(parsed))).toEqual([]); + + // The checker is not vacuous: a record with its history emptied is + // rejected by the claims that read history. + const emptied = parseJourneyReport({ ...JSON.parse(JSON.stringify(parsed)), history: [] }); + expect(categoriesOf(checkJourney(emptied))).toContain("stable-replacement"); + }); +}); + +/** + * Every dependency a shipped package declares and every specifier it publishes. + * + * The root manifest's own `devDependencies` are deliberately absent: that is + * where the exact `@bomb.sh/tty` pin belongs, and reading it here would make + * the boundary check pass or fail for the wrong reason. + */ +function* productionSurface(): Operation<{ + dependencies: Record; + exports: Record; +}> { + const dependencies: Record = {}; + const exports: Record = {}; + + const root = new URL("../../", import.meta.url); + const manifest = JSON.parse(yield* readTextFile(new URL("deno.json", root))); + const members = yield* listWorkspacePaths(manifest.workspace, root); + + dependencies["package.json"] = names( + JSON.parse(yield* readTextFile(new URL("package.json", root))).dependencies, + ); + + for (const member of members) { + for (const file of ["package.json", "deno.json"]) { + const url = new URL(`${member}/${file}`, root); + let source: string; + try { + source = yield* readTextFile(url); + } catch { + continue; + } + const parsed = JSON.parse(source); + dependencies[`${member}/${file}`] = [ + ...names(parsed.dependencies), + ...names(parsed.devDependencies), + ...names(parsed.imports), + ]; + exports[`${member}/${file}`] = specifiers(parsed.exports); + } + } + return { dependencies, exports }; +} + +function names(value: unknown): string[] { + return typeof value === "object" && value !== null ? Object.keys(value) : []; +} + +function specifiers(value: unknown): string[] { + if (typeof value === "string") { + return [value]; + } + if (typeof value !== "object" || value === null) { + return []; + } + return Object.values(value).flatMap((entry) => specifiers(entry)); +} diff --git a/scripts/tests/session-rendering/defaults/Session/Message/Assistant.md b/scripts/tests/session-rendering/defaults/Session/Message/Assistant.md new file mode 100644 index 000000000..872d844fe --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/Assistant.md @@ -0,0 +1,3 @@ +xmd-proof-assistant + + diff --git a/scripts/tests/session-rendering/defaults/Session/Message/Permission.md b/scripts/tests/session-rendering/defaults/Session/Message/Permission.md new file mode 100644 index 000000000..ec2910feb --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/Permission.md @@ -0,0 +1,3 @@ +xmd-proof-permission + + diff --git a/scripts/tests/session-rendering/defaults/Session/Message/Status.md b/scripts/tests/session-rendering/defaults/Session/Message/Status.md new file mode 100644 index 000000000..06c8ffa73 --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/Status.md @@ -0,0 +1,3 @@ +xmd-proof-status + + diff --git a/scripts/tests/session-rendering/defaults/Session/Message/Thought.md b/scripts/tests/session-rendering/defaults/Session/Message/Thought.md new file mode 100644 index 000000000..6be9206b7 --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/Thought.md @@ -0,0 +1,5 @@ +xmd-proof-thought + + + + diff --git a/scripts/tests/session-rendering/defaults/Session/Message/Tool.md b/scripts/tests/session-rendering/defaults/Session/Message/Tool.md new file mode 100644 index 000000000..aece91cac --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/Tool.md @@ -0,0 +1,3 @@ +xmd-proof-tool-default + + diff --git a/scripts/tests/session-rendering/defaults/Session/Message/Unknown.md b/scripts/tests/session-rendering/defaults/Session/Message/Unknown.md new file mode 100644 index 000000000..c7cc5f711 --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/Unknown.md @@ -0,0 +1,3 @@ +xmd-proof-unknown + + diff --git a/scripts/tests/session-rendering/defaults/Session/Message/User.md b/scripts/tests/session-rendering/defaults/Session/Message/User.md new file mode 100644 index 000000000..d414973b7 --- /dev/null +++ b/scripts/tests/session-rendering/defaults/Session/Message/User.md @@ -0,0 +1,3 @@ +xmd-proof-user + + diff --git a/scripts/tests/session-rendering/entrypoint.ts b/scripts/tests/session-rendering/entrypoint.ts new file mode 100644 index 000000000..d70d6273e --- /dev/null +++ b/scripts/tests/session-rendering/entrypoint.ts @@ -0,0 +1,103 @@ +/** + * The journey as a program, so the same code can be run from source and from a + * `deno compile` executable and the two answers compared. + * + * It prints exactly one JSON record and nothing else. A positive run prints the + * journey report; a run given one of the closed set of mutations prints the + * categories the invariant checker rejected it for. Exit status separates the + * two failures that matter: a mutation that was rejected by name is a working + * control and exits 0, while a mutation nobody caught, a shape nobody can + * parse, or an exception nobody named exits non-zero. + * + * The component roots are located from this module's own URL rather than from + * the working directory, because the compiled binary has no checkout to stand + * in and is deliberately run from somewhere else. + */ + +import { main } from "effection"; +import { fileURLToPath } from "node:url"; + +import { categoriesOf, checkJourney, parseJourneyReport } from "./evidence.ts"; +import { JOURNEY_MUTATIONS, parseJourneyMutation, REPORT_SCHEMA, runJourney } from "./journey.ts"; + +const ROOT = fileURLToPath(new URL(".", import.meta.url)); + +function emit(record: unknown): void { + console.log(JSON.stringify(record)); +} + +await main(function* () { + const [requested, ...extra] = Deno.args; + if (extra.length > 0) { + emit({ + schema: REPORT_SCHEMA, + outcome: "failed", + detail: `expected at most one mutation, got ${[requested, ...extra].join(" ")}`, + }); + Deno.exitCode = 1; + return; + } + + const mutation = requested === undefined ? undefined : parseJourneyMutation(requested); + if (requested !== undefined && mutation === undefined) { + emit({ + schema: REPORT_SCHEMA, + outcome: "failed", + detail: `"${requested}" is not one of ${JOURNEY_MUTATIONS.join(", ")}`, + }); + Deno.exitCode = 1; + return; + } + + let report: unknown; + try { + report = yield* runJourney({ root: ROOT, mutation }); + } catch (error) { + emit({ + schema: REPORT_SCHEMA, + outcome: "failed", + mutation: mutation ?? null, + detail: error instanceof Error ? `${error.name}: ${error.message}` : String(error), + }); + Deno.exitCode = 1; + return; + } + + // The record goes out through the same parser the outer test uses, so a + // journey that emitted a shape nothing can read fails here rather than in the + // comparison. + const parsed = parseJourneyReport(JSON.parse(JSON.stringify(report))); + const violations = checkJourney(parsed); + + if (mutation === undefined) { + if (violations.length > 0) { + // A rejected positive run carries the record it was rejected on: the + // reader of that failure needs the evidence, not just the verdict. + emit({ + schema: REPORT_SCHEMA, + outcome: "rejected", + mutation: null, + categories: categoriesOf(violations), + violations, + report, + }); + Deno.exitCode = 1; + return; + } + emit(report); + return; + } + + if (violations.length === 0) { + emit({ schema: REPORT_SCHEMA, outcome: "admitted", mutation }); + Deno.exitCode = 1; + return; + } + emit({ + schema: REPORT_SCHEMA, + outcome: "rejected", + mutation, + categories: categoriesOf(violations), + violations, + }); +}); diff --git a/scripts/tests/session-rendering/evidence.ts b/scripts/tests/session-rendering/evidence.ts new file mode 100644 index 000000000..e8b93fa83 --- /dev/null +++ b/scripts/tests/session-rendering/evidence.ts @@ -0,0 +1,764 @@ +/** + * What a journey has to have shown, and what it means when it has not. + * + * One checker admits the positive journey and rejects every mutation, so a + * control that "fails" cannot be failing for a reason nobody named: each + * rejection carries the invariant category of the claim it broke. The same + * module parses the JSON a journey process printed, which is what lets the + * source run and the compiled run be compared as values rather than as text. + * + * Parsing is how types arrive here. Nothing is cast: a record that does not + * have the shape below is not a report, and saying so is more useful than + * asserting against fields that were never there. + */ + +import { EMPHASIS_ATTRIBUTE, lexProofMarkdown } from "./markdown-projection.ts"; +import type { OperationDescription } from "./markdown-projection.ts"; + +/** The claim a rejection belongs to. */ +export const INVARIANT_CATEGORIES = [ + "presentation-selection", + "override-precedence", + "structured-markdown", + "stable-replacement", + "coalescing", + "history-and-newest", + "follow-unread", + "resize-preservation", + "bounded-diff", + "forbidden-integration", +] as const; + +export type InvariantCategory = (typeof INVARIANT_CATEGORIES)[number]; + +export interface Violation { + readonly category: InvariantCategory; + readonly detail: string; +} + +/** The seven names this proof selects, in the order history holds them. */ +export const PRESENTATION_COMPONENTS: readonly string[] = [ + "Session.Message.User", + "Session.Message.Assistant", + "Session.Message.Tool", + "Session.Message.Permission", + "Session.Message.Status", + "Session.Message.Unknown", + "Session.Message.Thought", +]; + +/** The name the repository-local override renders, which no default may print. */ +export const REPOSITORY_TOOL_MARKER = "xmd-proof-tool-repository"; + +export const EXPECTED_HISTORY: readonly string[] = [ + "entry-user", + "entry-assistant", + "entry-tool", + "entry-permission", + "entry-status", + "entry-unknown", + "entry-thought", + "entry-appended", + "entry-final", +]; + +const THOUGHT_ID = "entry-thought"; + +export class ReportShapeError extends Error { + constructor(field: string) { + super(`the journey record has no ${field}`); + this.name = "ReportShapeError"; + } +} + +function field(value: unknown, name: string): unknown { + if (typeof value !== "object" || value === null || !(name in value)) { + throw new ReportShapeError(name); + } + return Reflect.get(value, name); +} + +function asString(value: unknown, name: string): string { + const found = field(value, name); + if (typeof found !== "string") { + throw new ReportShapeError(`${name} as a string`); + } + return found; +} + +function asNumber(value: unknown, name: string): number { + const found = field(value, name); + if (typeof found !== "number") { + throw new ReportShapeError(`${name} as a number`); + } + return found; +} + +function asBoolean(value: unknown, name: string): boolean { + const found = field(value, name); + if (typeof found !== "boolean") { + throw new ReportShapeError(`${name} as a boolean`); + } + return found; +} + +function asArray(value: unknown, name: string): unknown[] { + const found = field(value, name); + if (!Array.isArray(found)) { + throw new ReportShapeError(`${name} as an array`); + } + return found; +} + +function asStrings(value: unknown, name: string): string[] { + return asArray(value, name).map((entry) => { + if (typeof entry !== "string") { + throw new ReportShapeError(`${name} as strings`); + } + return entry; + }); +} + +export interface ParsedPresentation { + readonly component: string; + readonly path: string; + readonly root: string; +} + +export interface ParsedProjection { + readonly id: string; + readonly component: string; + readonly componentPath: string; + readonly revision: number; + readonly complete: boolean; + readonly raw: string; +} + +export interface ParsedCommit { + readonly id: string; + readonly revision: number; + readonly complete: boolean; + readonly viewVersion: number; +} + +export interface ParsedFrame { + readonly label: string; + readonly width: number; + readonly height: number; + readonly visible: readonly string[]; + readonly anchor: string; + readonly follow: boolean; + readonly unread: number; + readonly bytes: number; + readonly operations: readonly OperationDescription[]; +} + +export interface ParsedReport { + readonly schema: string; + readonly dependency: { readonly name: string; readonly version: string }; + readonly authorities: Readonly>; + readonly presentations: readonly ParsedPresentation[]; + readonly projections: readonly ParsedProjection[]; + readonly history: readonly string[]; + readonly commits: readonly ParsedCommit[]; + readonly timeline: readonly string[]; + readonly barrier: { + readonly ingestedWhileBlocked: readonly number[]; + readonly releasedAfterVersion: number; + readonly committedAfterRelease: readonly ParsedCommit[]; + }; + readonly frames: readonly ParsedFrame[]; + readonly resize: { + readonly requested: readonly { readonly width: number; readonly height: number }[]; + readonly adopted: { readonly width: number; readonly height: number }; + readonly anchorBefore: string; + readonly anchorAfter: string; + readonly followBefore: boolean; + readonly followAfter: boolean; + readonly unreadBefore: number; + readonly unreadAfter: number; + readonly historyBefore: readonly string[]; + readonly historyAfter: readonly string[]; + }; + readonly diff: { + readonly incrementalBytes: number; + readonly freshBytes: number; + readonly neighbours: readonly string[]; + readonly neighboursBefore: readonly OperationDescription[]; + readonly neighboursAfter: readonly OperationDescription[]; + }; + readonly files: readonly { + readonly operation: string; + readonly path: string; + readonly admitted: boolean; + }[]; + readonly discardedProjections: number; +} + +function parseOperations(value: unknown, name: string): OperationDescription[] { + return asArray(value, name).map((entry) => { + const kind = asString(entry, "kind"); + if (kind === "open") { + const role = asString(entry, "role"); + if (role !== "viewport" && role !== "entry" && role !== "paragraph" && role !== "code") { + throw new ReportShapeError(`${name} with a known role`); + } + return { kind: "open", id: asString(entry, "id"), role }; + } + if (kind === "text") { + return { kind: "text", content: asString(entry, "content"), attrs: asNumber(entry, "attrs") }; + } + if (kind === "close") { + return { kind: "close" }; + } + throw new ReportShapeError(`${name} with a known operation kind`); + }); +} + +function parseCommits(value: unknown, name: string): ParsedCommit[] { + return asArray(value, name).map((entry) => ({ + id: asString(entry, "id"), + revision: asNumber(entry, "revision"), + complete: asBoolean(entry, "complete"), + viewVersion: asNumber(entry, "viewVersion"), + })); +} + +function parseSize(value: unknown): { width: number; height: number } { + return { width: asNumber(value, "width"), height: asNumber(value, "height") }; +} + +/** One journey record, parsed into the shape the oracles read. */ +export function parseJourneyReport(value: unknown): ParsedReport { + const dependency = field(value, "dependency"); + const authoritiesValue = field(value, "authorities"); + if (typeof authoritiesValue !== "object" || authoritiesValue === null) { + throw new ReportShapeError("authorities"); + } + const authorities: Record = {}; + for (const [name, state] of Object.entries(authoritiesValue)) { + if (typeof state !== "string") { + throw new ReportShapeError("authorities as strings"); + } + authorities[name] = state; + } + const barrier = field(value, "barrier"); + const resize = field(value, "resize"); + const diff = field(value, "diff"); + return { + schema: asString(value, "schema"), + dependency: { name: asString(dependency, "name"), version: asString(dependency, "version") }, + authorities, + presentations: asArray(value, "presentations").map((entry) => ({ + component: asString(entry, "component"), + path: asString(entry, "path"), + root: asString(entry, "root"), + })), + projections: asArray(value, "projections").map((entry) => ({ + id: asString(entry, "id"), + component: asString(entry, "component"), + componentPath: asString(entry, "componentPath"), + revision: asNumber(entry, "revision"), + complete: asBoolean(entry, "complete"), + raw: asString(entry, "raw"), + })), + history: asStrings(value, "history"), + commits: parseCommits(value, "commits"), + timeline: asStrings(value, "timeline"), + barrier: { + ingestedWhileBlocked: asArray(barrier, "ingestedWhileBlocked").map((entry) => { + if (typeof entry !== "number") { + throw new ReportShapeError("ingestedWhileBlocked as numbers"); + } + return entry; + }), + releasedAfterVersion: asNumber(barrier, "releasedAfterVersion"), + committedAfterRelease: parseCommits(barrier, "committedAfterRelease"), + }, + frames: asArray(value, "frames").map((entry) => ({ + label: asString(entry, "label"), + width: asNumber(entry, "width"), + height: asNumber(entry, "height"), + visible: asStrings(entry, "visible"), + anchor: asString(entry, "anchor"), + follow: asBoolean(entry, "follow"), + unread: asNumber(entry, "unread"), + bytes: asNumber(entry, "bytes"), + operations: parseOperations(entry, "operations"), + })), + resize: { + requested: asArray(resize, "requested").map(parseSize), + adopted: parseSize(field(resize, "adopted")), + anchorBefore: asString(resize, "anchorBefore"), + anchorAfter: asString(resize, "anchorAfter"), + followBefore: asBoolean(resize, "followBefore"), + followAfter: asBoolean(resize, "followAfter"), + unreadBefore: asNumber(resize, "unreadBefore"), + unreadAfter: asNumber(resize, "unreadAfter"), + historyBefore: asStrings(resize, "historyBefore"), + historyAfter: asStrings(resize, "historyAfter"), + }, + diff: { + incrementalBytes: asNumber(diff, "incrementalBytes"), + freshBytes: asNumber(diff, "freshBytes"), + neighbours: asStrings(diff, "neighbours"), + neighboursBefore: parseOperations(diff, "neighboursBefore"), + neighboursAfter: parseOperations(diff, "neighboursAfter"), + }, + files: asArray(value, "files").map((entry) => ({ + operation: asString(entry, "operation"), + path: asString(entry, "path"), + admitted: asBoolean(entry, "admitted"), + })), + discardedProjections: asNumber(value, "discardedProjections"), + }; +} + +function frameNamed(report: ParsedReport, label: string): ParsedFrame | undefined { + return report.frames.find((frame) => frame.label === label); +} + +function same(left: unknown, right: unknown): boolean { + return JSON.stringify(left) === JSON.stringify(right); +} + +/** The first visible line of a rendering, which is the presentation's marker. */ +function markerOf(raw: string): string { + return ( + raw + .split("\n") + .map((line) => line.trim()) + .find((line) => line.length > 0) ?? "" + ); +} + +function checkPresentations(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => + violations.push({ category: "presentation-selection", detail }); + + if ( + !same( + report.presentations.map((one) => one.component), + PRESENTATION_COMPONENTS, + ) + ) { + reject( + `selected ${report.presentations.length} names (${report.presentations + .map((one) => one.component) + .join(", ")})`, + ); + return; + } + for (const presentation of report.presentations) { + const leaf = presentation.component.split(".").join("/"); + const expected = `${presentation.root}/${leaf}.md`; + if (presentation.path !== expected) { + reject(`${presentation.component} resolved to ${presentation.path}, not ${expected}`); + } + } + const markers = new Map>(); + for (const projection of report.projections) { + const seen = markers.get(projection.component) ?? new Set(); + seen.add(markerOf(projection.raw)); + markers.set(projection.component, seen); + } + const distinct = new Set(); + for (const component of PRESENTATION_COMPONENTS) { + const seen = markers.get(component); + if (seen === undefined || seen.size !== 1) { + reject(`${component} rendered ${seen === undefined ? 0 : seen.size} distinct markers`); + continue; + } + const [marker] = [...seen]; + if (marker.length === 0) { + reject(`${component} rendered no marker`); + } + distinct.add(marker); + } + if (distinct.size !== PRESENTATION_COMPONENTS.length) { + reject(`the seven presentations share ${distinct.size} markers`); + } +} + +function checkOverride(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "override-precedence", detail }); + for (const presentation of report.presentations) { + const expected = + presentation.component === "Session.Message.Tool" ? "repository/components" : "defaults"; + if (presentation.root !== expected) { + reject(`${presentation.component} came from ${presentation.root}, not ${expected}`); + } + } + const tool = report.projections.filter((one) => one.component === "Session.Message.Tool"); + if (tool.length === 0) { + reject("no Tool projection was committed"); + } + for (const projection of tool) { + if (markerOf(projection.raw) !== REPOSITORY_TOOL_MARKER) { + reject(`the Tool rendering printed ${markerOf(projection.raw)}`); + } + } +} + +function checkStructuredMarkdown(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "structured-markdown", detail }); + + let paragraphs = 0; + let emphasised = 0; + let fenced = 0; + for (const projection of report.projections) { + const blocks = lexProofMarkdown(projection.raw); + paragraphs = Math.max(paragraphs, blocks.filter((block) => block.kind === "paragraph").length); + for (const block of blocks) { + if (block.kind === "paragraph" && block.runs.some((run) => run.emphasis)) { + emphasised++; + } + if (block.kind === "code" && block.language === "ts") { + fenced++; + } + } + } + if (paragraphs < 2) { + reject(`the widest capture held ${paragraphs} paragraph(s)`); + } + if (emphasised === 0) { + reject("no capture carried inline emphasis"); + } + if (fenced === 0) { + reject("no capture carried a fenced TypeScript block"); + } + + // Read every frame: the entry carrying the fenced block is not on screen in + // all of them, and what this claim is about is that the projection put the + // three shapes into the operation tree at all. + const ops = report.frames.flatMap((frame) => frame.operations); + if (ops.length === 0) { + reject("there are no frames to read operations from"); + return; + } + if (!ops.some((op) => op.kind === "open" && op.role === "paragraph")) { + reject("the operation tree has no paragraph container"); + } + if (!ops.some((op) => op.kind === "text" && op.attrs === EMPHASIS_ATTRIBUTE)) { + reject("no text operation carries the emphasis attribute"); + } + const code = ops.findIndex((op) => op.kind === "open" && op.role === "code"); + if (code === -1) { + reject("the operation tree has no code container"); + return; + } + const inside = ops[code + 1]; + if (inside === undefined || inside.kind !== "text" || inside.content.length === 0) { + reject("the code container holds no text operation"); + } +} + +function checkStableReplacement(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "stable-replacement", detail }); + + if (!same(report.history, EXPECTED_HISTORY)) { + reject(`history is ${report.history.join(", ")}`); + } + if (new Set(report.history).size !== report.history.length) { + reject("history holds a duplicate id"); + } + const thoughtCommits = report.commits.filter((commit) => commit.id === THOUGHT_ID); + const last = thoughtCommits[thoughtCommits.length - 1]; + if (last === undefined || last.revision !== 5 || !last.complete) { + reject(`the thought's last commit is ${JSON.stringify(last ?? null)}`); + } + if (!same(report.diff.neighboursBefore, report.diff.neighboursAfter)) { + reject(`the neighbours ${report.diff.neighbours.join(", ")} changed across the replacement`); + } + const initial = frameNamed(report, "initial"); + const completion = frameNamed(report, "thought-completion"); + if (initial === undefined || completion === undefined) { + reject("the replacement frames are missing"); + return; + } + if (initial.visible.indexOf(THOUGHT_ID) !== completion.visible.indexOf(THOUGHT_ID)) { + reject("the replacement moved the thought within the visible frame"); + } +} + +function checkCoalescing(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "coalescing", detail }); + + if (report.barrier.ingestedWhileBlocked.length !== 3) { + reject(`${report.barrier.ingestedWhileBlocked.length} snapshot(s) arrived while blocked`); + } + const after = report.barrier.committedAfterRelease; + if (after.length !== 1) { + reject(`${after.length} projection(s) committed after the barrier opened`); + } + const only = after[0]; + if (only === undefined || only.id !== THOUGHT_ID || only.revision !== 5 || !only.complete) { + reject(`the first commit after release is ${JSON.stringify(only ?? null)}`); + } + if (report.discardedProjections < 1) { + reject("no stale projection was discarded"); + } + const engaged = report.timeline.indexOf("barrier:engaged"); + const released = report.timeline.indexOf("barrier:released"); + const resumed = report.timeline.indexOf("barrier:resumed"); + if (engaged === -1 || released === -1 || resumed === -1 || !(engaged < released)) { + reject(`the barrier timeline is ${report.timeline.join(" ")}`); + return; + } + for (const version of report.barrier.ingestedWhileBlocked) { + const at = report.timeline.indexOf(`ingest:v${version}`); + if (!(at > engaged && at < released)) { + reject(`snapshot ${version} was not ingested between engaging and releasing`); + } + } +} + +function checkHistoryAndNewest(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "history-and-newest", detail }); + + const initial = frameNamed(report, "initial"); + const scrolled = frameNamed(report, "scrolled-to-oldest"); + if (initial === undefined || scrolled === undefined) { + reject("the history frames are missing"); + return; + } + if (!initial.follow || initial.unread !== 0) { + reject(`the initial frame is follow=${initial.follow} unread=${initial.unread}`); + } + if (!initial.visible.includes(THOUGHT_ID)) { + reject("the initial frame does not show the newest entry"); + } + if (scrolled.follow) { + reject("paging up left the view following"); + } + if (scrolled.anchor !== report.history[0]) { + reject(`paging up reached ${scrolled.anchor}, not ${report.history[0]}`); + } + for (const id of EXPECTED_HISTORY) { + if (!report.history.includes(id)) { + reject(`history lost ${id}`); + } + } +} + +function checkFollowAndUnread(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "follow-unread", detail }); + + const scrolled = frameNamed(report, "scrolled-to-oldest"); + const appended = frameNamed(report, "appended-off-bottom"); + const returned = frameNamed(report, "returned-to-bottom"); + const following = frameNamed(report, "appended-while-following"); + if ( + scrolled === undefined || + appended === undefined || + returned === undefined || + following === undefined + ) { + reject("the follow frames are missing"); + return; + } + if (appended.anchor !== scrolled.anchor) { + reject(`the append moved the anchor from ${scrolled.anchor} to ${appended.anchor}`); + } + if (appended.follow) { + reject("the append re-enabled following"); + } + if (appended.unread !== 1) { + reject(`the append left unread at ${appended.unread}`); + } + if (!returned.follow || returned.unread !== 0) { + reject(`End left follow=${returned.follow} unread=${returned.unread}`); + } + if (!returned.visible.includes("entry-appended")) { + reject("End did not return to the newest entry"); + } + if (!following.follow || following.unread !== 0) { + reject(`the following append left follow=${following.follow} unread=${following.unread}`); + } + if (!following.visible.includes("entry-final")) { + reject("the following append did not stay at the newest entry"); + } +} + +function checkResize(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "resize-preservation", detail }); + + const last = report.resize.requested[report.resize.requested.length - 1]; + if (last === undefined || !same(last, report.resize.adopted)) { + reject(`the batch adopted ${JSON.stringify(report.resize.adopted)}`); + } + const resized = frameNamed(report, "resized"); + if (resized === undefined) { + reject("there is no resized frame"); + return; + } + if ( + resized.width !== report.resize.adopted.width || + resized.height !== report.resize.adopted.height + ) { + reject(`the resized frame rendered ${resized.width}x${resized.height}`); + } + if (!same(report.resize.historyBefore, report.resize.historyAfter)) { + reject("the resize changed history"); + } + // The anchor claim is about an off-bottom view. A following view is supposed + // to re-anchor when the window grows, and whether this journey was off the + // bottom at all is the follow-and-unread claim rather than this one. + if (report.resize.followBefore) { + return; + } + if (report.resize.anchorBefore !== report.resize.anchorAfter) { + reject( + `the resize moved the anchor from ${report.resize.anchorBefore} to ${report.resize.anchorAfter}`, + ); + } + if (report.resize.followBefore !== report.resize.followAfter) { + reject("the resize changed follow mode"); + } + if (report.resize.unreadBefore !== report.resize.unreadAfter) { + reject("the resize changed the unread count"); + } +} + +function checkBoundedDiff(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "bounded-diff", detail }); + + if (report.diff.incrementalBytes === 0) { + reject("the incremental update produced no bytes"); + } + if (report.diff.incrementalBytes >= report.diff.freshBytes) { + reject( + `the incremental update cost ${report.diff.incrementalBytes} bytes against a fresh frame of ${report.diff.freshBytes}`, + ); + } + if (!same(report.diff.neighboursBefore, report.diff.neighboursAfter)) { + reject("the measured update also changed its neighbours"); + } +} + +function checkForbiddenIntegration(report: ParsedReport, violations: Violation[]): void { + const reject = (detail: string) => violations.push({ category: "forbidden-integration", detail }); + + if (report.files.length === 0) { + reject("the document filesystem ledger saw nothing at all"); + } + for (const request of report.files) { + if (!request.admitted) { + reject(`${request.operation} of ${request.path} was refused by the ledger`); + } + } + for (const authority of ["net", "write", "run", "sys", "ffi"]) { + if (report.authorities[authority] !== "denied") { + reject(`${authority} authority is ${report.authorities[authority]}`); + } + } +} + +/** Every claim this journey failed, or an empty list when it made them all. */ +export function checkJourney(report: ParsedReport): Violation[] { + const violations: Violation[] = []; + if (report.dependency.name !== "@bomb.sh/tty" || report.dependency.version !== "0.9.0") { + violations.push({ + category: "presentation-selection", + detail: `the record names ${report.dependency.name} ${report.dependency.version}`, + }); + } + checkPresentations(report, violations); + checkOverride(report, violations); + checkStructuredMarkdown(report, violations); + checkStableReplacement(report, violations); + checkCoalescing(report, violations); + checkHistoryAndNewest(report, violations); + checkFollowAndUnread(report, violations); + checkResize(report, violations); + checkBoundedDiff(report, violations); + checkForbiddenIntegration(report, violations); + return violations; +} + +/** The categories a set of violations names, in the order the checker found them. */ +export function categoriesOf(violations: readonly Violation[]): InvariantCategory[] { + const seen: InvariantCategory[] = []; + for (const violation of violations) { + if (!seen.includes(violation.category)) { + seen.push(violation.category); + } + } + return seen; +} + +/** + * What differs between the source record and the compiled one. + * + * Whole equality, not a spot check: a binary that shipped a different component, + * lost an embedded asset, or resolved a different dependency answers differently + * somewhere in the record, and naming the first field that differs is how a + * reader finds out where. + */ +export function compareRecords(source: unknown, compiled: unknown): string[] { + const differences: string[] = []; + walk(source, compiled, "", differences); + return differences; +} + +function walk(left: unknown, right: unknown, path: string, differences: string[]): void { + const here = path.length === 0 ? "" : path; + if (Array.isArray(left) || Array.isArray(right)) { + if (!Array.isArray(left) || !Array.isArray(right)) { + differences.push(`${here}: one side is an array and the other is not`); + return; + } + if (left.length !== right.length) { + differences.push(`${here}: ${left.length} entries against ${right.length}`); + return; + } + left.forEach((entry, index) => walk(entry, right[index], `${path}[${index}]`, differences)); + return; + } + if (typeof left === "object" && left !== null && typeof right === "object" && right !== null) { + const names = new Set([...Object.keys(left), ...Object.keys(right)]); + for (const name of [...names].sort()) { + if (!(name in left) || !(name in right)) { + differences.push(`${path}.${name}: present on one side only`); + continue; + } + walk(Reflect.get(left, name), Reflect.get(right, name), `${path}.${name}`, differences); + } + return; + } + if (!Object.is(left, right)) { + differences.push(`${here}: ${JSON.stringify(left)} against ${JSON.stringify(right)}`); + } +} + +export interface ProductionSurface { + /** Every production manifest, by path, with its declared dependency names. */ + readonly dependencies: Readonly>; + /** Every published export specifier, by manifest path. */ + readonly exports: Readonly>; +} + +/** + * What a production package would have to have adopted for this proof to have + * leaked out of `scripts/tests/`. + * + * The proof is disposable test infrastructure: no shipped package may depend on + * the terminal renderer it drives, and no export map may name a module under + * the proof directory. + */ +export function checkProductionBoundary(surface: ProductionSurface): string[] { + const leaks: string[] = []; + for (const [manifest, names] of Object.entries(surface.dependencies)) { + if (names.includes("@bomb.sh/tty")) { + leaks.push(`${manifest} depends on @bomb.sh/tty`); + } + } + for (const [manifest, specifiers] of Object.entries(surface.exports)) { + for (const specifier of specifiers) { + if (specifier.includes("session-rendering")) { + leaks.push(`${manifest} exports ${specifier}`); + } + } + } + return leaks; +} diff --git a/scripts/tests/session-rendering/journey.ts b/scripts/tests/session-rendering/journey.ts new file mode 100644 index 000000000..f361a3b67 --- /dev/null +++ b/scripts/tests/session-rendering/journey.ts @@ -0,0 +1,964 @@ +/** + * One finite session journey, owned by a single Effection scope. + * + * A source publishes immutable snapshots of a conversation. An ingest task + * reduces each one the moment it arrives, and a projector renders whatever the + * newest state says — never the snapshot that woke it, if a later one landed + * while it was suspended. That split is the whole point: while one presentation + * is blocked mid-projection the source keeps publishing, and what commits + * afterwards has to be the latest completed revision rather than the backlog + * replayed in order. + * + * Everything above the terminal belongs here — ordered history, stable entry + * identity, replacement, dirty-id collapsing, which entries are visible, the + * anchor entry, follow mode and the unread count. `@bomb.sh/tty` owns layout, + * clipping, input decoding, resize processing and the ANSI bytes, and is asked + * for a complete operation tree every frame. + * + * The entry shape is private to this module on purpose. It is not a normalized + * entry, it is not a component prop, and nothing outside this directory may + * grow a dependency on it. + */ + +import { createQueue, ensure, Err, Ok, scoped, spawn, until, withResolvers } from "effection"; +import type { Operation, Result } from "effection"; +import { close, createTerm, grow, open } from "@bomb.sh/tty"; +import { createInput } from "@bomb.sh/tty"; +import type { Op, Term } from "@bomb.sh/tty"; +import { join, relative, resolve } from "node:path"; +import { readTextFile } from "@effectionx/fs"; + +import { DocumentOutput } from "../../../packages/core/src/api.ts"; +import { collect } from "../../../packages/core/src/collect.ts"; +import { execute } from "../../../packages/core/src/execute.ts"; +import { inlineSource } from "../../../packages/core/src/root-source.ts"; +import { registerComponents } from "../../../packages/core/src/components/registration.ts"; +import { selectComponent } from "../../../packages/core/src/components/select.ts"; +import { Component } from "../../../packages/core/src/component-api.ts"; +import { FILES_ERROR, Files, FilesError } from "../../../packages/runtime/files.ts"; +import type { + FilePathInput, + FileWriteSuccess, + GlobInput, +} from "../../../packages/runtime/files.ts"; +import { InMemoryStream } from "../../../packages/durable-streams/mod.ts"; +import { + blockRows, + describeOperations, + entryOperations, + entrySlice, + lexProofMarkdown, +} from "./markdown-projection.ts"; +import type { Block, OperationDescription } from "./markdown-projection.ts"; + +/** The evidence schema this journey emits, so a reader can tell versions apart. */ +export const REPORT_SCHEMA = "executablemd.proof.session-rendering/v1"; + +/** The dependency whose operations and bytes this proof is about. */ +export const TTY_PACKAGE = "@bomb.sh/tty"; +export const TTY_VERSION = "0.9.0"; + +/** + * Every way this journey can be made to misbehave, and nothing else. + * + * Each one is a rejecting control for one row of the evidence matrix: it runs + * in a process of its own, and the same invariant checker that admits the + * positive journey has to reject it for the category that names the claim. + */ +export const JOURNEY_MUTATIONS = [ + "omit-component", + "default-before-repository", + "plain-markdown", + "unstable-regions", + "no-coalescing", + "forced-follow", + "row-offset-viewport", + "whole-history-repaint", + "forbidden-read", +] as const; + +export type JourneyMutation = (typeof JOURNEY_MUTATIONS)[number]; + +export function parseJourneyMutation(value: string): JourneyMutation | undefined { + return JOURNEY_MUTATIONS.find((mutation) => mutation === value); +} + +/** The seven presentations this proof selects, in the order history holds them. */ +type Presentation = "user" | "assistant" | "tool" | "permission" | "status" | "unknown" | "thought"; + +/** + * The component each presentation resolves to. + * + * The mapping is private: a document writes the component name, and nothing + * outside this module learns that a local discriminator chose it. + */ +const COMPONENT_OF: Record = { + user: "Session.Message.User", + assistant: "Session.Message.Assistant", + tool: "Session.Message.Tool", + permission: "Session.Message.Permission", + status: "Session.Message.Status", + unknown: "Session.Message.Unknown", + thought: "Session.Message.Thought", +}; + +const HISTORY: readonly Presentation[] = [ + "user", + "assistant", + "tool", + "permission", + "status", + "unknown", + "thought", +]; + +/** One entry as the source publishes it. Immutable, and private to this module. */ +interface Entry { + readonly id: string; + readonly presentation: Presentation; + readonly revision: number; + readonly complete: boolean; + readonly markdown: string; +} + +/** One published snapshot: the whole conversation as the source then saw it. */ +type Snapshot = readonly Entry[]; + +const TWO_PARAGRAPHS = "First *emphasis* line.\n\nSecond line."; +const WITH_CODE = `${TWO_PARAGRAPHS}\n\n\`\`\`ts\nconst proof: number = 1;\n\`\`\``; + +/** The payload each presentation carries on its first publication. */ +const INITIAL_MARKDOWN: Record = { + user: TWO_PARAGRAPHS, + assistant: TWO_PARAGRAPHS, + tool: WITH_CODE, + permission: TWO_PARAGRAPHS, + status: TWO_PARAGRAPHS, + // Carried by an entry the initial viewport shows as well as by the tool, so + // that the structured-content claim does not quietly depend on the view + // having scrolled far enough to reach a fenced block. + unknown: WITH_CODE, + thought: TWO_PARAGRAPHS, +}; + +/** What every payload collapses to when the journey flattens its Markdown. */ +const PLAIN_MARKDOWN = "One line of ordinary prose."; + +const THOUGHT_ID = "entry-thought"; + +function entryId(presentation: Presentation): string { + return `entry-${presentation}`; +} + +function frozen(entries: readonly Entry[]): Snapshot { + return Object.freeze(entries.map((entry) => Object.freeze({ ...entry }))); +} + +/** What one committed projection is: its Markdown, its blocks and its provenance. */ +interface Projection { + readonly id: string; + readonly component: string; + readonly componentPath: string; + readonly revision: number; + readonly complete: boolean; + readonly raw: string; + readonly blocks: readonly Block[]; +} + +/** One request the document filesystem boundary saw, and what the ledger said. */ +export interface FilesRequest { + readonly operation: string; + readonly path: string; + readonly admitted: boolean; +} + +/** One rendered frame, as the report carries it. */ +export interface FrameRecord { + readonly label: string; + readonly width: number; + readonly height: number; + readonly visible: readonly string[]; + readonly anchor: string; + readonly follow: boolean; + readonly unread: number; + readonly bytes: number; + readonly operations: readonly OperationDescription[]; +} + +/** One commit the projector made, in the order it made them. */ +export interface CommitRecord { + readonly id: string; + readonly revision: number; + readonly complete: boolean; + readonly viewVersion: number; +} + +/** Where one of the seven names resolved, asked of the resolver itself. */ +export interface PresentationRecord { + readonly component: string; + readonly path: string; + readonly root: string; +} + +/** One committed projection, as the report carries it. */ +export interface ProjectionRecord { + readonly id: string; + readonly component: string; + readonly componentPath: string; + readonly revision: number; + readonly complete: boolean; + readonly raw: string; +} + +export interface JourneyReport { + readonly schema: string; + readonly dependency: { readonly name: string; readonly version: string }; + readonly authorities: Readonly>; + readonly presentations: readonly PresentationRecord[]; + readonly projections: readonly ProjectionRecord[]; + readonly history: readonly string[]; + readonly commits: readonly CommitRecord[]; + readonly timeline: readonly string[]; + readonly barrier: { + readonly ingestedWhileBlocked: readonly number[]; + readonly releasedAfterVersion: number; + readonly committedAfterRelease: readonly CommitRecord[]; + }; + readonly frames: readonly FrameRecord[]; + readonly resize: { + readonly requested: readonly { readonly width: number; readonly height: number }[]; + readonly adopted: { readonly width: number; readonly height: number }; + readonly anchorBefore: string; + readonly anchorAfter: string; + readonly followBefore: boolean; + readonly followAfter: boolean; + readonly unreadBefore: number; + readonly unreadAfter: number; + readonly historyBefore: readonly string[]; + readonly historyAfter: readonly string[]; + }; + readonly diff: { + readonly incrementalBytes: number; + readonly freshBytes: number; + readonly neighbours: readonly string[]; + readonly neighboursBefore: readonly OperationDescription[]; + readonly neighboursAfter: readonly OperationDescription[]; + }; + readonly files: readonly FilesRequest[]; + readonly discardedProjections: number; +} + +const INITIAL_WIDTH = 60; +const INITIAL_HEIGHT = 12; +const RESIZE_BATCH = [ + { width: 70, height: 14 }, + { width: 80, height: 16 }, +] as const; + +/** The `@bomb.sh/tty` key bytes this journey feeds through the input parser. */ +const PAGE_UP = "\x1b[5~"; +const END = "\x1b[F"; + +/** The permissions the journey reports, queried rather than assumed. */ +function authorities(root: string): Record { + const record: Record = {}; + for (const name of ["net", "write", "run", "sys", "ffi", "env"] as const) { + record[name] = Deno.permissions.querySync({ name }).state; + } + record.read = Deno.permissions.querySync({ name: "read", path: root }).state; + return record; +} + +/** + * The document filesystem ledger. + * + * Every request is recorded with the verdict it got, and only paths inside the + * proof's own component roots are admitted. A journey that reached for anything + * else — a provider file, a session store, a host configuration — leaves a + * refused entry behind, which is what the forbidden-integration oracle reads. + */ +function useFilesLedger(root: string, ledger: FilesRequest[]): Operation { + function admits(input: { readonly cwd: string; readonly path: string }): boolean { + const inside = relative(root, resolve(input.cwd, input.path)); + return inside.length > 0 && !inside.startsWith("..") && !inside.startsWith("/"); + } + + function refuse(operation: "read" | "check-file-path"): Result { + return Err( + new FilesError({ + type: FILES_ERROR, + operation, + phase: "lexical", + reason: "resolved-escape", + }), + ); + } + + function deny(operation: string, path: string): Result { + ledger.push({ operation, path, admitted: false }); + return refuse("check-file-path"); + } + + return Files.around({ + // deno-lint-ignore require-yield + *checkFilePath([input]: [FilePathInput]) { + if (!admits(input)) { + return deny("check-file-path", input.path); + } + ledger.push({ operation: "check-file-path", path: input.path, admitted: true }); + return Ok(undefined); + }, + *readTextFile([input]: [FilePathInput]) { + if (!admits(input)) { + return deny("read", input.path); + } + ledger.push({ operation: "read", path: input.path, admitted: true }); + return Ok(yield* readTextFile(resolve(input.cwd, input.path))); + }, + // deno-lint-ignore require-yield + *writeTextFile([input]: [FilePathInput]) { + return deny("write", input.path); + }, + // deno-lint-ignore require-yield + *deleteFile([input]: [FilePathInput]) { + return deny("delete", input.path); + }, + // deno-lint-ignore require-yield + *ensureDirectory([input]: [FilePathInput]) { + return deny("ensure-directory", input.path); + }, + // deno-lint-ignore require-yield + *globFiles([input]: [GlobInput]) { + return deny("glob", input.include.join(",")); + }, + // deno-lint-ignore require-yield + *temporaryDirectory() { + return deny("temporary-directory", ""); + }, + }); +} + +interface SnapshotScript { + /** One snapshot per presentation, growing the conversation to its full history. */ + readonly initial: readonly Snapshot[]; + /** The revision whose projection blocks. */ + readonly blocking: Snapshot; + /** Two further revisions and the completion, published while that one is held. */ + readonly whileBlocked: readonly Snapshot[]; + readonly appendOffBottom: Snapshot; + readonly appendFollowing: Snapshot; +} + +/** + * The fixed sequence of snapshots this journey publishes. + * + * Everything the journey waits for is an event or a barrier and no step is + * timed, so the same order holds under any scheduling. + */ +function journeySnapshots(mutation: JourneyMutation | undefined): SnapshotScript { + const presentations = + mutation === "omit-component" + ? HISTORY.filter((presentation) => presentation !== "unknown") + : HISTORY; + const markdownOf = (presentation: Presentation): string => + mutation === "plain-markdown" ? PLAIN_MARKDOWN : INITIAL_MARKDOWN[presentation]; + + let conversation: Entry[] = []; + const initial: Snapshot[] = []; + for (const presentation of presentations) { + conversation = [ + ...conversation, + { + id: entryId(presentation), + presentation, + revision: 1, + complete: true, + markdown: markdownOf(presentation), + }, + ]; + initial.push(frozen(conversation)); + } + + const thoughtText = (revision: number): string => + mutation === "plain-markdown" + ? `${PLAIN_MARKDOWN} Revision ${revision}.` + : `First *emphasis* line, revision ${revision}.\n\nSecond line.`; + + const revise = (revision: number, complete: boolean): Snapshot => { + conversation = conversation.map((entry) => + entry.id === THOUGHT_ID + ? { ...entry, revision, complete, markdown: thoughtText(revision) } + : entry, + ); + return frozen(conversation); + }; + + const blocking = revise(2, false); + const whileBlocked = [revise(3, false), revise(4, false), revise(5, true)]; + + conversation = [ + ...conversation, + { + id: "entry-appended", + presentation: "status", + revision: 1, + complete: true, + markdown: markdownOf("status"), + }, + ]; + const appendOffBottom = frozen(conversation); + + conversation = [ + ...conversation, + { + id: "entry-final", + presentation: "assistant", + revision: 1, + complete: true, + markdown: markdownOf("assistant"), + }, + ]; + + return { + initial, + blocking, + whileBlocked, + appendOffBottom, + appendFollowing: frozen(conversation), + }; +} + +export function runJourney(options: { + readonly root: string; + readonly mutation?: JourneyMutation; +}): Operation { + const { root, mutation } = options; + return scoped(function* (): Operation { + const ledger: FilesRequest[] = []; + const timeline: string[] = []; + const commits: CommitRecord[] = []; + const frames: FrameRecord[] = []; + const ingestedWhileBlocked: number[] = []; + let discardedProjections = 0; + let barrierReleased = false; + + // Cleanup is established before anything is acquired or subscribed. The tty + // objects hold no host resource of their own — construction instantiates + // bundled WebAssembly and performs no terminal I/O — so teardown is this + // scope dropping its references. + yield* ensure(() => { + timeline.push("scope:closed"); + }); + + yield* useFilesLedger(root, ledger); + + const includes = + mutation === "default-before-repository" + ? [join(root, "defaults"), join(root, "repository", "components")] + : [join(root, "repository", "components"), join(root, "defaults")]; + + const barrierEngaged = withResolvers(); + const barrierRelease = withResolvers(); + const backlogIngested = withResolvers(); + let thoughtProjections = 0; + + yield* registerComponents([ + { + name: "ProofBarrier", + origin: "session-rendering-proof", + description: "Holds the second Thought projection open so later revisions arrive first.", + props: { type: "object", properties: {}, additionalProperties: false }, + *fn(): Operation { + thoughtProjections++; + if (thoughtProjections === 2) { + timeline.push("barrier:engaged"); + barrierEngaged.resolve(); + yield* barrierRelease.operation; + timeline.push("barrier:resumed"); + } + return ""; + }, + }, + ]); + + const presentations = yield* describePresentations(root, includes, mutation); + + const term = yield* until(createTerm({ width: INITIAL_WIDTH, height: INITIAL_HEIGHT })); + const input = yield* until(createInput({ escLatency: 1 })); + + // The permitted probe: the ledger admits the proof's own component roots, + // and the positive run is the one that shows it admitting something. + yield* Files.operations.checkFilePath({ + cwd: root, + path: join("defaults", "Session", "Message", "User.md"), + }); + if (mutation === "forbidden-read") { + yield* Files.operations.readTextFile({ cwd: root, path: "../../../../etc/hosts" }); + } + + const script = journeySnapshots(mutation); + const snapshots = createQueue(); + const wake = createQueue(); + const settled = createQueue(); + + let state: Snapshot = []; + let version = 0; + const dirty = new Set(); + const backlog: Entry[] = []; + const order: string[] = []; + const committed = new Map(); + + const gates = { + replace: withResolvers(), + appendOffBottom: withResolvers(), + appendFollowing: withResolvers(), + }; + + yield* spawn(function* source(): Operation { + for (const snapshot of script.initial) { + snapshots.add(snapshot); + } + yield* gates.replace.operation; + snapshots.add(script.blocking); + // Published without waiting for anything to render: two later revisions + // and the completion land while the projector is still inside the Thought + // it started before them. + yield* barrierEngaged.operation; + for (const snapshot of script.whileBlocked) { + snapshots.add(snapshot); + } + yield* gates.appendOffBottom.operation; + snapshots.add(script.appendOffBottom); + yield* gates.appendFollowing.operation; + snapshots.add(script.appendFollowing); + }); + + yield* spawn(function* ingest(): Operation { + while (true) { + const arrived = yield* snapshots.next(); + if (arrived.done) { + return; + } + const snapshot = arrived.value; + version++; + for (const entry of snapshot) { + const previous = state.find((candidate) => candidate.id === entry.id); + if ( + previous === undefined || + previous.revision !== entry.revision || + previous.complete !== entry.complete || + previous.markdown !== entry.markdown + ) { + dirty.add(entry.id); + if (mutation === "no-coalescing") { + backlog.push(entry); + } + } + if (!order.includes(entry.id)) { + order.push(entry.id); + } + } + state = snapshot; + timeline.push(`ingest:v${version}`); + if (thoughtProjections === 2 && !barrierReleased) { + ingestedWhileBlocked.push(version); + if (ingestedWhileBlocked.length === script.whileBlocked.length) { + backlogIngested.resolve(); + } + } + wake.add(version); + } + }); + + const viewport = { anchorIndex: 0, follow: true, unread: 0, anchorRowsFromEnd: 0 }; + let width = INITIAL_WIDTH; + let height = INITIAL_HEIGHT; + let currentTerm: Term = term; + + function rowsOf(id: string): number { + const projection = committed.get(id); + return projection === undefined ? 0 : blockRows(projection.blocks); + } + + function bottomAnchorIndex(): number { + let used = 0; + let index = order.length - 1; + while (index >= 0) { + const rows = rowsOf(order[index]); + if (used + rows > height && index < order.length - 1) { + break; + } + used += rows; + index--; + } + return index + 1; + } + + function visibleIds(): string[] { + const visible: string[] = []; + let used = 0; + for (let index = viewport.anchorIndex; index < order.length; index++) { + const rows = rowsOf(order[index]); + if (used + rows > height && visible.length > 0) { + break; + } + used += rows; + visible.push(order[index]); + } + return visible; + } + + function rowsBefore(index: number): number { + let rows = 0; + for (let cursor = 0; cursor < index; cursor++) { + rows += rowsOf(order[cursor]); + } + return rows; + } + + function frameOperations(visible: readonly string[]): Op[] { + const ops: Op[] = [ + open("viewport", { layout: { width: grow(), height: grow(), direction: "ttb" } }), + ]; + for (const id of visible) { + const projection = committed.get(id); + if (projection !== undefined) { + ops.push(...entryOperations(id, projection.blocks)); + } + } + ops.push(close()); + return ops; + } + + function* render(label: string): Operation { + if (viewport.follow) { + viewport.anchorIndex = bottomAnchorIndex(); + } + const visible = visibleIds(); + const ops = frameOperations(visible); + // A whole-history repaint throws the previous frame away, which is what + // makes every update cost a full screen instead of a diff. + if (mutation === "whole-history-repaint") { + currentTerm = yield* until(createTerm({ width, height })); + } + const result = currentTerm.render(ops); + if (result.errors.length > 0) { + throw new Error(`tty reported ${result.errors.length} layout error(s) on frame ${label}`); + } + // The output view expires on the next render or update, so it is copied + // here rather than kept. + const bytes = Uint8Array.from(result.output); + const record: FrameRecord = { + label, + width, + height, + visible, + anchor: order[viewport.anchorIndex] ?? "", + follow: viewport.follow, + unread: viewport.unread, + bytes: bytes.length, + operations: describeOperations(ops), + }; + frames.push(record); + return record; + } + + function* projectOnce(entry: Entry): Operation { + const component = COMPONENT_OF[entry.presentation]; + const selection = yield* scoped(function* () { + return yield* selectComponent(component, { + includes, + registry: yield* Component.operations.registry, + }); + }); + const componentPath = + selection.kind === "repository" ? relative(root, resolve(selection.path)) : selection.kind; + const captured: string[] = []; + yield* scoped(function* () { + yield* DocumentOutput.around({ + *output([text, exact], next) { + captured.push(text); + yield* next(text, exact); + }, + }); + yield* collect( + yield* execute({ + ...inlineSource(`<${component}>\n${entry.markdown}\n\n`), + stream: new InMemoryStream(), + includes, + secretDetection: false, + }), + ); + }); + const raw = captured.join(""); + return { + id: entry.id, + component, + componentPath, + revision: entry.revision, + complete: entry.complete, + raw, + blocks: lexProofMarkdown(raw), + }; + } + + function commit(projection: Projection, shadowed: boolean): void { + if (shadowed) { + const shadow = `${projection.id}#${projection.revision}`; + committed.set(shadow, projection); + order.push(shadow); + } else { + committed.set(projection.id, projection); + } + commits.push({ + id: projection.id, + revision: projection.revision, + complete: projection.complete, + viewVersion: version, + }); + } + + /** + * Project whatever the ingest task has reduced, and commit only that. + * + * A projection records the version it began with. If the source advanced + * while it was suspended, the result describes a state nobody is looking at + * any more, so it is dropped and the newest state is projected instead — + * which is also why a replacement can never be appended: the commit is keyed + * by the entry's own id. + */ + function* drain(): Operation { + while (dirty.size > 0 || backlog.length > 0) { + if (mutation === "no-coalescing") { + const entry = backlog.shift(); + if (entry === undefined) { + dirty.clear(); + continue; + } + commit(yield* projectOnce(entry), false); + dirty.delete(entry.id); + continue; + } + const id = [...dirty][0]; + const began = version; + const entry = state.find((candidate) => candidate.id === id); + if (entry === undefined) { + dirty.delete(id); + continue; + } + const projection = yield* projectOnce(entry); + if (version !== began) { + discardedProjections++; + timeline.push(`project:discarded:${id}`); + continue; + } + dirty.delete(id); + commit(projection, mutation === "unstable-regions" && committed.has(id)); + } + } + + yield* spawn(function* project(): Operation { + while (true) { + const awoken = yield* wake.next(); + if (awoken.done) { + return; + } + yield* drain(); + settled.add(version); + } + }); + + function* settleAt(target: number): Operation { + while (true) { + const next = yield* settled.next(); + if (next.done) { + return; + } + if (next.value >= target && dirty.size === 0) { + return; + } + } + } + + const throughInitial = script.initial.length; + yield* settleAt(throughInitial); + yield* render("initial"); + + gates.replace.resolve(); + yield* barrierEngaged.operation; + // Ingestion has to reach the completion snapshot before the barrier opens; + // that is what makes the coalescing claim a claim about a real backlog. + yield* backlogIngested.operation; + const releasedAfterVersion = version; + barrierReleased = true; + timeline.push("barrier:released"); + const commitsBeforeRelease = commits.length; + barrierRelease.resolve(); + const throughReplacement = throughInitial + 1 + script.whileBlocked.length; + yield* settleAt(throughReplacement); + // Read the post-release commits here, while the replacement is the only + // thing that has happened since: the claim is about what the backlog + // collapsed to, not about everything the journey committed afterwards. + const committedAfterRelease = commits.slice(commitsBeforeRelease); + + const beforeCompletion = frames[frames.length - 1]; + const neighbours = neighbourIds(order, THOUGHT_ID); + const completionFrame = yield* render("thought-completion"); + const freshTerm = yield* until(createTerm({ width, height })); + const freshResult = freshTerm.render(frameOperations(completionFrame.visible)); + const freshBytes = Uint8Array.from(freshResult.output).length; + + // Page Up until the oldest entry is the anchor. Follow is released by the + // decoded key rather than by the loop finishing. + const decoder = new TextEncoder(); + let presses = 0; + while (viewport.anchorIndex > 0 && presses <= order.length) { + presses++; + const scan = input.scan(decoder.encode(PAGE_UP)); + for (const event of scan.events) { + if (event.type !== "keydown" || event.code !== "PageUp") { + continue; + } + if (mutation === "forced-follow") { + continue; + } + viewport.follow = false; + viewport.anchorIndex = Math.max(0, viewport.anchorIndex - Math.max(1, visibleIds().length)); + } + if (mutation === "forced-follow") { + break; + } + } + viewport.anchorRowsFromEnd = rowsBefore(order.length) - rowsBefore(viewport.anchorIndex); + yield* render("scrolled-to-oldest"); + + gates.appendOffBottom.resolve(); + yield* settleAt(throughReplacement + 1); + if (!viewport.follow && !visibleIds().includes(order[order.length - 1])) { + viewport.unread++; + } + yield* render("appended-off-bottom"); + + const anchorBefore = order[viewport.anchorIndex] ?? ""; + const followBefore = viewport.follow; + const unreadBefore = viewport.unread; + const historyBefore = [...order]; + currentTerm.update({ events: RESIZE_BATCH.map((size) => ({ type: "resize", ...size })) }); + const adopted = RESIZE_BATCH[RESIZE_BATCH.length - 1]; + const previousHeight = height; + width = adopted.width; + height = adopted.height; + if (mutation === "row-offset-viewport") { + // The anchor kept as a row offset rather than as an entry: a taller + // viewport moves that offset onto a different entry, which is exactly the + // mistake a stable anchor id cannot make. + viewport.anchorIndex = Math.min( + Math.max(order.length - 1, 0), + viewport.anchorIndex + (height - previousHeight), + ); + } + const resizeFrame = yield* render("resized"); + // Read where the resize left things before anything else moves them: the + // claim is about what one batch of resize events preserved, not about what + // the rest of the journey went on to do. + const resized = { + requested: RESIZE_BATCH.map((size) => ({ ...size })), + adopted: { ...adopted }, + anchorBefore, + anchorAfter: resizeFrame.anchor, + followBefore, + followAfter: resizeFrame.follow, + unreadBefore, + unreadAfter: resizeFrame.unread, + historyBefore, + historyAfter: [...order], + }; + + for (const event of input.scan(decoder.encode(END)).events) { + if (event.type === "keydown" && event.code === "End") { + viewport.follow = true; + viewport.unread = 0; + } + } + yield* render("returned-to-bottom"); + + gates.appendFollowing.resolve(); + yield* settleAt(throughReplacement + 2); + yield* render("appended-while-following"); + + return { + schema: REPORT_SCHEMA, + dependency: { name: TTY_PACKAGE, version: TTY_VERSION }, + authorities: authorities(root), + presentations, + projections: [...committed.values()].map((projection) => ({ + id: projection.id, + component: projection.component, + componentPath: projection.componentPath, + revision: projection.revision, + complete: projection.complete, + raw: projection.raw, + })), + history: [...order], + commits, + timeline, + barrier: { + ingestedWhileBlocked, + releasedAfterVersion, + committedAfterRelease, + }, + frames, + resize: resized, + diff: { + incrementalBytes: completionFrame.bytes, + freshBytes, + neighbours, + neighboursBefore: neighbours.flatMap((id) => entrySlice(beforeCompletion.operations, id)), + neighboursAfter: neighbours.flatMap((id) => entrySlice(completionFrame.operations, id)), + }, + files: ledger, + discardedProjections, + }; + }); +} + +/** The two entries immediately before `id` in history order. */ +function neighbourIds(order: readonly string[], id: string): string[] { + const index = order.indexOf(id); + if (index < 2) { + return order.filter((candidate) => candidate !== id).slice(0, 2); + } + return [order[index - 2], order[index - 1]]; +} + +/** Where each name resolved, asked of the resolver the engine itself uses. */ +function* describePresentations( + root: string, + includes: readonly string[], + mutation: JourneyMutation | undefined, +): Operation { + const presentations = + mutation === "omit-component" + ? HISTORY.filter((presentation) => presentation !== "unknown") + : HISTORY; + const records: PresentationRecord[] = []; + for (const presentation of presentations) { + const component = COMPONENT_OF[presentation]; + const selection = yield* scoped(function* () { + return yield* selectComponent(component, { + includes, + registry: yield* Component.operations.registry, + }); + }); + if (selection.kind !== "repository") { + throw new Error(`${component} resolved to ${selection.kind}, not to a proof Markdown file`); + } + const path = relative(root, resolve(selection.path)); + records.push({ + component, + path, + root: path.startsWith("repository/components") ? "repository/components" : "defaults", + }); + } + return records; +} diff --git a/scripts/tests/session-rendering/markdown-projection.ts b/scripts/tests/session-rendering/markdown-projection.ts new file mode 100644 index 000000000..0f723aa59 --- /dev/null +++ b/scripts/tests/session-rendering/markdown-projection.ts @@ -0,0 +1,251 @@ +/** + * The ordinary Markdown a presentation rendered, projected into `@bomb.sh/tty` + * operations. + * + * The projection is deliberately narrow. It understands paragraphs, inline + * emphasis and fenced code and refuses everything else, because a projector + * that quietly degraded an unsupported token into plain text would let a + * uniform-plain-text rendering pass the structured-content oracle. The three + * shapes it does understand become three independently recognizable things in + * the operation tree — a paragraph container, an emphasis attribute on a text + * operation, and a code container holding one code text operation — so no + * single mistake can satisfy all three at once. + * + * Nothing here formats for a terminal. The Markdown arrives exactly as the + * document emitted it, and `@bomb.sh/tty` alone decides what bytes a frame + * becomes. + */ + +import { marked } from "marked"; +import { close, open, text } from "@bomb.sh/tty"; +import type { Op } from "@bomb.sh/tty"; + +/** + * The italic attribute bit, which `@bomb.sh/tty` 0.9.0 emits as `SGR 3`. + * + * Named for the Markdown it carries rather than for the escape it produces: + * what this proof asserts is that emphasis survived as an attribute, and the + * byte sequence behind it belongs to tty. + */ +export const EMPHASIS_ATTRIBUTE = 4; + +/** An inline run of one paragraph: its text, and whether Markdown emphasized it. */ +export interface InlineRun { + readonly content: string; + readonly emphasis: boolean; +} + +export type Block = + | { readonly kind: "paragraph"; readonly runs: readonly InlineRun[] } + | { readonly kind: "code"; readonly language: string; readonly content: string }; + +/** A token this projector does not understand, named where it was found. */ +export class UnsupportedMarkdownError extends Error { + readonly token: string; + + constructor(token: string) { + super(`the proof projector does not render Markdown token "${token}"`); + this.name = "UnsupportedMarkdownError"; + this.token = token; + } +} + +function tokenType(token: unknown): string { + if (typeof token !== "object" || token === null || !("type" in token)) { + return "unknown"; + } + const type = token.type; + return typeof type === "string" ? type : "unknown"; +} + +function tokenText(token: unknown): string { + if (typeof token === "object" && token !== null && "text" in token) { + const value = token.text; + if (typeof value === "string") { + return value; + } + } + return ""; +} + +function tokenLanguage(token: unknown): string { + if (typeof token === "object" && token !== null && "lang" in token) { + const value = token.lang; + if (typeof value === "string") { + return value; + } + } + return ""; +} + +function childTokens(token: unknown): unknown[] { + if (typeof token === "object" && token !== null && "tokens" in token) { + const value = token.tokens; + if (Array.isArray(value)) { + return value; + } + } + return []; +} + +function inlineRuns(tokens: readonly unknown[]): InlineRun[] { + const runs: InlineRun[] = []; + for (const token of tokens) { + const type = tokenType(token); + if (type === "text") { + runs.push({ content: tokenText(token), emphasis: false }); + continue; + } + if (type === "em") { + // Emphasis nests its own text token; the proof payloads never nest + // further, and anything that did would arrive here as an unsupported + // token rather than as silently flattened prose. + for (const child of childTokens(token)) { + if (tokenType(child) !== "text") { + throw new UnsupportedMarkdownError(tokenType(child)); + } + runs.push({ content: tokenText(child), emphasis: true }); + } + continue; + } + throw new UnsupportedMarkdownError(type); + } + return runs; +} + +/** + * The blocks one presentation's Markdown contains. + * + * Blank space between blocks is Markdown's own separator rather than content, + * so it is dropped; every other token this does not understand stops the + * projection. + */ +export function lexProofMarkdown(source: string): Block[] { + const blocks: Block[] = []; + for (const token of marked.lexer(source)) { + const type = tokenType(token); + if (type === "space") { + continue; + } + if (type === "paragraph") { + blocks.push({ kind: "paragraph", runs: inlineRuns(childTokens(token)) }); + continue; + } + if (type === "code") { + blocks.push({ kind: "code", language: tokenLanguage(token), content: tokenText(token) }); + continue; + } + throw new UnsupportedMarkdownError(type); + } + return blocks; +} + +/** The container id of one entry, which every frame reuses for that entry. */ +export function entryContainerId(entryId: string): string { + return `entry/${entryId}`; +} + +/** + * The operations one entry contributes to a frame. + * + * Container ids are derived from the entry's own stable id, so the same entry + * occupies the same container across every frame it appears in and a + * replacement cannot arrive as a new element. + */ +export function entryOperations(entryId: string, blocks: readonly Block[]): Op[] { + const container = entryContainerId(entryId); + const ops: Op[] = [open(container, { layout: { direction: "ttb" } })]; + blocks.forEach((block, index) => { + if (block.kind === "paragraph") { + ops.push(open(`${container}/paragraph/${index}`, { layout: { direction: "ltr" } })); + for (const run of block.runs) { + ops.push(text(run.content, run.emphasis ? { attrs: EMPHASIS_ATTRIBUTE } : {})); + } + ops.push(close()); + return; + } + ops.push(open(`${container}/code/${index}`, { layout: { direction: "ttb" } })); + ops.push(text(block.content)); + ops.push(close()); + }); + ops.push(close()); + return ops; +} + +/** How many terminal rows an entry's blocks occupy. */ +export function blockRows(blocks: readonly Block[]): number { + return blocks.reduce( + (rows, block) => rows + (block.kind === "paragraph" ? 1 : block.content.split("\n").length), + 0, + ); +} + +/** What a container id says the element is. */ +export type OperationRole = "viewport" | "entry" | "paragraph" | "code"; + +export type OperationDescription = + | { readonly kind: "open"; readonly id: string; readonly role: OperationRole } + | { readonly kind: "text"; readonly content: string; readonly attrs: number } + | { readonly kind: "close" }; + +function roleOf(id: string): OperationRole { + const segments = id.split("/"); + if (segments.length >= 4 && segments[2] === "paragraph") { + return "paragraph"; + } + if (segments.length >= 4 && segments[2] === "code") { + return "code"; + } + if (segments[0] === "entry") { + return "entry"; + } + return "viewport"; +} + +/** + * The evidence form of an operation tree, read back off the operations + * themselves rather than recorded alongside them. + * + * Describing the real `Op` objects is what makes this evidence: a description + * assembled in parallel with the tree could agree with an intention the tree + * never carried. + */ +export function describeOperations(ops: readonly Op[]): OperationDescription[] { + return ops.map((op) => { + if ("id" in op) { + return { kind: "open", id: op.id, role: roleOf(op.id) }; + } + if ("content" in op) { + return { kind: "text", content: op.content, attrs: op.attrs ?? 0 }; + } + return { kind: "close" }; + }); +} + +/** The descriptions belonging to one entry's container, including its own open/close. */ +export function entrySlice( + descriptions: readonly OperationDescription[], + entryId: string, +): OperationDescription[] { + const container = entryContainerId(entryId); + const start = descriptions.findIndex( + (description) => description.kind === "open" && description.id === container, + ); + if (start === -1) { + return []; + } + let depth = 0; + for (let index = start; index < descriptions.length; index++) { + const description = descriptions[index]; + if (description.kind === "open") { + depth++; + } + if (description.kind === "close") { + depth--; + if (depth === 0) { + return descriptions.slice(start, index + 1); + } + } + } + return descriptions.slice(start); +} diff --git a/scripts/tests/session-rendering/repository/components/Session/Message/Tool.md b/scripts/tests/session-rendering/repository/components/Session/Message/Tool.md new file mode 100644 index 000000000..6ebcad57e --- /dev/null +++ b/scripts/tests/session-rendering/repository/components/Session/Message/Tool.md @@ -0,0 +1,3 @@ +xmd-proof-tool-repository + + From 7cc1752d6ae3a90c234b768842cfb714d874e093 Mon Sep 17 00:00:00 2001 From: Taras Mankovski Date: Fri, 11 Sep 2026 10:26:38 -0400 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=8C=20Measure=20the=20corpus=20wit?= =?UTF-8?q?h=20the=20session-rendering=20proof=20in=20it=20(#799)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Downloaded from the Measure test weights run for 9a3cf24, unedited. The proof measures 15.7s under Deno and is charged to no other runtime, which is what the exclusion manifest says it should be. --- test-weights.json | 1914 +++++++++++++++++++++++---------------------- 1 file changed, 982 insertions(+), 932 deletions(-) diff --git a/test-weights.json b/test-weights.json index 241580387..57ca070d4 100644 --- a/test-weights.json +++ b/test-weights.json @@ -1,8 +1,8 @@ { "version": 1, "source": { - "commit": "a7f60c024a356d6bd75d3bba4a693019693f6466", - "runUrl": "https://github.com/taras/executable.md/actions/runs/33585991716", + "commit": "9a3cf2473ca706c0ac89b66700a539a6ca368908", + "runUrl": "https://github.com/taras/executable.md/actions/runs/34599573472", "attempt": 1, "runner": "ubuntu-latest", "deno": "deno 2.9.5 (stable, release, x86_64-unknown-linux-gnu)", @@ -11,954 +11,1004 @@ }, "runtimes": { "deno": { - "packages/acp/tests/acceptance.test.ts": 5283, - "packages/acp/tests/acpx-checkpoint-meta.test.ts": 7780, - "packages/acp/tests/acpx-materialization.test.ts": 8165, - "packages/acp/tests/acpx-transient-env.test.ts": 1829, - "packages/acp/tests/adapter-materialization.test.ts": 76640, - "packages/acp/tests/adapter-protocol.test.ts": 42448, - "packages/acp/tests/native-launch.test.ts": 4700, - "packages/acp/tests/permission-bridge.test.ts": 3739, - "packages/acp/tests/provider.test.ts": 4458, - "packages/acp/tests/serial-queue.test.ts": 1565, - "packages/acp/tests/session-key.test.ts": 3521, - "packages/acp/tests/session-route.test.ts": 3748, - "packages/cli/tests/agent-adapters.test.ts": 5790, - "packages/cli/tests/agent-cli.test.ts": 25306, - "packages/cli/tests/agent-config.test.ts": 3328, - "packages/cli/tests/agent-session-coordinator.test.ts": 3988, - "packages/cli/tests/cli-help.test.ts": 14811, - "packages/cli/tests/command.test.ts": 10132, - "packages/cli/tests/compiled-upgrade.test.ts": 10076, - "packages/cli/tests/document-suites/inline/inline-markdown.test.ts": 8054, - "packages/cli/tests/document-suites/props/props-markdown.test.ts": 7565, - "packages/cli/tests/document-suites/syntax/syntax-markdown.test.ts": 11440, - "packages/cli/tests/document-suites/targets/targets-markdown.test.ts": 9031, - "packages/cli/tests/document-suites/verbose/verbose-markdown.test.ts": 14599, - "packages/cli/tests/fetch-cli.test.ts": 3793, - "packages/cli/tests/file-stream.test.ts": 1785, - "packages/cli/tests/inline-cli.test.ts": 29574, - "packages/cli/tests/launch-timeout.test.ts": 11598, - "packages/cli/tests/packaged-document.test.ts": 4824, - "packages/cli/tests/plan-args.test.ts": 2227, - "packages/cli/tests/plan-cli.test.ts": 32382, - "packages/cli/tests/plan-command-document.test.ts": 5278, - "packages/cli/tests/plan-component.test.ts": 7218, - "packages/cli/tests/plan-host-acts.test.ts": 5649, - "packages/cli/tests/plan.test.ts": 22020, - "packages/cli/tests/process-retention.test.ts": 5492, - "packages/cli/tests/props-cli.test.ts": 28673, - "packages/cli/tests/props-schema.test.ts": 3756, - "packages/cli/tests/props-sources.test.ts": 2294, - "packages/cli/tests/pull-request-read-fork.test.ts": 7542, - "packages/cli/tests/run-composition-deno.test.ts": 7396, - "packages/cli/tests/run-composition-nested.test.ts": 20736, - "packages/cli/tests/run-composition.test.ts": 6713, - "packages/cli/tests/run-deadline.test.ts": 8385, - "packages/cli/tests/run-timeouts.test.ts": 12819, - "packages/cli/tests/secret-detection-cli.test.ts": 19341, - "packages/cli/tests/service-document.test.ts": 4925, - "packages/cli/tests/service-host.test.ts": 4857, - "packages/cli/tests/session-launch-cli.test.ts": 11117, - "packages/cli/tests/stdout-delivery.test.ts": 1558, - "packages/cli/tests/syntax-cli.test.ts": 20524, - "packages/cli/tests/targets-cli.test.ts": 26747, - "packages/cli/tests/test-target.test.ts": 40235, - "packages/cli/tests/testing-activation.test.ts": 4420, - "packages/cli/tests/testing-execution-host.test.ts": 37159, - "packages/cli/tests/upgrade-cli.test.ts": 19987, - "packages/cli/tests/upgrade-command-document.test.ts": 6720, - "packages/cli/tests/upgrade-output.test.ts": 4168, - "packages/cli/tests/value-root.test.ts": 17320, - "packages/cli/tests/verbose-component.test.ts": 5037, - "packages/cli/tests/workflow-agent-sessions.test.ts": 20886, - "packages/cli/tests/workflow-agent.test.ts": 17623, - "packages/cli/tests/workflow-cli.test.ts": 98597, - "packages/cli/tests/workflow-crash.test.ts": 81856, - "packages/cli/tests/workflow-declaration.test.ts": 3993, - "packages/cli/tests/workflow-export-publication.test.ts": 18217, - "packages/cli/tests/workflow-fetch.test.ts": 8400, - "packages/cli/tests/workflow-fork.test.ts": 85734, - "packages/cli/tests/workflow-host.test.ts": 14016, - "packages/cli/tests/workflow-inspection.test.ts": 114902, - "packages/cli/tests/workflow-installation.test.ts": 6023, - "packages/cli/tests/workflow-lifecycle-control.test.ts": 20784, - "packages/cli/tests/workflow-retention.test.ts": 7188, - "packages/cli/tests/workflow-suspension.test.ts": 8876, - "packages/code-review-agent/tests/doctor.test.ts": 1538, - "packages/code-review-agent/tests/parse-diagnostics.test.ts": 1625, - "packages/code-review-agent/tests/parse-diff.test.ts": 1564, - "packages/code-review-agent/tests/parse-doctor.test.ts": 1646, - "packages/code-review-agent/tests/parse-oxlint.test.ts": 1560, - "packages/code-review-agent/tests/policy.test.ts": 1561, - "packages/core/tests/agent-api.test.ts": 1568, - "packages/core/tests/agent-components.test.ts": 4215, - "packages/core/tests/agent-function-components.test.ts": 4740, - "packages/core/tests/agent-session-launch.test.ts": 5083, - "packages/core/tests/agent-stack.test.ts": 3866, - "packages/core/tests/answers-component.test.ts": 4210, - "packages/core/tests/answers-expansion-recursion.test.ts": 2797, - "packages/core/tests/capture-errors.test.ts": 3056, - "packages/core/tests/capture-props.test.ts": 2856, - "packages/core/tests/cli-journal.test.ts": 11900, - "packages/core/tests/code-block-component.test.ts": 4731, - "packages/core/tests/compiler-boundary.test.ts": 3397, - "packages/core/tests/component-api.test.ts": 1978, - "packages/core/tests/component-registration.test.ts": 4220, - "packages/core/tests/component-returns.test.ts": 4576, - "packages/core/tests/component-schema-conformance.test.ts": 2408, - "packages/core/tests/config-api.test.ts": 3675, - "packages/core/tests/construct-error-observation.test.ts": 3105, - "packages/core/tests/contextual-cwd.test.ts": 4647, - "packages/core/tests/daemon-integration.test.ts": 4185, - "packages/core/tests/daemon.test.ts": 2200, - "packages/core/tests/declared-markdown-component.test.ts": 4411, - "packages/core/tests/document-output-api.test.ts": 1546, - "packages/core/tests/document-target-execution.test.ts": 6129, - "packages/core/tests/document-targets.test.ts": 3201, - "packages/core/tests/document-validation.test.ts": 4803, - "packages/core/tests/each.test.ts": 3659, - "packages/core/tests/elicit-component.test.ts": 4125, - "packages/core/tests/ephemeral-service.test.ts": 4063, - "packages/core/tests/eval-bindings.test.ts": 3639, - "packages/core/tests/eval-context.test.ts": 2264, - "packages/core/tests/eval-durable.test.ts": 3691, - "packages/core/tests/eval-error-mode.test.ts": 3951, - "packages/core/tests/eval-interpolate.test.ts": 1609, - "packages/core/tests/eval-middleware.test.ts": 2331, - "packages/core/tests/eval-persist.test.ts": 3715, - "packages/core/tests/eval-return.test.ts": 3635, - "packages/core/tests/eval-scope.test.ts": 3562, - "packages/core/tests/eval-timeout.test.ts": 3693, - "packages/core/tests/eval-transform.test.ts": 2144, - "packages/core/tests/exec-timeout.test.ts": 3666, - "packages/core/tests/execute.test.ts": 4251, - "packages/core/tests/execution-protocol.test.ts": 5110, - "packages/core/tests/expand.test.ts": 3466, - "packages/core/tests/expansion-identity.test.ts": 4325, - "packages/core/tests/expansion-metadata.test.ts": 3098, - "packages/core/tests/expression-props.test.ts": 4191, - "packages/core/tests/fail-component.test.ts": 3900, - "packages/core/tests/failure-printing.test.ts": 3936, - "packages/core/tests/fatal-cause.test.ts": 3092, - "packages/core/tests/fetch-component.test.ts": 5225, - "packages/core/tests/file-component.test.ts": 5638, - "packages/core/tests/file-delete-component.test.ts": 3848, - "packages/core/tests/files-fatal.test.ts": 4685, - "packages/core/tests/foreground-exec.test.ts": 4777, - "packages/core/tests/frontmatter.test.ts": 2096, - "packages/core/tests/function-components.test.ts": 4213, - "packages/core/tests/generated-xmd.test.ts": 4897, - "packages/core/tests/glob-api.test.ts": 1973, - "packages/core/tests/glob-component.test.ts": 4357, - "packages/core/tests/guarded-journal.test.ts": 3730, - "packages/core/tests/has-content.test.ts": 3011, - "packages/core/tests/heal.test.ts": 2979, - "packages/core/tests/if.test.ts": 4298, - "packages/core/tests/inline-root.test.ts": 3842, - "packages/core/tests/invocation-failures.test.ts": 2212, - "packages/core/tests/invocation-identity.test.ts": 4428, - "packages/core/tests/invocation-scope.test.ts": 3149, - "packages/core/tests/journal-source-position.test.ts": 4053, - "packages/core/tests/json-component.test.ts": 3987, - "packages/core/tests/json.test.ts": 2077, - "packages/core/tests/let.test.ts": 3718, - "packages/core/tests/loaded-copy-files.test.ts": 2571, - "packages/core/tests/loop.test.ts": 4420, - "packages/core/tests/named-slots.test.ts": 4439, - "packages/core/tests/output-error-mode.test.ts": 4563, - "packages/core/tests/output-normalize.test.ts": 1590, - "packages/core/tests/output-terminal.test.ts": 1693, - "packages/core/tests/parse-components.test.ts": 3669, - "packages/core/tests/props-binding.test.ts": 3753, - "packages/core/tests/registered-printed-errors.test.ts": 2887, - "packages/core/tests/replay-stream.test.ts": 1574, - "packages/core/tests/retain.test.ts": 3030, - "packages/core/tests/root-props.test.ts": 3692, - "packages/core/tests/root-provider.test.ts": 3881, - "packages/core/tests/sample-component.test.ts": 4406, - "packages/core/tests/scanner.test.ts": 2153, - "packages/core/tests/scope-local.test.ts": 1581, - "packages/core/tests/secret-detection.test.ts": 4454, - "packages/core/tests/secret-files.test.ts": 2107, - "packages/core/tests/secret-rules.test.ts": 2139, - "packages/core/tests/secret-scanner-baseline.test.ts": 1793, - "packages/core/tests/secret-scanner.test.ts": 1970, - "packages/core/tests/source-position.test.ts": 3418, - "packages/core/tests/state-ownership.test.ts": 3530, - "packages/core/tests/streaming-emission.test.ts": 3463, - "packages/core/tests/switch.test.ts": 4151, - "packages/core/tests/syntax-catalog.test.ts": 4161, - "packages/core/tests/temp-dir.test.ts": 5930, - "packages/core/tests/temp-file-compiler.test.ts": 2194, - "packages/core/tests/text-interpolation.test.ts": 2742, - "packages/core/tests/try-content.test.ts": 2729, - "packages/core/tests/unused-in-diff.test.ts": 3481, - "packages/core/tests/validate.test.ts": 2307, - "packages/core/tests/validation-integration.test.ts": 3426, - "packages/core/tests/workflow-component-bundle.test.ts": 3799, - "packages/durable-streams/tests/context.test.ts": 1826, - "packages/durable-streams/tests/deterministic-id.test.ts": 1887, - "packages/durable-streams/tests/divergence-api.test.ts": 1848, - "packages/durable-streams/tests/divergence.test.ts": 1948, - "packages/durable-streams/tests/durable-each.test.ts": 1881, - "packages/durable-streams/tests/durable-position.test.ts": 1869, - "packages/durable-streams/tests/durable-run.test.ts": 1929, - "packages/durable-streams/tests/ephemeral.test.ts": 1870, - "packages/durable-streams/tests/fail-stop.test.ts": 1903, - "packages/durable-streams/tests/guard-stream.test.ts": 1962, - "packages/durable-streams/tests/live-coordinator.test.ts": 1913, - "packages/durable-streams/tests/parse.test.ts": 1849, - "packages/durable-streams/tests/replay-guard.test.ts": 1937, - "packages/durable-streams/tests/replay-index.test.ts": 1707, - "packages/durable-streams/tests/retained.test.ts": 1697, - "packages/durable-streams/tests/serialize-event.test.ts": 1853, - "packages/durable-streams/tests/smoke.test.ts": 1811, - "packages/durable-streams/tests/structured-concurrency.test.ts": 1977, - "packages/durable-streams/tests/terminal-boundary.test.ts": 1927, - "packages/durable-streams/tests/types.test.ts": 1533, - "packages/runtime/tests/agent-session-coordinator.test.ts": 2256, - "packages/runtime/tests/duration.test.ts": 1551, - "packages/runtime/tests/executable-observer.test.ts": 1903, - "packages/runtime/tests/fetch.test.ts": 2326, - "packages/runtime/tests/fs.test.ts": 1750, - "packages/runtime/tests/host-files.test.ts": 2615, - "packages/runtime/tests/native-launcher.test.ts": 3963, - "packages/runtime/tests/process.test.ts": 1742, - "packages/runtime/tests/service.test.ts": 1881, - "packages/test-agent/tests/acp-server.test.ts": 1717, - "packages/test-agent/tests/behavior-engine.test.ts": 4078, - "packages/test-agent/tests/bridge.test.ts": 3411, - "packages/test-agent/tests/command-lazy.test.ts": 7633, - "packages/test-agent/tests/components.test.ts": 60410, - "packages/test-agent/tests/controller.test.ts": 3027, - "packages/test-agent/tests/cross-package-resolution.test.ts": 5854, - "packages/test-agent/tests/native-launch.test.ts": 29835, - "packages/test-agent/tests/net.test.ts": 1621, - "packages/test-agent/tests/profile.test.ts": 3738, - "packages/test-agent/tests/protocol.test.ts": 2530, - "packages/test-agent/tests/provider.test.ts": 4033, - "packages/test-agent/tests/public-api.test.ts": 4704, - "packages/test-agent/tests/route-slot.test.ts": 1578, - "packages/test-agent/tests/smoke.test.ts": 20568, - "packages/test-agent/tests/template.test.ts": 3648, - "packages/test-agent/tests/worker-lifecycle.test.ts": 13116, - "packages/test-support/tests/journal.test.ts": 1890, - "packages/testing/tests/agent-composition.test.ts": 4094, - "packages/testing/tests/assert-throws.test.ts": 5342, - "packages/testing/tests/assert.test.ts": 1636, - "packages/testing/tests/assertions.test.ts": 5964, - "packages/testing/tests/boundary-contract.test.ts": 4847, - "packages/testing/tests/cli.test.ts": 7103, - "packages/testing/tests/execution-harness.test.ts": 8834, - "packages/testing/tests/replay.test.ts": 5272, - "packages/testing/tests/smoke.test.ts": 5416, - "packages/testing/tests/test-component.test.ts": 5981, - "packages/testing/tests/testing-activation.test.ts": 5452, - "packages/testing/tests/testing-boundary.test.ts": 4396, - "packages/testing/tests/testing-mode.test.ts": 6095, - "packages/testing/tests/use-testing.test.ts": 4975, - "packages/web/tests/assets.test.ts": 1645, - "packages/web/tests/client-logic.test.ts": 1674, - "packages/web/tests/compile.test.ts": 4410, - "packages/web/tests/component.test.ts": 4848, - "packages/web/tests/declaration.test.ts": 4293, - "packages/web/tests/document.test.ts": 4594, - "packages/web/tests/elicitation.test.ts": 4168, - "packages/web/tests/live-form.test.ts": 4192, - "packages/web/tests/markdown.test.ts": 1800, - "packages/web/tests/opener.test.ts": 4052, - "packages/web/tests/page.test.ts": 1665, - "packages/web/tests/responder.test.ts": 4331, - "packages/web/tests/server-lifecycle.test.ts": 4217, - "packages/web/tests/server.test.ts": 4669, - "packages/workflow/tests/ambient-authentication.test.ts": 28532, - "packages/workflow/tests/credential-helper.test.ts": 5562, - "packages/workflow/tests/generated-agent-component.test.ts": 9515, - "packages/workflow/tests/generated-observations.test.ts": 3921, - "packages/workflow/tests/git-add-crash.test.ts": 7267, - "packages/workflow/tests/git-add-durability.test.ts": 27331, - "packages/workflow/tests/git-add.test.ts": 35856, - "packages/workflow/tests/git-commit-crash.test.ts": 7505, - "packages/workflow/tests/git-commit-durability.test.ts": 35362, - "packages/workflow/tests/git-commit.test.ts": 41817, - "packages/workflow/tests/git-host-effect.test.ts": 4789, - "packages/workflow/tests/git-push-crash.test.ts": 9785, - "packages/workflow/tests/git-push-durability.test.ts": 40635, - "packages/workflow/tests/git-push.test.ts": 52753, - "packages/workflow/tests/git-switch-crash.test.ts": 7183, - "packages/workflow/tests/git-switch-durability.test.ts": 22945, - "packages/workflow/tests/git-switch.test.ts": 23225, - "packages/workflow/tests/git.test.ts": 1904, - "packages/workflow/tests/issue-github.test.ts": 3925, - "packages/workflow/tests/issue-markdown.test.ts": 11641, - "packages/workflow/tests/issue-records.test.ts": 3760, - "packages/workflow/tests/materialization.test.ts": 5269, - "packages/workflow/tests/public-entrypoint.test.ts": 6246, - "packages/workflow/tests/pull-request-crash.test.ts": 8116, - "packages/workflow/tests/pull-request-durability.test.ts": 41239, - "packages/workflow/tests/pull-request-github.test.ts": 3588, - "packages/workflow/tests/pull-request-read.test.ts": 8044, - "packages/workflow/tests/pull-request-records.test.ts": 3930, - "packages/workflow/tests/pull-request.test.ts": 73197, - "packages/workflow/tests/repository-components.test.ts": 12567, - "packages/workflow/tests/repository-control-plane.test.ts": 11141, - "packages/workflow/tests/repository-materialization.test.ts": 8054, - "packages/workflow/tests/repository-replay.test.ts": 15717, - "packages/workflow/tests/repository-storage.test.ts": 19442, - "packages/workflow/tests/retained-run.test.ts": 4528, - "packages/workflow/tests/run-composition-ambient.test.ts": 12819, - "packages/workflow/tests/run-composition-managed.test.ts": 14874, - "packages/workflow/tests/run-composition-remote.test.ts": 14647, - "packages/workflow/tests/selection-authentication.test.ts": 1872, - "packages/workflow/tests/service-denial.test.ts": 1888, - "packages/workflow/tests/workflow-agent-checkpoints.test.ts": 6318, - "packages/workflow/tests/workflow-agent-sessions.test.ts": 5441, - "packages/workflow/tests/workflow-bundle.test.ts": 4430, - "packages/workflow/tests/workflow-checkpoint.test.ts": 5971, - "packages/workflow/tests/workflow-definition.test.ts": 4089, - "packages/workflow/tests/workflow-export.test.ts": 7855, - "packages/workflow/tests/workflow-fork.test.ts": 4148, - "packages/workflow/tests/workflow-lifecycle-authority.test.ts": 6384, - "packages/workflow/tests/workflow-lifecycle-control.test.ts": 5524, - "packages/workflow/tests/workflow-lifecycle-inspection.test.ts": 11076, - "packages/workflow/tests/workflow-run-journal.test.ts": 7593, - "packages/workflow/tests/workflow-run-storage.test.ts": 8060, - "packages/workflow/tests/workflow-run.test.ts": 4535, - "packages/workflow/tests/workflow-suspension-answer.test.ts": 6337, - "packages/workflow/tests/workflow-suspension.test.ts": 6051, - "packages/workflow/tests/workspace-crash-recovery.test.ts": 8308, - "packages/workflow/tests/workspace-effect-loaded-copy.test.ts": 4604, - "packages/workflow/tests/workspace-effect-transaction.test.ts": 5999, - "packages/workflow/tests/workspace-effect.test.ts": 6722, - "packages/workflow/tests/workspace-files.test.ts": 13754, - "packages/workflow/tests/workspace-root-restoration.test.ts": 7249, - "packages/workflow/tests/workspace-root.test.ts": 5500, - "packages/workflow/tests/workspace-transaction.test.ts": 5513, - "packages/workflow/tests/worktree-replay.test.ts": 6791, - "packages/workflow/tests/xmd-artifact.test.ts": 7215, - "scripts/tests/acpx-vendor.test.ts": 2167, - "scripts/tests/adapter-distribution.test.ts": 4121, - "scripts/tests/adapter-npm-package.test.ts": 33272, - "scripts/tests/adapter-vendor.test.ts": 3688, - "scripts/tests/bootstrap-npm-package.test.ts": 10741, - "scripts/tests/build-npm.test.ts": 5536, - "scripts/tests/build-web-client.test.ts": 30217, - "scripts/tests/bump-version.test.ts": 1649, - "scripts/tests/changed-paths.test.ts": 1646, - "scripts/tests/ci-workflow.test.ts": 3408, - "scripts/tests/cli-npm-bin.test.ts": 90858, - "scripts/tests/cloudflare-dofs-vendor.test.ts": 4410, - "scripts/tests/consumer-cycle.test.ts": 1687, - "scripts/tests/filesystem-contract-workflow.test.ts": 1569, - "scripts/tests/frozen-entry.test.ts": 7698, - "scripts/tests/main-green.test.ts": 1956, - "scripts/tests/main-health.test.ts": 1756, - "scripts/tests/measure-test-weights.test.ts": 2013, - "scripts/tests/no-module-scoped-registry.test.ts": 2411, - "scripts/tests/no-redundant-test-scope.test.ts": 6484, - "scripts/tests/no-sync-filesystem.test.ts": 6480, - "scripts/tests/no-yield-in-finally.test.ts": 2436, - "scripts/tests/oxlint-policy.test.ts": 12638, - "scripts/tests/packaged-document.test.ts": 1533, - "scripts/tests/prefer-effection-operation.test.ts": 7384, - "scripts/tests/prefer-effection-result.test.ts": 5801, - "scripts/tests/prepared-state.test.ts": 2868, - "scripts/tests/publish-workflow-generator.test.ts": 6180, - "scripts/tests/publish-workflow-membership.test.ts": 1552, - "scripts/tests/readme-targets.test.ts": 19063, - "scripts/tests/release-targets.test.ts": 1648, - "scripts/tests/review-infrastructure.test.ts": 5787, - "scripts/tests/runtime-exclusions.test.ts": 2094, - "scripts/tests/runtime-tests.test.ts": 1774, - "scripts/tests/shard-execution.test.ts": 11670, - "scripts/tests/staged-write.test.ts": 1649, - "scripts/tests/test-file-discovery.test.ts": 1842, - "scripts/tests/test-shards.test.ts": 1641, - "scripts/tests/test-weights.test.ts": 1949, - "scripts/tests/tracked.test.ts": 1630, - "scripts/tests/verify-adapter.test.ts": 8052, - "scripts/tests/verify-clean.test.ts": 1837, - "scripts/tests/verify-coordinator.test.ts": 2033, - "scripts/tests/web-client-module.test.ts": 1631, - "scripts/tests/workspace.test.ts": 1607 + "packages/acp/tests/acceptance.test.ts": 5284, + "packages/acp/tests/acpx-checkpoint-meta.test.ts": 8157, + "packages/acp/tests/acpx-materialization.test.ts": 8179, + "packages/acp/tests/acpx-transient-env.test.ts": 1851, + "packages/acp/tests/adapter-materialization.test.ts": 77350, + "packages/acp/tests/adapter-protocol.test.ts": 46882, + "packages/acp/tests/native-launch.test.ts": 5040, + "packages/acp/tests/permission-bridge.test.ts": 4027, + "packages/acp/tests/provider.test.ts": 4795, + "packages/acp/tests/serial-queue.test.ts": 1568, + "packages/acp/tests/session-key.test.ts": 3848, + "packages/acp/tests/session-route.test.ts": 4110, + "packages/cli/tests/agent-adapters.test.ts": 5884, + "packages/cli/tests/agent-cli.test.ts": 23863, + "packages/cli/tests/agent-config.test.ts": 3553, + "packages/cli/tests/agent-session-coordinator.test.ts": 4293, + "packages/cli/tests/cli-help.test.ts": 15707, + "packages/cli/tests/command.test.ts": 10295, + "packages/cli/tests/compiled-upgrade.test.ts": 10653, + "packages/cli/tests/document-suites/inline/inline-markdown.test.ts": 8190, + "packages/cli/tests/document-suites/plan/plan-markdown.test.ts": 117678, + "packages/cli/tests/document-suites/props/props-markdown.test.ts": 7888, + "packages/cli/tests/document-suites/syntax/syntax-markdown.test.ts": 11750, + "packages/cli/tests/document-suites/targets/targets-markdown.test.ts": 9363, + "packages/cli/tests/document-suites/verbose/verbose-markdown.test.ts": 14986, + "packages/cli/tests/evaluate-component.test.ts": 11948, + "packages/cli/tests/evaluate-workflow.test.ts": 6180, + "packages/cli/tests/fetch-cli.test.ts": 3983, + "packages/cli/tests/file-stream.test.ts": 1802, + "packages/cli/tests/inline-cli.test.ts": 33153, + "packages/cli/tests/launch-timeout.test.ts": 11659, + "packages/cli/tests/packaged-document.test.ts": 5152, + "packages/cli/tests/plan-args.test.ts": 1586, + "packages/cli/tests/plan-cli.test.ts": 90677, + "packages/cli/tests/plan-command-document.test.ts": 10424, + "packages/cli/tests/plan-component.test.ts": 12602, + "packages/cli/tests/plan-host-acts.test.ts": 5848, + "packages/cli/tests/plan.test.ts": 18818, + "packages/cli/tests/process-retention.test.ts": 5434, + "packages/cli/tests/props-cli.test.ts": 29905, + "packages/cli/tests/props-schema.test.ts": 4162, + "packages/cli/tests/props-sources.test.ts": 2361, + "packages/cli/tests/pull-request-read-fork.test.ts": 7698, + "packages/cli/tests/run-composition-deno.test.ts": 7988, + "packages/cli/tests/run-composition-nested.test.ts": 20641, + "packages/cli/tests/run-composition.test.ts": 7226, + "packages/cli/tests/run-deadline.test.ts": 8874, + "packages/cli/tests/run-timeouts.test.ts": 13158, + "packages/cli/tests/secret-detection-cli.test.ts": 20050, + "packages/cli/tests/service-document.test.ts": 5391, + "packages/cli/tests/service-host.test.ts": 5234, + "packages/cli/tests/session-launch-cli.test.ts": 10741, + "packages/cli/tests/stdin-cli.test.ts": 35740, + "packages/cli/tests/stdout-delivery.test.ts": 1561, + "packages/cli/tests/syntax-cli.test.ts": 37082, + "packages/cli/tests/targets-cli.test.ts": 27794, + "packages/cli/tests/test-target.test.ts": 41090, + "packages/cli/tests/testing-activation.test.ts": 4588, + "packages/cli/tests/testing-execution-host.test.ts": 57814, + "packages/cli/tests/upgrade-cli.test.ts": 20347, + "packages/cli/tests/upgrade-command-document.test.ts": 7135, + "packages/cli/tests/upgrade-output.test.ts": 4414, + "packages/cli/tests/value-root.test.ts": 17523, + "packages/cli/tests/verbose-component.test.ts": 5228, + "packages/cli/tests/workflow-agent-sessions.test.ts": 20799, + "packages/cli/tests/workflow-agent.test.ts": 17695, + "packages/cli/tests/workflow-cli.test.ts": 96770, + "packages/cli/tests/workflow-crash.test.ts": 82018, + "packages/cli/tests/workflow-declaration.test.ts": 4266, + "packages/cli/tests/workflow-export-publication.test.ts": 18055, + "packages/cli/tests/workflow-fetch.test.ts": 8789, + "packages/cli/tests/workflow-fork.test.ts": 90811, + "packages/cli/tests/workflow-host.test.ts": 13877, + "packages/cli/tests/workflow-inspection.test.ts": 114944, + "packages/cli/tests/workflow-installation.test.ts": 6340, + "packages/cli/tests/workflow-lifecycle-control.test.ts": 21100, + "packages/cli/tests/workflow-retention.test.ts": 7648, + "packages/cli/tests/workflow-suspension.test.ts": 9280, + "packages/code-review-agent/tests/doctor.test.ts": 1562, + "packages/code-review-agent/tests/parse-diagnostics.test.ts": 1646, + "packages/code-review-agent/tests/parse-diff.test.ts": 1601, + "packages/code-review-agent/tests/parse-doctor.test.ts": 1712, + "packages/code-review-agent/tests/parse-oxlint.test.ts": 1594, + "packages/code-review-agent/tests/policy.test.ts": 1584, + "packages/core/tests/agent-api.test.ts": 1573, + "packages/core/tests/agent-components.test.ts": 4657, + "packages/core/tests/agent-function-components.test.ts": 5186, + "packages/core/tests/agent-session-launch.test.ts": 5718, + "packages/core/tests/agent-stack.test.ts": 4348, + "packages/core/tests/answer-identity.test.ts": 3698, + "packages/core/tests/answers-component.test.ts": 4989, + "packages/core/tests/answers-expansion-recursion.test.ts": 3935, + "packages/core/tests/capture-errors.test.ts": 4134, + "packages/core/tests/capture-props.test.ts": 3943, + "packages/core/tests/cli-journal.test.ts": 12772, + "packages/core/tests/code-block-component.test.ts": 5506, + "packages/core/tests/compiler-boundary.test.ts": 3932, + "packages/core/tests/component-api.test.ts": 3640, + "packages/core/tests/component-registration.test.ts": 4688, + "packages/core/tests/component-returns.test.ts": 5202, + "packages/core/tests/component-schema-conformance.test.ts": 4052, + "packages/core/tests/config-api.test.ts": 4158, + "packages/core/tests/construct-error-observation.test.ts": 4271, + "packages/core/tests/contextual-cwd.test.ts": 5211, + "packages/core/tests/daemon-integration.test.ts": 4676, + "packages/core/tests/daemon.test.ts": 3675, + "packages/core/tests/declared-markdown-component.test.ts": 5040, + "packages/core/tests/document-output-api.test.ts": 1599, + "packages/core/tests/document-target-execution.test.ts": 6903, + "packages/core/tests/document-targets.test.ts": 4015, + "packages/core/tests/document-validation.test.ts": 5103, + "packages/core/tests/documentation-index.test.ts": 3778, + "packages/core/tests/each.test.ts": 3989, + "packages/core/tests/elicit-component.test.ts": 4489, + "packages/core/tests/ephemeral-service.test.ts": 4501, + "packages/core/tests/eval-bindings.test.ts": 3925, + "packages/core/tests/eval-context.test.ts": 2255, + "packages/core/tests/eval-durable.test.ts": 3923, + "packages/core/tests/eval-error-mode.test.ts": 4218, + "packages/core/tests/eval-interpolate.test.ts": 1567, + "packages/core/tests/eval-middleware.test.ts": 3585, + "packages/core/tests/eval-persist.test.ts": 4058, + "packages/core/tests/eval-return.test.ts": 3920, + "packages/core/tests/eval-scope.test.ts": 3832, + "packages/core/tests/eval-timeout.test.ts": 3944, + "packages/core/tests/eval-transform.test.ts": 3571, + "packages/core/tests/evaluate-component.test.ts": 5863, + "packages/core/tests/evaluate-loaded-copy.test.ts": 3999, + "packages/core/tests/evaluate-provider-lifetime.test.ts": 4135, + "packages/core/tests/evaluation-profile.test.ts": 3834, + "packages/core/tests/exec-timeout.test.ts": 4030, + "packages/core/tests/execute.test.ts": 4522, + "packages/core/tests/execution-protocol.test.ts": 5308, + "packages/core/tests/expand.test.ts": 4333, + "packages/core/tests/expansion-identity.test.ts": 4620, + "packages/core/tests/expansion-metadata.test.ts": 3889, + "packages/core/tests/expression-props.test.ts": 4421, + "packages/core/tests/fail-component.test.ts": 4143, + "packages/core/tests/failure-printing.test.ts": 4130, + "packages/core/tests/fatal-cause.test.ts": 3787, + "packages/core/tests/fetch-component.test.ts": 5288, + "packages/core/tests/file-component.test.ts": 5932, + "packages/core/tests/file-delete-component.test.ts": 4166, + "packages/core/tests/files-fatal.test.ts": 4877, + "packages/core/tests/foreground-exec.test.ts": 5000, + "packages/core/tests/frontmatter.test.ts": 3613, + "packages/core/tests/function-components.test.ts": 4479, + "packages/core/tests/generated-composition.test.ts": 4454, + "packages/core/tests/generated-xmd.test.ts": 5983, + "packages/core/tests/glob-api.test.ts": 1979, + "packages/core/tests/glob-component.test.ts": 4670, + "packages/core/tests/guarded-journal.test.ts": 3993, + "packages/core/tests/has-content.test.ts": 3816, + "packages/core/tests/heal.test.ts": 3820, + "packages/core/tests/if.test.ts": 4470, + "packages/core/tests/inline-root.test.ts": 4076, + "packages/core/tests/invocation-failures.test.ts": 3650, + "packages/core/tests/invocation-identity.test.ts": 4405, + "packages/core/tests/invocation-scope.test.ts": 4052, + "packages/core/tests/journal-source-position.test.ts": 4189, + "packages/core/tests/json-component.test.ts": 4258, + "packages/core/tests/json.test.ts": 3602, + "packages/core/tests/let.test.ts": 3982, + "packages/core/tests/loaded-copy-files.test.ts": 3919, + "packages/core/tests/loop.test.ts": 4810, + "packages/core/tests/named-slots.test.ts": 4782, + "packages/core/tests/output-error-mode.test.ts": 4908, + "packages/core/tests/output-normalize.test.ts": 1595, + "packages/core/tests/output-terminal.test.ts": 1705, + "packages/core/tests/parse-components.test.ts": 4038, + "packages/core/tests/plan-response.test.ts": 1617, + "packages/core/tests/props-binding.test.ts": 4083, + "packages/core/tests/protected-content.test.ts": 3573, + "packages/core/tests/registered-printed-errors.test.ts": 3729, + "packages/core/tests/replay-stream.test.ts": 1565, + "packages/core/tests/retain.test.ts": 4042, + "packages/core/tests/root-props.test.ts": 4143, + "packages/core/tests/root-provider.test.ts": 4159, + "packages/core/tests/sample-component.test.ts": 4963, + "packages/core/tests/scanner.test.ts": 3681, + "packages/core/tests/scope-local.test.ts": 1562, + "packages/core/tests/secret-detection.test.ts": 4964, + "packages/core/tests/secret-files.test.ts": 2103, + "packages/core/tests/secret-rules.test.ts": 2107, + "packages/core/tests/secret-scanner-baseline.test.ts": 1724, + "packages/core/tests/secret-scanner.test.ts": 1952, + "packages/core/tests/source-position.test.ts": 3789, + "packages/core/tests/state-ownership.test.ts": 3842, + "packages/core/tests/streaming-emission.test.ts": 3818, + "packages/core/tests/switch.test.ts": 4390, + "packages/core/tests/syntax-catalog.test.ts": 4345, + "packages/core/tests/syntax-component.test.ts": 5218, + "packages/core/tests/syntax-loaded-copy.test.ts": 4043, + "packages/core/tests/temp-dir.test.ts": 6449, + "packages/core/tests/temp-file-compiler.test.ts": 2223, + "packages/core/tests/terminal-grid-structure.test.ts": 3756, + "packages/core/tests/text-interpolation.test.ts": 3759, + "packages/core/tests/try-content.test.ts": 3750, + "packages/core/tests/unused-in-diff.test.ts": 3989, + "packages/core/tests/validate.test.ts": 3698, + "packages/core/tests/validation-integration.test.ts": 3843, + "packages/core/tests/workflow-component-bundle.test.ts": 4153, + "packages/durable-streams/tests/context.test.ts": 1804, + "packages/durable-streams/tests/deterministic-id.test.ts": 1856, + "packages/durable-streams/tests/divergence-api.test.ts": 1831, + "packages/durable-streams/tests/divergence.test.ts": 1901, + "packages/durable-streams/tests/durable-each.test.ts": 1902, + "packages/durable-streams/tests/durable-position.test.ts": 1843, + "packages/durable-streams/tests/durable-run.test.ts": 1861, + "packages/durable-streams/tests/ephemeral.test.ts": 1833, + "packages/durable-streams/tests/fail-stop.test.ts": 1849, + "packages/durable-streams/tests/guard-stream.test.ts": 1913, + "packages/durable-streams/tests/live-coordinator.test.ts": 1872, + "packages/durable-streams/tests/parse.test.ts": 1859, + "packages/durable-streams/tests/replay-guard.test.ts": 1959, + "packages/durable-streams/tests/replay-index.test.ts": 1647, + "packages/durable-streams/tests/retained.test.ts": 1707, + "packages/durable-streams/tests/serialize-event.test.ts": 1890, + "packages/durable-streams/tests/smoke.test.ts": 1822, + "packages/durable-streams/tests/structured-concurrency.test.ts": 2020, + "packages/durable-streams/tests/terminal-boundary.test.ts": 1881, + "packages/durable-streams/tests/types.test.ts": 1543, + "packages/runtime/tests/agent-session-coordinator.test.ts": 2238, + "packages/runtime/tests/duration.test.ts": 1558, + "packages/runtime/tests/executable-observer.test.ts": 1936, + "packages/runtime/tests/fetch.test.ts": 2440, + "packages/runtime/tests/fs.test.ts": 1776, + "packages/runtime/tests/host-files.test.ts": 2640, + "packages/runtime/tests/native-launcher.test.ts": 4007, + "packages/runtime/tests/process.test.ts": 1789, + "packages/runtime/tests/service.test.ts": 1907, + "packages/test-agent/tests/acp-server.test.ts": 1699, + "packages/test-agent/tests/behavior-engine.test.ts": 4358, + "packages/test-agent/tests/bridge.test.ts": 3772, + "packages/test-agent/tests/command-lazy.test.ts": 8022, + "packages/test-agent/tests/components.test.ts": 61161, + "packages/test-agent/tests/controller.test.ts": 3022, + "packages/test-agent/tests/cross-package-resolution.test.ts": 6168, + "packages/test-agent/tests/native-launch.test.ts": 30671, + "packages/test-agent/tests/net.test.ts": 1673, + "packages/test-agent/tests/profile.test.ts": 3959, + "packages/test-agent/tests/protocol.test.ts": 2581, + "packages/test-agent/tests/provider.test.ts": 4325, + "packages/test-agent/tests/public-api.test.ts": 5187, + "packages/test-agent/tests/route-slot.test.ts": 1580, + "packages/test-agent/tests/smoke.test.ts": 21034, + "packages/test-agent/tests/template.test.ts": 4048, + "packages/test-agent/tests/worker-lifecycle.test.ts": 13294, + "packages/test-support/tests/journal.test.ts": 1845, + "packages/testing/tests/agent-composition.test.ts": 4328, + "packages/testing/tests/assert-throws.test.ts": 5525, + "packages/testing/tests/assert.test.ts": 1585, + "packages/testing/tests/assertions.test.ts": 6154, + "packages/testing/tests/boundary-contract.test.ts": 5112, + "packages/testing/tests/cli.test.ts": 7178, + "packages/testing/tests/execution-harness.test.ts": 8919, + "packages/testing/tests/replay.test.ts": 5468, + "packages/testing/tests/smoke.test.ts": 5639, + "packages/testing/tests/test-component.test.ts": 6120, + "packages/testing/tests/testing-activation.test.ts": 5796, + "packages/testing/tests/testing-boundary.test.ts": 4667, + "packages/testing/tests/testing-mode.test.ts": 6442, + "packages/testing/tests/use-testing.test.ts": 5298, + "packages/web/tests/assets.test.ts": 1643, + "packages/web/tests/client-logic.test.ts": 1700, + "packages/web/tests/compile.test.ts": 4732, + "packages/web/tests/component.test.ts": 5277, + "packages/web/tests/declaration.test.ts": 4430, + "packages/web/tests/document.test.ts": 4682, + "packages/web/tests/elicitation.test.ts": 4341, + "packages/web/tests/live-form.test.ts": 4294, + "packages/web/tests/markdown.test.ts": 1793, + "packages/web/tests/opener.test.ts": 4309, + "packages/web/tests/page.test.ts": 1625, + "packages/web/tests/responder.test.ts": 4558, + "packages/web/tests/server-lifecycle.test.ts": 4450, + "packages/web/tests/server.test.ts": 4767, + "packages/workflow/tests/ambient-authentication.test.ts": 27268, + "packages/workflow/tests/credential-helper.test.ts": 5686, + "packages/workflow/tests/generated-agent-component.test.ts": 9729, + "packages/workflow/tests/generated-observations.test.ts": 4129, + "packages/workflow/tests/git-add-crash.test.ts": 7401, + "packages/workflow/tests/git-add-durability.test.ts": 26908, + "packages/workflow/tests/git-add.test.ts": 36233, + "packages/workflow/tests/git-commit-crash.test.ts": 7714, + "packages/workflow/tests/git-commit-durability.test.ts": 35424, + "packages/workflow/tests/git-commit.test.ts": 42345, + "packages/workflow/tests/git-host-effect.test.ts": 5176, + "packages/workflow/tests/git-push-crash.test.ts": 10630, + "packages/workflow/tests/git-push-durability.test.ts": 43607, + "packages/workflow/tests/git-push.test.ts": 53362, + "packages/workflow/tests/git-switch-crash.test.ts": 7308, + "packages/workflow/tests/git-switch-durability.test.ts": 22701, + "packages/workflow/tests/git-switch.test.ts": 24683, + "packages/workflow/tests/git.test.ts": 1928, + "packages/workflow/tests/issue-github.test.ts": 4314, + "packages/workflow/tests/issue-markdown.test.ts": 11688, + "packages/workflow/tests/issue-records.test.ts": 4026, + "packages/workflow/tests/materialization.test.ts": 5747, + "packages/workflow/tests/public-entrypoint.test.ts": 6990, + "packages/workflow/tests/pull-request-crash.test.ts": 9215, + "packages/workflow/tests/pull-request-durability.test.ts": 48666, + "packages/workflow/tests/pull-request-github.test.ts": 4168, + "packages/workflow/tests/pull-request-read.test.ts": 8330, + "packages/workflow/tests/pull-request-records.test.ts": 4163, + "packages/workflow/tests/pull-request.test.ts": 75205, + "packages/workflow/tests/repository-components.test.ts": 13308, + "packages/workflow/tests/repository-control-plane.test.ts": 11944, + "packages/workflow/tests/repository-materialization.test.ts": 8655, + "packages/workflow/tests/repository-replay.test.ts": 16215, + "packages/workflow/tests/repository-storage.test.ts": 19455, + "packages/workflow/tests/retained-run.test.ts": 4793, + "packages/workflow/tests/run-composition-ambient.test.ts": 12903, + "packages/workflow/tests/run-composition-managed.test.ts": 15191, + "packages/workflow/tests/run-composition-remote.test.ts": 14670, + "packages/workflow/tests/selection-authentication.test.ts": 1824, + "packages/workflow/tests/service-denial.test.ts": 1869, + "packages/workflow/tests/workflow-agent-checkpoints.test.ts": 6585, + "packages/workflow/tests/workflow-agent-sessions.test.ts": 5447, + "packages/workflow/tests/workflow-bundle.test.ts": 4590, + "packages/workflow/tests/workflow-checkpoint.test.ts": 6096, + "packages/workflow/tests/workflow-definition.test.ts": 4317, + "packages/workflow/tests/workflow-export.test.ts": 7932, + "packages/workflow/tests/workflow-fork.test.ts": 4298, + "packages/workflow/tests/workflow-lifecycle-authority.test.ts": 6430, + "packages/workflow/tests/workflow-lifecycle-control.test.ts": 5658, + "packages/workflow/tests/workflow-lifecycle-inspection.test.ts": 11174, + "packages/workflow/tests/workflow-run-journal.test.ts": 7803, + "packages/workflow/tests/workflow-run-storage.test.ts": 8223, + "packages/workflow/tests/workflow-run.test.ts": 4655, + "packages/workflow/tests/workflow-suspension-answer.test.ts": 6529, + "packages/workflow/tests/workflow-suspension.test.ts": 6030, + "packages/workflow/tests/workspace-crash-recovery.test.ts": 8406, + "packages/workflow/tests/workspace-effect-loaded-copy.test.ts": 4675, + "packages/workflow/tests/workspace-effect-transaction.test.ts": 6131, + "packages/workflow/tests/workspace-effect.test.ts": 6881, + "packages/workflow/tests/workspace-files.test.ts": 13225, + "packages/workflow/tests/workspace-root-restoration.test.ts": 7259, + "packages/workflow/tests/workspace-root.test.ts": 5556, + "packages/workflow/tests/workspace-transaction.test.ts": 5580, + "packages/workflow/tests/worktree-replay.test.ts": 6891, + "packages/workflow/tests/xmd-artifact.test.ts": 7282, + "scripts/tests/acpx-vendor.test.ts": 2145, + "scripts/tests/adapter-distribution.test.ts": 4456, + "scripts/tests/adapter-npm-package.test.ts": 32561, + "scripts/tests/adapter-vendor.test.ts": 4005, + "scripts/tests/bootstrap-npm-package.test.ts": 11117, + "scripts/tests/build-npm.test.ts": 7676, + "scripts/tests/build-web-client.test.ts": 30330, + "scripts/tests/bump-version.test.ts": 1695, + "scripts/tests/changed-paths.test.ts": 1610, + "scripts/tests/ci-workflow.test.ts": 3344, + "scripts/tests/cli-npm-bin.test.ts": 150877, + "scripts/tests/cloudflare-dofs-vendor.test.ts": 4399, + "scripts/tests/consumer-cycle.test.ts": 1664, + "scripts/tests/documentation-validation.test.ts": 5904, + "scripts/tests/filesystem-contract-workflow.test.ts": 1567, + "scripts/tests/frozen-entry.test.ts": 8436, + "scripts/tests/jsr-consumer-documentation.test.ts": 17639, + "scripts/tests/main-green.test.ts": 1943, + "scripts/tests/main-health.test.ts": 1700, + "scripts/tests/measure-test-weights.test.ts": 2016, + "scripts/tests/no-module-scoped-registry.test.ts": 2388, + "scripts/tests/no-redundant-test-scope.test.ts": 6548, + "scripts/tests/no-sync-filesystem.test.ts": 6411, + "scripts/tests/no-yield-in-finally.test.ts": 2415, + "scripts/tests/oxlint-policy.test.ts": 12343, + "scripts/tests/packaged-document.test.ts": 1586, + "scripts/tests/prefer-effection-operation.test.ts": 7361, + "scripts/tests/prefer-effection-result.test.ts": 5705, + "scripts/tests/prepared-state.test.ts": 2845, + "scripts/tests/publish-workflow-generator.test.ts": 6247, + "scripts/tests/publish-workflow-membership.test.ts": 1604, + "scripts/tests/readme-targets.test.ts": 19289, + "scripts/tests/release-targets.test.ts": 1673, + "scripts/tests/review-infrastructure.test.ts": 6112, + "scripts/tests/runtime-exclusions.test.ts": 2113, + "scripts/tests/runtime-tests.test.ts": 1733, + "scripts/tests/scope-bound-event-registration.test.ts": 6435, + "scripts/tests/session-rendering.test.ts": 15713, + "scripts/tests/shard-execution.test.ts": 11483, + "scripts/tests/staged-write.test.ts": 1587, + "scripts/tests/test-file-discovery.test.ts": 1804, + "scripts/tests/test-shards.test.ts": 1618, + "scripts/tests/test-weights.test.ts": 1910, + "scripts/tests/tracked.test.ts": 1577, + "scripts/tests/verify-adapter.test.ts": 7958, + "scripts/tests/verify-clean.test.ts": 1825, + "scripts/tests/verify-coordinator.test.ts": 1918, + "scripts/tests/web-client-module.test.ts": 1579, + "scripts/tests/workspace.test.ts": 1569 }, "node": { - "packages/acp/tests/acceptance.test.ts": 2110, - "packages/acp/tests/acpx-checkpoint-meta.test.ts": 4910, - "packages/acp/tests/acpx-materialization.test.ts": 7162, - "packages/acp/tests/acpx-transient-env.test.ts": 873, - "packages/acp/tests/adapter-materialization.test.ts": 75221, - "packages/acp/tests/adapter-protocol.test.ts": 38157, - "packages/acp/tests/native-launch.test.ts": 2018, - "packages/acp/tests/permission-bridge.test.ts": 1215, - "packages/acp/tests/provider.test.ts": 1747, - "packages/acp/tests/serial-queue.test.ts": 516, - "packages/acp/tests/session-key.test.ts": 547, - "packages/cli/tests/agent-adapters.test.ts": 2910, - "packages/cli/tests/agent-cli.test.ts": 26388, - "packages/cli/tests/agent-config.test.ts": 485, - "packages/cli/tests/agent-session-coordinator.test.ts": 1329, - "packages/cli/tests/cli-help.test.ts": 28686, - "packages/cli/tests/command.test.ts": 14928, - "packages/cli/tests/document-suites/inline/inline-markdown.test.ts": 3749, - "packages/cli/tests/document-suites/props/props-markdown.test.ts": 3266, - "packages/cli/tests/document-suites/syntax/syntax-markdown.test.ts": 9851, - "packages/cli/tests/document-suites/targets/targets-markdown.test.ts": 5047, - "packages/cli/tests/document-suites/verbose/verbose-markdown.test.ts": 17677, - "packages/cli/tests/fetch-cli.test.ts": 4738, - "packages/cli/tests/file-stream.test.ts": 541, - "packages/cli/tests/inline-cli.test.ts": 59512, - "packages/cli/tests/launch-timeout.test.ts": 20558, - "packages/cli/tests/packaged-document.test.ts": 1683, - "packages/cli/tests/plan-args.test.ts": 652, - "packages/cli/tests/plan-cli.test.ts": 48057, - "packages/cli/tests/plan-command-document.test.ts": 2152, - "packages/cli/tests/plan-component.test.ts": 5086, - "packages/cli/tests/plan-host-acts.test.ts": 2634, - "packages/cli/tests/plan.test.ts": 23344, - "packages/cli/tests/process-retention.test.ts": 4686, - "packages/cli/tests/props-cli.test.ts": 60160, - "packages/cli/tests/props-schema.test.ts": 1315, - "packages/cli/tests/props-sources.test.ts": 684, - "packages/cli/tests/run-composition.test.ts": 4213, - "packages/cli/tests/run-deadline.test.ts": 3800, - "packages/cli/tests/run-timeouts.test.ts": 19440, - "packages/cli/tests/secret-detection-cli.test.ts": 36835, - "packages/cli/tests/service-document.test.ts": 2570, - "packages/cli/tests/service-host.test.ts": 2346, - "packages/cli/tests/session-launch-cli.test.ts": 10714, - "packages/cli/tests/stdout-delivery.test.ts": 500, - "packages/cli/tests/syntax-cli.test.ts": 32184, - "packages/cli/tests/targets-cli.test.ts": 49189, - "packages/cli/tests/test-target.test.ts": 76268, - "packages/cli/tests/testing-activation.test.ts": 1478, - "packages/cli/tests/testing-execution-host.test.ts": 54491, - "packages/cli/tests/upgrade-cli.test.ts": 43799, - "packages/cli/tests/upgrade-command-document.test.ts": 5273, - "packages/cli/tests/upgrade-output.test.ts": 1813, - "packages/cli/tests/value-root.test.ts": 30041, - "packages/cli/tests/verbose-component.test.ts": 2031, - "packages/cli/tests/workflow-declaration.test.ts": 1253, - "packages/cli/tests/workflow-host.test.ts": 10928, - "packages/code-review-agent/tests/doctor.test.ts": 481, - "packages/code-review-agent/tests/parse-diagnostics.test.ts": 519, - "packages/code-review-agent/tests/parse-diff.test.ts": 505, - "packages/code-review-agent/tests/parse-doctor.test.ts": 489, - "packages/code-review-agent/tests/parse-oxlint.test.ts": 481, - "packages/code-review-agent/tests/policy.test.ts": 490, - "packages/core/tests/agent-api.test.ts": 518, - "packages/core/tests/agent-components.test.ts": 1951, - "packages/core/tests/agent-function-components.test.ts": 2637, - "packages/core/tests/agent-session-launch.test.ts": 2999, - "packages/core/tests/agent-stack.test.ts": 1499, - "packages/core/tests/answers-component.test.ts": 2311, - "packages/core/tests/answers-expansion-recursion.test.ts": 952, - "packages/core/tests/capture-errors.test.ts": 1234, - "packages/core/tests/capture-props.test.ts": 960, - "packages/core/tests/cli-journal.test.ts": 21029, - "packages/core/tests/code-block-component.test.ts": 2963, - "packages/core/tests/compiler-boundary.test.ts": 1120, - "packages/core/tests/component-api.test.ts": 555, - "packages/core/tests/component-registration.test.ts": 2005, - "packages/core/tests/component-returns.test.ts": 2676, - "packages/core/tests/component-schema-conformance.test.ts": 1106, - "packages/core/tests/config-api.test.ts": 1227, - "packages/core/tests/construct-error-observation.test.ts": 1336, - "packages/core/tests/contextual-cwd.test.ts": 2442, - "packages/core/tests/daemon-integration.test.ts": 1837, - "packages/core/tests/daemon.test.ts": 579, - "packages/core/tests/declared-markdown-component.test.ts": 2132, - "packages/core/tests/document-output-api.test.ts": 527, - "packages/core/tests/document-target-execution.test.ts": 4414, - "packages/core/tests/document-targets.test.ts": 1134, - "packages/core/tests/document-validation.test.ts": 2361, - "packages/core/tests/each.test.ts": 1227, - "packages/core/tests/elicit-component.test.ts": 1813, - "packages/core/tests/ephemeral-service.test.ts": 1779, - "packages/core/tests/eval-bindings.test.ts": 1204, - "packages/core/tests/eval-context.test.ts": 612, - "packages/core/tests/eval-durable.test.ts": 1286, - "packages/core/tests/eval-error-mode.test.ts": 1657, - "packages/core/tests/eval-interpolate.test.ts": 526, - "packages/core/tests/eval-middleware.test.ts": 598, - "packages/core/tests/eval-persist.test.ts": 1372, - "packages/core/tests/eval-return.test.ts": 1249, - "packages/core/tests/eval-scope.test.ts": 1146, - "packages/core/tests/eval-timeout.test.ts": 1256, - "packages/core/tests/eval-transform.test.ts": 590, - "packages/core/tests/exec-timeout.test.ts": 1278, - "packages/core/tests/execute.test.ts": 1923, - "packages/core/tests/execution-protocol.test.ts": 2629, - "packages/core/tests/expand.test.ts": 1566, - "packages/core/tests/expansion-identity.test.ts": 2024, - "packages/core/tests/expansion-metadata.test.ts": 1014, - "packages/core/tests/expression-props.test.ts": 1905, - "packages/core/tests/fail-component.test.ts": 1654, - "packages/core/tests/failure-printing.test.ts": 1477, - "packages/core/tests/fatal-cause.test.ts": 875, - "packages/core/tests/fetch-component.test.ts": 3013, - "packages/core/tests/file-component.test.ts": 3444, - "packages/core/tests/file-delete-component.test.ts": 1485, - "packages/core/tests/files-fatal.test.ts": 2434, - "packages/core/tests/foreground-exec.test.ts": 2300, - "packages/core/tests/frontmatter.test.ts": 579, - "packages/core/tests/function-components.test.ts": 2056, - "packages/core/tests/generated-xmd.test.ts": 2603, - "packages/core/tests/glob-api.test.ts": 595, - "packages/core/tests/glob-component.test.ts": 2093, - "packages/core/tests/guarded-journal.test.ts": 1339, - "packages/core/tests/has-content.test.ts": 927, - "packages/core/tests/heal.test.ts": 930, - "packages/core/tests/if.test.ts": 1911, - "packages/core/tests/inline-root.test.ts": 1354, - "packages/core/tests/invocation-failures.test.ts": 631, - "packages/core/tests/invocation-identity.test.ts": 1808, - "packages/core/tests/invocation-scope.test.ts": 1257, - "packages/core/tests/journal-source-position.test.ts": 1451, - "packages/core/tests/json-component.test.ts": 1557, - "packages/core/tests/json.test.ts": 517, - "packages/core/tests/let.test.ts": 1326, + "packages/acp/tests/acceptance.test.ts": 2186, + "packages/acp/tests/acpx-checkpoint-meta.test.ts": 4887, + "packages/acp/tests/acpx-materialization.test.ts": 7113, + "packages/acp/tests/acpx-transient-env.test.ts": 838, + "packages/acp/tests/adapter-materialization.test.ts": 74016, + "packages/acp/tests/adapter-protocol.test.ts": 42641, + "packages/acp/tests/native-launch.test.ts": 2039, + "packages/acp/tests/permission-bridge.test.ts": 1226, + "packages/acp/tests/provider.test.ts": 1764, + "packages/acp/tests/serial-queue.test.ts": 498, + "packages/acp/tests/session-key.test.ts": 527, + "packages/cli/tests/agent-adapters.test.ts": 2824, + "packages/cli/tests/agent-cli.test.ts": 26778, + "packages/cli/tests/agent-config.test.ts": 481, + "packages/cli/tests/agent-session-coordinator.test.ts": 1346, + "packages/cli/tests/cli-help.test.ts": 30156, + "packages/cli/tests/command.test.ts": 14660, + "packages/cli/tests/document-suites/inline/inline-markdown.test.ts": 3685, + "packages/cli/tests/document-suites/plan/plan-markdown.test.ts": 170363, + "packages/cli/tests/document-suites/props/props-markdown.test.ts": 3345, + "packages/cli/tests/document-suites/syntax/syntax-markdown.test.ts": 9999, + "packages/cli/tests/document-suites/targets/targets-markdown.test.ts": 5402, + "packages/cli/tests/document-suites/verbose/verbose-markdown.test.ts": 18656, + "packages/cli/tests/evaluate-component.test.ts": 15997, + "packages/cli/tests/fetch-cli.test.ts": 5021, + "packages/cli/tests/file-stream.test.ts": 557, + "packages/cli/tests/inline-cli.test.ts": 66722, + "packages/cli/tests/launch-timeout.test.ts": 20535, + "packages/cli/tests/packaged-document.test.ts": 1649, + "packages/cli/tests/plan-args.test.ts": 514, + "packages/cli/tests/plan-cli.test.ts": 108778, + "packages/cli/tests/plan-command-document.test.ts": 8152, + "packages/cli/tests/plan-component.test.ts": 11282, + "packages/cli/tests/plan-host-acts.test.ts": 2563, + "packages/cli/tests/plan.test.ts": 18700, + "packages/cli/tests/process-retention.test.ts": 4844, + "packages/cli/tests/props-cli.test.ts": 63394, + "packages/cli/tests/props-schema.test.ts": 1338, + "packages/cli/tests/props-sources.test.ts": 702, + "packages/cli/tests/run-composition.test.ts": 4361, + "packages/cli/tests/run-deadline.test.ts": 3889, + "packages/cli/tests/run-timeouts.test.ts": 20086, + "packages/cli/tests/secret-detection-cli.test.ts": 38318, + "packages/cli/tests/service-document.test.ts": 2685, + "packages/cli/tests/service-host.test.ts": 2425, + "packages/cli/tests/session-launch-cli.test.ts": 11008, + "packages/cli/tests/stdin-cli.test.ts": 61265, + "packages/cli/tests/stdout-delivery.test.ts": 518, + "packages/cli/tests/syntax-cli.test.ts": 64419, + "packages/cli/tests/targets-cli.test.ts": 49866, + "packages/cli/tests/test-target.test.ts": 80161, + "packages/cli/tests/testing-activation.test.ts": 1540, + "packages/cli/tests/testing-execution-host.test.ts": 92870, + "packages/cli/tests/upgrade-cli.test.ts": 47315, + "packages/cli/tests/upgrade-command-document.test.ts": 6154, + "packages/cli/tests/upgrade-output.test.ts": 1977, + "packages/cli/tests/value-root.test.ts": 31848, + "packages/cli/tests/verbose-component.test.ts": 2168, + "packages/cli/tests/workflow-declaration.test.ts": 1274, + "packages/cli/tests/workflow-host.test.ts": 11502, + "packages/code-review-agent/tests/doctor.test.ts": 508, + "packages/code-review-agent/tests/parse-diagnostics.test.ts": 534, + "packages/code-review-agent/tests/parse-diff.test.ts": 514, + "packages/code-review-agent/tests/parse-doctor.test.ts": 506, + "packages/code-review-agent/tests/parse-oxlint.test.ts": 485, + "packages/code-review-agent/tests/policy.test.ts": 524, + "packages/core/tests/agent-api.test.ts": 504, + "packages/core/tests/agent-components.test.ts": 2007, + "packages/core/tests/agent-function-components.test.ts": 2740, + "packages/core/tests/agent-session-launch.test.ts": 3130, + "packages/core/tests/agent-stack.test.ts": 1583, + "packages/core/tests/answer-identity.test.ts": 543, + "packages/core/tests/answers-component.test.ts": 2521, + "packages/core/tests/answers-expansion-recursion.test.ts": 992, + "packages/core/tests/capture-errors.test.ts": 1293, + "packages/core/tests/capture-props.test.ts": 1024, + "packages/core/tests/cli-journal.test.ts": 21883, + "packages/core/tests/code-block-component.test.ts": 3206, + "packages/core/tests/compiler-boundary.test.ts": 1219, + "packages/core/tests/component-api.test.ts": 571, + "packages/core/tests/component-registration.test.ts": 2062, + "packages/core/tests/component-returns.test.ts": 2982, + "packages/core/tests/component-schema-conformance.test.ts": 1163, + "packages/core/tests/config-api.test.ts": 1334, + "packages/core/tests/construct-error-observation.test.ts": 1433, + "packages/core/tests/contextual-cwd.test.ts": 2477, + "packages/core/tests/daemon-integration.test.ts": 1930, + "packages/core/tests/daemon.test.ts": 578, + "packages/core/tests/declared-markdown-component.test.ts": 2606, + "packages/core/tests/document-output-api.test.ts": 532, + "packages/core/tests/document-target-execution.test.ts": 4919, + "packages/core/tests/document-targets.test.ts": 1231, + "packages/core/tests/document-validation.test.ts": 2706, + "packages/core/tests/documentation-index.test.ts": 848, + "packages/core/tests/each.test.ts": 1323, + "packages/core/tests/elicit-component.test.ts": 1885, + "packages/core/tests/ephemeral-service.test.ts": 1883, + "packages/core/tests/eval-bindings.test.ts": 1254, + "packages/core/tests/eval-context.test.ts": 609, + "packages/core/tests/eval-durable.test.ts": 1323, + "packages/core/tests/eval-error-mode.test.ts": 1737, + "packages/core/tests/eval-interpolate.test.ts": 532, + "packages/core/tests/eval-middleware.test.ts": 604, + "packages/core/tests/eval-persist.test.ts": 1413, + "packages/core/tests/eval-return.test.ts": 1306, + "packages/core/tests/eval-scope.test.ts": 1197, + "packages/core/tests/eval-timeout.test.ts": 1274, + "packages/core/tests/eval-transform.test.ts": 603, + "packages/core/tests/evaluate-component.test.ts": 3750, + "packages/core/tests/evaluate-loaded-copy.test.ts": 1366, + "packages/core/tests/evaluate-provider-lifetime.test.ts": 1448, + "packages/core/tests/evaluation-profile.test.ts": 911, + "packages/core/tests/exec-timeout.test.ts": 1352, + "packages/core/tests/execute.test.ts": 2020, + "packages/core/tests/execution-protocol.test.ts": 2819, + "packages/core/tests/expand.test.ts": 1629, + "packages/core/tests/expansion-identity.test.ts": 2046, + "packages/core/tests/expansion-metadata.test.ts": 1058, + "packages/core/tests/expression-props.test.ts": 1959, + "packages/core/tests/fail-component.test.ts": 1693, + "packages/core/tests/failure-printing.test.ts": 1525, + "packages/core/tests/fatal-cause.test.ts": 913, + "packages/core/tests/fetch-component.test.ts": 3088, + "packages/core/tests/file-component.test.ts": 3407, + "packages/core/tests/file-delete-component.test.ts": 1521, + "packages/core/tests/files-fatal.test.ts": 2483, + "packages/core/tests/foreground-exec.test.ts": 2345, + "packages/core/tests/frontmatter.test.ts": 551, + "packages/core/tests/function-components.test.ts": 2057, + "packages/core/tests/generated-composition.test.ts": 2114, + "packages/core/tests/generated-xmd.test.ts": 3635, + "packages/core/tests/glob-api.test.ts": 603, + "packages/core/tests/glob-component.test.ts": 2111, + "packages/core/tests/guarded-journal.test.ts": 1374, + "packages/core/tests/has-content.test.ts": 957, + "packages/core/tests/heal.test.ts": 950, + "packages/core/tests/if.test.ts": 1877, + "packages/core/tests/inline-root.test.ts": 1359, + "packages/core/tests/invocation-failures.test.ts": 600, + "packages/core/tests/invocation-identity.test.ts": 1787, + "packages/core/tests/invocation-scope.test.ts": 1239, + "packages/core/tests/journal-source-position.test.ts": 1492, + "packages/core/tests/json-component.test.ts": 1570, + "packages/core/tests/json.test.ts": 512, + "packages/core/tests/let.test.ts": 1317, "packages/core/tests/loop.test.ts": 2373, - "packages/core/tests/named-slots.test.ts": 2468, - "packages/core/tests/output-error-mode.test.ts": 2544, - "packages/core/tests/output-normalize.test.ts": 535, - "packages/core/tests/output-terminal.test.ts": 680, - "packages/core/tests/parse-components.test.ts": 1413, - "packages/core/tests/props-binding.test.ts": 1401, - "packages/core/tests/registered-printed-errors.test.ts": 847, - "packages/core/tests/replay-stream.test.ts": 509, - "packages/core/tests/retain.test.ts": 1150, - "packages/core/tests/root-props.test.ts": 1405, - "packages/core/tests/root-provider.test.ts": 1311, - "packages/core/tests/sample-component.test.ts": 2389, - "packages/core/tests/scanner.test.ts": 610, - "packages/core/tests/scope-local.test.ts": 511, - "packages/core/tests/secret-detection.test.ts": 2067, - "packages/core/tests/secret-files.test.ts": 745, - "packages/core/tests/secret-rules.test.ts": 854, - "packages/core/tests/secret-scanner-baseline.test.ts": 743, - "packages/core/tests/secret-scanner.test.ts": 725, - "packages/core/tests/source-position.test.ts": 1088, - "packages/core/tests/state-ownership.test.ts": 1146, - "packages/core/tests/streaming-emission.test.ts": 1136, - "packages/core/tests/switch.test.ts": 1880, - "packages/core/tests/syntax-catalog.test.ts": 1700, - "packages/core/tests/temp-dir.test.ts": 3702, - "packages/core/tests/temp-file-compiler.test.ts": 545, - "packages/core/tests/text-interpolation.test.ts": 883, - "packages/core/tests/try-content.test.ts": 893, - "packages/core/tests/unused-in-diff.test.ts": 1373, - "packages/core/tests/validate.test.ts": 815, - "packages/core/tests/validation-integration.test.ts": 1131, - "packages/core/tests/workflow-component-bundle.test.ts": 1509, - "packages/durable-streams/tests/context.test.ts": 523, - "packages/durable-streams/tests/deterministic-id.test.ts": 562, - "packages/durable-streams/tests/divergence-api.test.ts": 549, - "packages/durable-streams/tests/divergence.test.ts": 559, - "packages/durable-streams/tests/durable-each.test.ts": 575, - "packages/durable-streams/tests/durable-position.test.ts": 547, - "packages/durable-streams/tests/durable-run.test.ts": 565, - "packages/durable-streams/tests/ephemeral.test.ts": 544, - "packages/durable-streams/tests/fail-stop.test.ts": 606, - "packages/durable-streams/tests/guard-stream.test.ts": 619, - "packages/durable-streams/tests/live-coordinator.test.ts": 564, - "packages/durable-streams/tests/parse.test.ts": 589, - "packages/durable-streams/tests/replay-guard.test.ts": 585, - "packages/durable-streams/tests/replay-index.test.ts": 561, - "packages/durable-streams/tests/retained.test.ts": 530, - "packages/durable-streams/tests/serialize-event.test.ts": 529, - "packages/durable-streams/tests/smoke.test.ts": 531, - "packages/durable-streams/tests/structured-concurrency.test.ts": 595, - "packages/durable-streams/tests/terminal-boundary.test.ts": 575, - "packages/durable-streams/tests/types.test.ts": 502, - "packages/runtime/tests/duration.test.ts": 498, - "packages/runtime/tests/fetch.test.ts": 1110, - "packages/runtime/tests/fs.test.ts": 549, - "packages/runtime/tests/host-files.test.ts": 1285, - "packages/runtime/tests/native-launcher.test.ts": 2858, - "packages/runtime/tests/process.test.ts": 549, - "packages/runtime/tests/service.test.ts": 524, - "packages/test-agent/tests/acp-server.test.ts": 721, - "packages/test-agent/tests/behavior-engine.test.ts": 1536, - "packages/test-agent/tests/bridge.test.ts": 525, - "packages/test-agent/tests/command-lazy.test.ts": 6427, - "packages/test-agent/tests/components.test.ts": 103438, - "packages/test-agent/tests/controller.test.ts": 798, - "packages/test-agent/tests/cross-package-resolution.test.ts": 3040, - "packages/test-agent/tests/native-launch.test.ts": 52218, - "packages/test-agent/tests/net.test.ts": 589, - "packages/test-agent/tests/profile.test.ts": 1162, - "packages/test-agent/tests/protocol.test.ts": 582, - "packages/test-agent/tests/provider.test.ts": 1331, - "packages/test-agent/tests/public-api.test.ts": 1527, - "packages/test-agent/tests/route-slot.test.ts": 515, - "packages/test-agent/tests/smoke.test.ts": 27717, - "packages/test-agent/tests/template.test.ts": 1162, - "packages/test-agent/tests/worker-lifecycle.test.ts": 22495, - "packages/test-support/tests/journal.test.ts": 488, - "packages/testing/tests/agent-composition.test.ts": 1454, - "packages/testing/tests/assert-throws.test.ts": 3055, - "packages/testing/tests/assert.test.ts": 521, - "packages/testing/tests/assertions.test.ts": 3770, - "packages/testing/tests/boundary-contract.test.ts": 2498, - "packages/testing/tests/cli.test.ts": 11015, - "packages/testing/tests/execution-harness.test.ts": 7363, - "packages/testing/tests/replay.test.ts": 3046, - "packages/testing/tests/smoke.test.ts": 3167, - "packages/testing/tests/test-component.test.ts": 3835, - "packages/testing/tests/testing-activation.test.ts": 3363, - "packages/testing/tests/testing-boundary.test.ts": 1985, - "packages/testing/tests/testing-mode.test.ts": 4044, - "packages/testing/tests/use-testing.test.ts": 2691, - "packages/web/tests/assets.test.ts": 517, - "packages/web/tests/client-logic.test.ts": 548, - "packages/web/tests/compile.test.ts": 1937, - "packages/web/tests/component.test.ts": 2426, - "packages/web/tests/declaration.test.ts": 1639, - "packages/web/tests/document.test.ts": 1771, - "packages/web/tests/elicitation.test.ts": 1563, - "packages/web/tests/live-form.test.ts": 1454, - "packages/web/tests/markdown.test.ts": 702, - "packages/web/tests/opener.test.ts": 1460, - "packages/web/tests/page.test.ts": 494, - "packages/web/tests/responder.test.ts": 1779, - "packages/web/tests/server-lifecycle.test.ts": 1544, - "packages/web/tests/server.test.ts": 2000, - "packages/workflow/tests/generated-observations.test.ts": 1388, - "packages/workflow/tests/git-host-effect.test.ts": 2443, - "packages/workflow/tests/git.test.ts": 524, - "packages/workflow/tests/issue-github.test.ts": 1197, - "packages/workflow/tests/issue-markdown.test.ts": 9804, - "packages/workflow/tests/issue-records.test.ts": 1169, - "packages/workflow/tests/pull-request-github.test.ts": 604, - "packages/workflow/tests/pull-request-records.test.ts": 1205, - "packages/workflow/tests/retained-run.test.ts": 2115, - "packages/workflow/tests/selection-authentication.test.ts": 489, - "packages/workflow/tests/service-denial.test.ts": 526, - "packages/workflow/tests/workflow-bundle.test.ts": 1639, - "packages/workflow/tests/workflow-definition.test.ts": 1246, - "packages/workflow/tests/workflow-fork.test.ts": 1235, - "packages/workflow/tests/workflow-run.test.ts": 1909, - "packages/workflow/tests/workspace-effect.test.ts": 3228, - "packages/workflow/tests/xmd-artifact.test.ts": 3708, - "scripts/tests/adapter-vendor.test.ts": 732, - "scripts/tests/bootstrap-npm-package.test.ts": 8010, - "scripts/tests/bump-version.test.ts": 602, - "scripts/tests/changed-paths.test.ts": 538, - "scripts/tests/ci-workflow.test.ts": 2100, - "scripts/tests/consumer-cycle.test.ts": 676, - "scripts/tests/filesystem-contract-workflow.test.ts": 581, - "scripts/tests/main-green.test.ts": 797, - "scripts/tests/main-health.test.ts": 618, - "scripts/tests/no-module-scoped-registry.test.ts": 1323, - "scripts/tests/no-redundant-test-scope.test.ts": 5347, - "scripts/tests/no-sync-filesystem.test.ts": 5517, - "scripts/tests/no-yield-in-finally.test.ts": 1355, - "scripts/tests/oxlint-policy.test.ts": 10991, - "scripts/tests/packaged-document.test.ts": 492, - "scripts/tests/prefer-effection-operation.test.ts": 6084, - "scripts/tests/prefer-effection-result.test.ts": 4590, - "scripts/tests/publish-workflow-membership.test.ts": 552, - "scripts/tests/review-infrastructure.test.ts": 3229, - "scripts/tests/runtime-exclusions.test.ts": 992, - "scripts/tests/runtime-tests.test.ts": 550, - "scripts/tests/staged-write.test.ts": 544, - "scripts/tests/test-file-discovery.test.ts": 804, - "scripts/tests/test-shards.test.ts": 585, - "scripts/tests/test-weights.test.ts": 706, - "scripts/tests/tracked.test.ts": 511, - "scripts/tests/verify-coordinator.test.ts": 731, - "scripts/tests/web-client-module.test.ts": 544, - "scripts/tests/workspace.test.ts": 509 + "packages/core/tests/named-slots.test.ts": 2380, + "packages/core/tests/output-error-mode.test.ts": 2731, + "packages/core/tests/output-normalize.test.ts": 518, + "packages/core/tests/output-terminal.test.ts": 710, + "packages/core/tests/parse-components.test.ts": 1495, + "packages/core/tests/plan-response.test.ts": 627, + "packages/core/tests/props-binding.test.ts": 1528, + "packages/core/tests/protected-content.test.ts": 568, + "packages/core/tests/registered-printed-errors.test.ts": 910, + "packages/core/tests/replay-stream.test.ts": 519, + "packages/core/tests/retain.test.ts": 1215, + "packages/core/tests/root-props.test.ts": 1509, + "packages/core/tests/root-provider.test.ts": 1392, + "packages/core/tests/sample-component.test.ts": 2519, + "packages/core/tests/scanner.test.ts": 615, + "packages/core/tests/scope-local.test.ts": 521, + "packages/core/tests/secret-detection.test.ts": 2211, + "packages/core/tests/secret-files.test.ts": 757, + "packages/core/tests/secret-rules.test.ts": 876, + "packages/core/tests/secret-scanner-baseline.test.ts": 801, + "packages/core/tests/secret-scanner.test.ts": 744, + "packages/core/tests/source-position.test.ts": 1168, + "packages/core/tests/state-ownership.test.ts": 1245, + "packages/core/tests/streaming-emission.test.ts": 1223, + "packages/core/tests/switch.test.ts": 1919, + "packages/core/tests/syntax-catalog.test.ts": 1745, + "packages/core/tests/syntax-component.test.ts": 2866, + "packages/core/tests/temp-dir.test.ts": 3819, + "packages/core/tests/temp-file-compiler.test.ts": 586, + "packages/core/tests/terminal-grid-structure.test.ts": 936, + "packages/core/tests/text-interpolation.test.ts": 952, + "packages/core/tests/try-content.test.ts": 952, + "packages/core/tests/unused-in-diff.test.ts": 1422, + "packages/core/tests/validate.test.ts": 870, + "packages/core/tests/validation-integration.test.ts": 1253, + "packages/core/tests/workflow-component-bundle.test.ts": 1645, + "packages/durable-streams/tests/context.test.ts": 568, + "packages/durable-streams/tests/deterministic-id.test.ts": 573, + "packages/durable-streams/tests/divergence-api.test.ts": 569, + "packages/durable-streams/tests/divergence.test.ts": 586, + "packages/durable-streams/tests/durable-each.test.ts": 576, + "packages/durable-streams/tests/durable-position.test.ts": 562, + "packages/durable-streams/tests/durable-run.test.ts": 624, + "packages/durable-streams/tests/ephemeral.test.ts": 560, + "packages/durable-streams/tests/fail-stop.test.ts": 614, + "packages/durable-streams/tests/guard-stream.test.ts": 638, + "packages/durable-streams/tests/live-coordinator.test.ts": 588, + "packages/durable-streams/tests/parse.test.ts": 600, + "packages/durable-streams/tests/replay-guard.test.ts": 623, + "packages/durable-streams/tests/replay-index.test.ts": 564, + "packages/durable-streams/tests/retained.test.ts": 556, + "packages/durable-streams/tests/serialize-event.test.ts": 562, + "packages/durable-streams/tests/smoke.test.ts": 550, + "packages/durable-streams/tests/structured-concurrency.test.ts": 636, + "packages/durable-streams/tests/terminal-boundary.test.ts": 607, + "packages/durable-streams/tests/types.test.ts": 518, + "packages/runtime/tests/duration.test.ts": 555, + "packages/runtime/tests/fetch.test.ts": 1154, + "packages/runtime/tests/fs.test.ts": 600, + "packages/runtime/tests/host-files.test.ts": 1349, + "packages/runtime/tests/native-launcher.test.ts": 2937, + "packages/runtime/tests/process.test.ts": 589, + "packages/runtime/tests/service.test.ts": 571, + "packages/test-agent/tests/acp-server.test.ts": 710, + "packages/test-agent/tests/behavior-engine.test.ts": 1680, + "packages/test-agent/tests/bridge.test.ts": 534, + "packages/test-agent/tests/command-lazy.test.ts": 6735, + "packages/test-agent/tests/components.test.ts": 106694, + "packages/test-agent/tests/controller.test.ts": 831, + "packages/test-agent/tests/cross-package-resolution.test.ts": 3012, + "packages/test-agent/tests/native-launch.test.ts": 54773, + "packages/test-agent/tests/net.test.ts": 623, + "packages/test-agent/tests/profile.test.ts": 1213, + "packages/test-agent/tests/protocol.test.ts": 583, + "packages/test-agent/tests/provider.test.ts": 1375, + "packages/test-agent/tests/public-api.test.ts": 1578, + "packages/test-agent/tests/route-slot.test.ts": 519, + "packages/test-agent/tests/smoke.test.ts": 28926, + "packages/test-agent/tests/template.test.ts": 1242, + "packages/test-agent/tests/worker-lifecycle.test.ts": 23816, + "packages/test-support/tests/journal.test.ts": 512, + "packages/testing/tests/agent-composition.test.ts": 1537, + "packages/testing/tests/assert-throws.test.ts": 3212, + "packages/testing/tests/assert.test.ts": 533, + "packages/testing/tests/assertions.test.ts": 3877, + "packages/testing/tests/boundary-contract.test.ts": 2560, + "packages/testing/tests/cli.test.ts": 11678, + "packages/testing/tests/execution-harness.test.ts": 7880, + "packages/testing/tests/replay.test.ts": 3174, + "packages/testing/tests/smoke.test.ts": 3418, + "packages/testing/tests/test-component.test.ts": 3971, + "packages/testing/tests/testing-activation.test.ts": 3523, + "packages/testing/tests/testing-boundary.test.ts": 2021, + "packages/testing/tests/testing-mode.test.ts": 4224, + "packages/testing/tests/use-testing.test.ts": 2849, + "packages/web/tests/assets.test.ts": 510, + "packages/web/tests/client-logic.test.ts": 547, + "packages/web/tests/compile.test.ts": 2027, + "packages/web/tests/component.test.ts": 2607, + "packages/web/tests/declaration.test.ts": 1710, + "packages/web/tests/document.test.ts": 1827, + "packages/web/tests/elicitation.test.ts": 1626, + "packages/web/tests/live-form.test.ts": 1545, + "packages/web/tests/markdown.test.ts": 714, + "packages/web/tests/opener.test.ts": 1534, + "packages/web/tests/page.test.ts": 515, + "packages/web/tests/responder.test.ts": 1835, + "packages/web/tests/server-lifecycle.test.ts": 1666, + "packages/web/tests/server.test.ts": 2076, + "packages/workflow/tests/generated-observations.test.ts": 1473, + "packages/workflow/tests/git-host-effect.test.ts": 2649, + "packages/workflow/tests/git.test.ts": 539, + "packages/workflow/tests/issue-github.test.ts": 1239, + "packages/workflow/tests/issue-markdown.test.ts": 10923, + "packages/workflow/tests/issue-records.test.ts": 1216, + "packages/workflow/tests/pull-request-github.test.ts": 638, + "packages/workflow/tests/pull-request-records.test.ts": 1302, + "packages/workflow/tests/retained-run.test.ts": 2202, + "packages/workflow/tests/selection-authentication.test.ts": 521, + "packages/workflow/tests/service-denial.test.ts": 541, + "packages/workflow/tests/workflow-bundle.test.ts": 1707, + "packages/workflow/tests/workflow-definition.test.ts": 1417, + "packages/workflow/tests/workflow-fork.test.ts": 1287, + "packages/workflow/tests/workflow-run.test.ts": 2114, + "packages/workflow/tests/workspace-effect.test.ts": 3426, + "packages/workflow/tests/xmd-artifact.test.ts": 3991, + "scripts/tests/adapter-vendor.test.ts": 768, + "scripts/tests/bootstrap-npm-package.test.ts": 8812, + "scripts/tests/bump-version.test.ts": 649, + "scripts/tests/changed-paths.test.ts": 545, + "scripts/tests/ci-workflow.test.ts": 2297, + "scripts/tests/consumer-cycle.test.ts": 707, + "scripts/tests/filesystem-contract-workflow.test.ts": 612, + "scripts/tests/main-green.test.ts": 794, + "scripts/tests/main-health.test.ts": 632, + "scripts/tests/no-module-scoped-registry.test.ts": 1370, + "scripts/tests/no-redundant-test-scope.test.ts": 5571, + "scripts/tests/no-sync-filesystem.test.ts": 5810, + "scripts/tests/no-yield-in-finally.test.ts": 1383, + "scripts/tests/oxlint-policy.test.ts": 11311, + "scripts/tests/packaged-document.test.ts": 543, + "scripts/tests/prefer-effection-operation.test.ts": 6347, + "scripts/tests/prefer-effection-result.test.ts": 4695, + "scripts/tests/publish-workflow-membership.test.ts": 596, + "scripts/tests/review-infrastructure.test.ts": 3397, + "scripts/tests/runtime-exclusions.test.ts": 1018, + "scripts/tests/runtime-tests.test.ts": 584, + "scripts/tests/scope-bound-event-registration.test.ts": 5557, + "scripts/tests/staged-write.test.ts": 561, + "scripts/tests/test-file-discovery.test.ts": 858, + "scripts/tests/test-shards.test.ts": 564, + "scripts/tests/test-weights.test.ts": 777, + "scripts/tests/tracked.test.ts": 547, + "scripts/tests/verify-coordinator.test.ts": 774, + "scripts/tests/web-client-module.test.ts": 530, + "scripts/tests/workspace.test.ts": 518 }, "bun": { - "packages/acp/tests/acceptance.test.ts": 764, - "packages/acp/tests/acpx-checkpoint-meta.test.ts": 4306, - "packages/acp/tests/acpx-materialization.test.ts": 6502, - "packages/acp/tests/acpx-transient-env.test.ts": 251, - "packages/acp/tests/adapter-materialization.test.ts": 69745, - "packages/acp/tests/adapter-protocol.test.ts": 36552, - "packages/acp/tests/native-launch.test.ts": 895, - "packages/acp/tests/permission-bridge.test.ts": 351, - "packages/acp/tests/provider.test.ts": 774, - "packages/acp/tests/serial-queue.test.ts": 66, - "packages/acp/tests/session-key.test.ts": 77, - "packages/cli/tests/agent-adapters.test.ts": 1485, - "packages/cli/tests/agent-cli.test.ts": 12007, - "packages/cli/tests/agent-config.test.ts": 29, - "packages/cli/tests/agent-session-coordinator.test.ts": 378, - "packages/cli/tests/cli-help.test.ts": 10485, - "packages/cli/tests/command.test.ts": 7822, - "packages/cli/tests/document-suites/inline/inline-markdown.test.ts": 2352, - "packages/cli/tests/document-suites/props/props-markdown.test.ts": 1890, - "packages/cli/tests/document-suites/syntax/syntax-markdown.test.ts": 4856, - "packages/cli/tests/document-suites/targets/targets-markdown.test.ts": 3841, - "packages/cli/tests/document-suites/verbose/verbose-markdown.test.ts": 8433, - "packages/cli/tests/fetch-cli.test.ts": 2186, - "packages/cli/tests/file-stream.test.ts": 57, - "packages/cli/tests/inline-cli.test.ts": 27163, - "packages/cli/tests/launch-timeout.test.ts": 10098, - "packages/cli/tests/packaged-document.test.ts": 469, - "packages/cli/tests/plan-args.test.ts": 84, - "packages/cli/tests/plan-cli.test.ts": 26713, - "packages/cli/tests/plan-command-document.test.ts": 930, - "packages/cli/tests/plan-component.test.ts": 3482, - "packages/cli/tests/plan-host-acts.test.ts": 1461, - "packages/cli/tests/plan.test.ts": 22521, - "packages/cli/tests/process-retention.test.ts": 2326, - "packages/cli/tests/props-cli.test.ts": 27671, - "packages/cli/tests/props-schema.test.ts": 451, - "packages/cli/tests/props-sources.test.ts": 133, - "packages/cli/tests/run-composition.test.ts": 3210, - "packages/cli/tests/run-deadline.test.ts": 2540, - "packages/cli/tests/run-timeouts.test.ts": 11094, - "packages/cli/tests/secret-detection-cli.test.ts": 18587, - "packages/cli/tests/service-document.test.ts": 1570, - "packages/cli/tests/service-host.test.ts": 1452, - "packages/cli/tests/session-launch-cli.test.ts": 5353, - "packages/cli/tests/stdout-delivery.test.ts": 52, - "packages/cli/tests/syntax-cli.test.ts": 17431, - "packages/cli/tests/targets-cli.test.ts": 20355, - "packages/cli/tests/test-target.test.ts": 40330, - "packages/cli/tests/testing-activation.test.ts": 563, - "packages/cli/tests/testing-execution-host.test.ts": 30494, - "packages/cli/tests/upgrade-cli.test.ts": 17333, - "packages/cli/tests/upgrade-command-document.test.ts": 3516, - "packages/cli/tests/upgrade-output.test.ts": 777, - "packages/cli/tests/value-root.test.ts": 15182, - "packages/cli/tests/verbose-component.test.ts": 889, - "packages/cli/tests/workflow-declaration.test.ts": 305, - "packages/cli/tests/workflow-host.test.ts": 4039, - "packages/code-review-agent/tests/doctor.test.ts": 29, - "packages/code-review-agent/tests/parse-diagnostics.test.ts": 42, - "packages/code-review-agent/tests/parse-diff.test.ts": 36, - "packages/code-review-agent/tests/parse-doctor.test.ts": 29, - "packages/code-review-agent/tests/parse-oxlint.test.ts": 29, - "packages/code-review-agent/tests/policy.test.ts": 31, - "packages/core/tests/agent-api.test.ts": 30, - "packages/core/tests/agent-components.test.ts": 1187, - "packages/core/tests/agent-function-components.test.ts": 1944, - "packages/core/tests/agent-session-launch.test.ts": 2051, - "packages/core/tests/agent-stack.test.ts": 691, - "packages/core/tests/answers-component.test.ts": 1342, - "packages/core/tests/answers-expansion-recursion.test.ts": 317, - "packages/core/tests/capture-errors.test.ts": 556, - "packages/core/tests/capture-props.test.ts": 329, - "packages/core/tests/cli-journal.test.ts": 9573, - "packages/core/tests/code-block-component.test.ts": 2278, - "packages/core/tests/compiler-boundary.test.ts": 312, - "packages/core/tests/component-api.test.ts": 65, - "packages/core/tests/component-registration.test.ts": 1035, - "packages/core/tests/component-returns.test.ts": 1560, - "packages/core/tests/component-schema-conformance.test.ts": 561, + "packages/acp/tests/acceptance.test.ts": 879, + "packages/acp/tests/acpx-checkpoint-meta.test.ts": 4327, + "packages/acp/tests/acpx-materialization.test.ts": 6529, + "packages/acp/tests/acpx-transient-env.test.ts": 278, + "packages/acp/tests/adapter-materialization.test.ts": 71439, + "packages/acp/tests/adapter-protocol.test.ts": 41733, + "packages/acp/tests/native-launch.test.ts": 949, + "packages/acp/tests/permission-bridge.test.ts": 382, + "packages/acp/tests/provider.test.ts": 809, + "packages/acp/tests/serial-queue.test.ts": 68, + "packages/acp/tests/session-key.test.ts": 66, + "packages/cli/tests/agent-adapters.test.ts": 1374, + "packages/cli/tests/agent-cli.test.ts": 13127, + "packages/cli/tests/agent-config.test.ts": 31, + "packages/cli/tests/agent-session-coordinator.test.ts": 405, + "packages/cli/tests/cli-help.test.ts": 11535, + "packages/cli/tests/command.test.ts": 8001, + "packages/cli/tests/document-suites/inline/inline-markdown.test.ts": 2464, + "packages/cli/tests/document-suites/plan/plan-markdown.test.ts": 103960, + "packages/cli/tests/document-suites/props/props-markdown.test.ts": 1975, + "packages/cli/tests/document-suites/syntax/syntax-markdown.test.ts": 5024, + "packages/cli/tests/document-suites/targets/targets-markdown.test.ts": 4147, + "packages/cli/tests/document-suites/verbose/verbose-markdown.test.ts": 9074, + "packages/cli/tests/evaluate-component.test.ts": 8030, + "packages/cli/tests/fetch-cli.test.ts": 2370, + "packages/cli/tests/file-stream.test.ts": 60, + "packages/cli/tests/inline-cli.test.ts": 31469, + "packages/cli/tests/launch-timeout.test.ts": 10099, + "packages/cli/tests/packaged-document.test.ts": 473, + "packages/cli/tests/plan-args.test.ts": 37, + "packages/cli/tests/plan-cli.test.ts": 50345, + "packages/cli/tests/plan-command-document.test.ts": 5649, + "packages/cli/tests/plan-component.test.ts": 9407, + "packages/cli/tests/plan-host-acts.test.ts": 1374, + "packages/cli/tests/plan.test.ts": 15815, + "packages/cli/tests/process-retention.test.ts": 2413, + "packages/cli/tests/props-cli.test.ts": 27872, + "packages/cli/tests/props-schema.test.ts": 421, + "packages/cli/tests/props-sources.test.ts": 127, + "packages/cli/tests/run-composition.test.ts": 3221, + "packages/cli/tests/run-deadline.test.ts": 2560, + "packages/cli/tests/run-timeouts.test.ts": 11125, + "packages/cli/tests/secret-detection-cli.test.ts": 18895, + "packages/cli/tests/service-document.test.ts": 1525, + "packages/cli/tests/service-host.test.ts": 1425, + "packages/cli/tests/session-launch-cli.test.ts": 5536, + "packages/cli/tests/stdin-cli.test.ts": 28816, + "packages/cli/tests/stdout-delivery.test.ts": 53, + "packages/cli/tests/syntax-cli.test.ts": 35264, + "packages/cli/tests/targets-cli.test.ts": 21387, + "packages/cli/tests/test-target.test.ts": 42557, + "packages/cli/tests/testing-activation.test.ts": 578, + "packages/cli/tests/testing-execution-host.test.ts": 50835, + "packages/cli/tests/upgrade-cli.test.ts": 18252, + "packages/cli/tests/upgrade-command-document.test.ts": 3812, + "packages/cli/tests/upgrade-output.test.ts": 866, + "packages/cli/tests/value-root.test.ts": 16026, + "packages/cli/tests/verbose-component.test.ts": 960, + "packages/cli/tests/workflow-declaration.test.ts": 311, + "packages/cli/tests/workflow-host.test.ts": 4141, + "packages/code-review-agent/tests/doctor.test.ts": 30, + "packages/code-review-agent/tests/parse-diagnostics.test.ts": 44, + "packages/code-review-agent/tests/parse-diff.test.ts": 37, + "packages/code-review-agent/tests/parse-doctor.test.ts": 31, + "packages/code-review-agent/tests/parse-oxlint.test.ts": 32, + "packages/code-review-agent/tests/policy.test.ts": 32, + "packages/core/tests/agent-api.test.ts": 33, + "packages/core/tests/agent-components.test.ts": 1292, + "packages/core/tests/agent-function-components.test.ts": 2028, + "packages/core/tests/agent-session-launch.test.ts": 2259, + "packages/core/tests/agent-stack.test.ts": 726, + "packages/core/tests/answer-identity.test.ts": 43, + "packages/core/tests/answers-component.test.ts": 1466, + "packages/core/tests/answers-expansion-recursion.test.ts": 324, + "packages/core/tests/capture-errors.test.ts": 575, + "packages/core/tests/capture-props.test.ts": 335, + "packages/core/tests/cli-journal.test.ts": 10249, + "packages/core/tests/code-block-component.test.ts": 2348, + "packages/core/tests/compiler-boundary.test.ts": 345, + "packages/core/tests/component-api.test.ts": 58, + "packages/core/tests/component-registration.test.ts": 1074, + "packages/core/tests/component-returns.test.ts": 1654, + "packages/core/tests/component-schema-conformance.test.ts": 562, "packages/core/tests/config-api.test.ts": 348, - "packages/core/tests/construct-error-observation.test.ts": 704, - "packages/core/tests/contextual-cwd.test.ts": 1516, - "packages/core/tests/daemon-integration.test.ts": 1005, - "packages/core/tests/daemon.test.ts": 73, - "packages/core/tests/declared-markdown-component.test.ts": 1296, - "packages/core/tests/document-output-api.test.ts": 38, - "packages/core/tests/document-target-execution.test.ts": 3484, - "packages/core/tests/document-targets.test.ts": 409, - "packages/core/tests/document-validation.test.ts": 1405, - "packages/core/tests/each.test.ts": 394, - "packages/core/tests/elicit-component.test.ts": 881, - "packages/core/tests/ephemeral-service.test.ts": 770, - "packages/core/tests/eval-bindings.test.ts": 376, - "packages/core/tests/eval-context.test.ts": 75, - "packages/core/tests/eval-durable.test.ts": 406, - "packages/core/tests/eval-error-mode.test.ts": 646, - "packages/core/tests/eval-interpolate.test.ts": 38, - "packages/core/tests/eval-middleware.test.ts": 74, - "packages/core/tests/eval-persist.test.ts": 471, - "packages/core/tests/eval-return.test.ts": 403, - "packages/core/tests/eval-scope.test.ts": 322, - "packages/core/tests/eval-timeout.test.ts": 401, - "packages/core/tests/eval-transform.test.ts": 65, - "packages/core/tests/exec-timeout.test.ts": 466, - "packages/core/tests/execute.test.ts": 981, - "packages/core/tests/execution-protocol.test.ts": 1511, - "packages/core/tests/expand.test.ts": 866, - "packages/core/tests/expansion-identity.test.ts": 1210, + "packages/core/tests/construct-error-observation.test.ts": 699, + "packages/core/tests/contextual-cwd.test.ts": 1556, + "packages/core/tests/daemon-integration.test.ts": 1034, + "packages/core/tests/daemon.test.ts": 71, + "packages/core/tests/declared-markdown-component.test.ts": 1645, + "packages/core/tests/document-output-api.test.ts": 41, + "packages/core/tests/document-target-execution.test.ts": 3721, + "packages/core/tests/document-targets.test.ts": 446, + "packages/core/tests/document-validation.test.ts": 1917, + "packages/core/tests/documentation-index.test.ts": 178, + "packages/core/tests/each.test.ts": 457, + "packages/core/tests/elicit-component.test.ts": 999, + "packages/core/tests/ephemeral-service.test.ts": 883, + "packages/core/tests/eval-bindings.test.ts": 415, + "packages/core/tests/eval-context.test.ts": 87, + "packages/core/tests/eval-durable.test.ts": 450, + "packages/core/tests/eval-error-mode.test.ts": 728, + "packages/core/tests/eval-interpolate.test.ts": 39, + "packages/core/tests/eval-middleware.test.ts": 82, + "packages/core/tests/eval-persist.test.ts": 521, + "packages/core/tests/eval-return.test.ts": 455, + "packages/core/tests/eval-scope.test.ts": 363, + "packages/core/tests/eval-timeout.test.ts": 441, + "packages/core/tests/eval-transform.test.ts": 90, + "packages/core/tests/evaluate-component.test.ts": 2713, + "packages/core/tests/evaluate-loaded-copy.test.ts": 529, + "packages/core/tests/evaluate-provider-lifetime.test.ts": 620, + "packages/core/tests/evaluation-profile.test.ts": 187, + "packages/core/tests/exec-timeout.test.ts": 503, + "packages/core/tests/execute.test.ts": 1113, + "packages/core/tests/execution-protocol.test.ts": 1646, + "packages/core/tests/expand.test.ts": 848, + "packages/core/tests/expansion-identity.test.ts": 1239, "packages/core/tests/expansion-metadata.test.ts": 354, - "packages/core/tests/expression-props.test.ts": 830, - "packages/core/tests/fail-component.test.ts": 734, - "packages/core/tests/failure-printing.test.ts": 674, - "packages/core/tests/fatal-cause.test.ts": 172, - "packages/core/tests/fetch-component.test.ts": 1624, - "packages/core/tests/file-component.test.ts": 2347, - "packages/core/tests/file-delete-component.test.ts": 601, - "packages/core/tests/files-fatal.test.ts": 1583, - "packages/core/tests/foreground-exec.test.ts": 1271, - "packages/core/tests/frontmatter.test.ts": 52, - "packages/core/tests/function-components.test.ts": 898, - "packages/core/tests/generated-xmd.test.ts": 1432, - "packages/core/tests/glob-api.test.ts": 93, - "packages/core/tests/glob-component.test.ts": 1237, - "packages/core/tests/guarded-journal.test.ts": 438, - "packages/core/tests/has-content.test.ts": 258, - "packages/core/tests/heal.test.ts": 248, - "packages/core/tests/if.test.ts": 834, - "packages/core/tests/inline-root.test.ts": 480, - "packages/core/tests/invocation-failures.test.ts": 105, - "packages/core/tests/invocation-identity.test.ts": 789, - "packages/core/tests/invocation-scope.test.ts": 531, - "packages/core/tests/journal-source-position.test.ts": 558, - "packages/core/tests/json-component.test.ts": 2439, + "packages/core/tests/expression-props.test.ts": 888, + "packages/core/tests/fail-component.test.ts": 754, + "packages/core/tests/failure-printing.test.ts": 690, + "packages/core/tests/fatal-cause.test.ts": 196, + "packages/core/tests/fetch-component.test.ts": 1733, + "packages/core/tests/file-component.test.ts": 2417, + "packages/core/tests/file-delete-component.test.ts": 639, + "packages/core/tests/files-fatal.test.ts": 1476, + "packages/core/tests/foreground-exec.test.ts": 1253, + "packages/core/tests/frontmatter.test.ts": 51, + "packages/core/tests/function-components.test.ts": 915, + "packages/core/tests/generated-composition.test.ts": 1138, + "packages/core/tests/generated-xmd.test.ts": 2289, + "packages/core/tests/glob-api.test.ts": 101, + "packages/core/tests/glob-component.test.ts": 1262, + "packages/core/tests/guarded-journal.test.ts": 453, + "packages/core/tests/has-content.test.ts": 283, + "packages/core/tests/heal.test.ts": 268, + "packages/core/tests/if.test.ts": 820, + "packages/core/tests/inline-root.test.ts": 484, + "packages/core/tests/invocation-failures.test.ts": 163, + "packages/core/tests/invocation-identity.test.ts": 790, + "packages/core/tests/invocation-scope.test.ts": 533, + "packages/core/tests/journal-source-position.test.ts": 575, + "packages/core/tests/json-component.test.ts": 2438, "packages/core/tests/json.test.ts": 34, - "packages/core/tests/let.test.ts": 404, - "packages/core/tests/loop.test.ts": 1188, - "packages/core/tests/named-slots.test.ts": 1336, - "packages/core/tests/output-error-mode.test.ts": 1530, - "packages/core/tests/output-normalize.test.ts": 42, - "packages/core/tests/output-terminal.test.ts": 167, - "packages/core/tests/parse-components.test.ts": 593, - "packages/core/tests/props-binding.test.ts": 549, - "packages/core/tests/registered-printed-errors.test.ts": 206, - "packages/core/tests/replay-stream.test.ts": 39, - "packages/core/tests/retain.test.ts": 459, - "packages/core/tests/root-props.test.ts": 557, - "packages/core/tests/root-provider.test.ts": 530, - "packages/core/tests/sample-component.test.ts": 1131, - "packages/core/tests/scanner.test.ts": 77, + "packages/core/tests/let.test.ts": 424, + "packages/core/tests/loop.test.ts": 1263, + "packages/core/tests/named-slots.test.ts": 1275, + "packages/core/tests/output-error-mode.test.ts": 1770, + "packages/core/tests/output-normalize.test.ts": 46, + "packages/core/tests/output-terminal.test.ts": 163, + "packages/core/tests/parse-components.test.ts": 612, + "packages/core/tests/plan-response.test.ts": 79, + "packages/core/tests/props-binding.test.ts": 561, + "packages/core/tests/protected-content.test.ts": 49, + "packages/core/tests/registered-printed-errors.test.ts": 216, + "packages/core/tests/replay-stream.test.ts": 38, + "packages/core/tests/retain.test.ts": 488, + "packages/core/tests/root-props.test.ts": 599, + "packages/core/tests/root-provider.test.ts": 597, + "packages/core/tests/sample-component.test.ts": 1143, + "packages/core/tests/scanner.test.ts": 79, "packages/core/tests/scope-local.test.ts": 36, - "packages/core/tests/secret-detection.test.ts": 1073, - "packages/core/tests/secret-files.test.ts": 133, - "packages/core/tests/secret-rules.test.ts": 163, - "packages/core/tests/secret-scanner-baseline.test.ts": 154, - "packages/core/tests/secret-scanner.test.ts": 100, - "packages/core/tests/source-position.test.ts": 318, - "packages/core/tests/state-ownership.test.ts": 408, - "packages/core/tests/streaming-emission.test.ts": 316, - "packages/core/tests/switch.test.ts": 809, - "packages/core/tests/syntax-catalog.test.ts": 829, - "packages/core/tests/temp-dir.test.ts": 2781, - "packages/core/tests/temp-file-compiler.test.ts": 78, - "packages/core/tests/text-interpolation.test.ts": 233, - "packages/core/tests/try-content.test.ts": 254, - "packages/core/tests/unused-in-diff.test.ts": 456, - "packages/core/tests/validate.test.ts": 302, - "packages/core/tests/validation-integration.test.ts": 368, - "packages/core/tests/workflow-component-bundle.test.ts": 673, + "packages/core/tests/secret-detection.test.ts": 1140, + "packages/core/tests/secret-files.test.ts": 136, + "packages/core/tests/secret-rules.test.ts": 170, + "packages/core/tests/secret-scanner-baseline.test.ts": 159, + "packages/core/tests/secret-scanner.test.ts": 104, + "packages/core/tests/source-position.test.ts": 339, + "packages/core/tests/state-ownership.test.ts": 399, + "packages/core/tests/streaming-emission.test.ts": 323, + "packages/core/tests/switch.test.ts": 871, + "packages/core/tests/syntax-catalog.test.ts": 775, + "packages/core/tests/syntax-component.test.ts": 1769, + "packages/core/tests/temp-dir.test.ts": 2800, + "packages/core/tests/temp-file-compiler.test.ts": 87, + "packages/core/tests/terminal-grid-structure.test.ts": 202, + "packages/core/tests/text-interpolation.test.ts": 243, + "packages/core/tests/try-content.test.ts": 267, + "packages/core/tests/unused-in-diff.test.ts": 511, + "packages/core/tests/validate.test.ts": 325, + "packages/core/tests/validation-integration.test.ts": 370, + "packages/core/tests/workflow-component-bundle.test.ts": 707, "packages/durable-streams/tests/context.test.ts": 36, - "packages/durable-streams/tests/deterministic-id.test.ts": 72, - "packages/durable-streams/tests/divergence-api.test.ts": 47, - "packages/durable-streams/tests/divergence.test.ts": 58, - "packages/durable-streams/tests/durable-each.test.ts": 68, - "packages/durable-streams/tests/durable-position.test.ts": 54, - "packages/durable-streams/tests/durable-run.test.ts": 65, + "packages/durable-streams/tests/deterministic-id.test.ts": 71, + "packages/durable-streams/tests/divergence-api.test.ts": 49, + "packages/durable-streams/tests/divergence.test.ts": 57, + "packages/durable-streams/tests/durable-each.test.ts": 74, + "packages/durable-streams/tests/durable-position.test.ts": 55, + "packages/durable-streams/tests/durable-run.test.ts": 66, "packages/durable-streams/tests/ephemeral.test.ts": 62, - "packages/durable-streams/tests/fail-stop.test.ts": 74, - "packages/durable-streams/tests/guard-stream.test.ts": 99, - "packages/durable-streams/tests/live-coordinator.test.ts": 58, - "packages/durable-streams/tests/parse.test.ts": 49, - "packages/durable-streams/tests/replay-guard.test.ts": 75, - "packages/durable-streams/tests/replay-index.test.ts": 47, - "packages/durable-streams/tests/retained.test.ts": 45, - "packages/durable-streams/tests/serialize-event.test.ts": 43, - "packages/durable-streams/tests/smoke.test.ts": 36, - "packages/durable-streams/tests/structured-concurrency.test.ts": 160, - "packages/durable-streams/tests/terminal-boundary.test.ts": 81, - "packages/durable-streams/tests/types.test.ts": 28, + "packages/durable-streams/tests/fail-stop.test.ts": 79, + "packages/durable-streams/tests/guard-stream.test.ts": 103, + "packages/durable-streams/tests/live-coordinator.test.ts": 62, + "packages/durable-streams/tests/parse.test.ts": 50, + "packages/durable-streams/tests/replay-guard.test.ts": 74, + "packages/durable-streams/tests/replay-index.test.ts": 100, + "packages/durable-streams/tests/retained.test.ts": 50, + "packages/durable-streams/tests/serialize-event.test.ts": 41, + "packages/durable-streams/tests/smoke.test.ts": 34, + "packages/durable-streams/tests/structured-concurrency.test.ts": 96, + "packages/durable-streams/tests/terminal-boundary.test.ts": 79, + "packages/durable-streams/tests/types.test.ts": 29, "packages/runtime/tests/duration.test.ts": 30, - "packages/runtime/tests/fetch.test.ts": 610, - "packages/runtime/tests/fs.test.ts": 73, - "packages/runtime/tests/host-files.test.ts": 733, - "packages/runtime/tests/native-launcher.test.ts": 2396, - "packages/runtime/tests/process.test.ts": 91, - "packages/runtime/tests/service.test.ts": 65, - "packages/test-agent/tests/acp-server.test.ts": 109, - "packages/test-agent/tests/behavior-engine.test.ts": 658, - "packages/test-agent/tests/bridge.test.ts": 68, - "packages/test-agent/tests/command-lazy.test.ts": 3260, - "packages/test-agent/tests/components.test.ts": 51444, - "packages/test-agent/tests/controller.test.ts": 211, - "packages/test-agent/tests/cross-package-resolution.test.ts": 1807, - "packages/test-agent/tests/native-launch.test.ts": 23663, - "packages/test-agent/tests/net.test.ts": 83, - "packages/test-agent/tests/profile.test.ts": 304, + "packages/runtime/tests/fetch.test.ts": 613, + "packages/runtime/tests/fs.test.ts": 80, + "packages/runtime/tests/host-files.test.ts": 726, + "packages/runtime/tests/native-launcher.test.ts": 2405, + "packages/runtime/tests/process.test.ts": 89, + "packages/runtime/tests/service.test.ts": 68, + "packages/test-agent/tests/acp-server.test.ts": 110, + "packages/test-agent/tests/behavior-engine.test.ts": 680, + "packages/test-agent/tests/bridge.test.ts": 67, + "packages/test-agent/tests/command-lazy.test.ts": 3232, + "packages/test-agent/tests/components.test.ts": 51983, + "packages/test-agent/tests/controller.test.ts": 203, + "packages/test-agent/tests/cross-package-resolution.test.ts": 2053, + "packages/test-agent/tests/native-launch.test.ts": 23840, + "packages/test-agent/tests/net.test.ts": 112, + "packages/test-agent/tests/profile.test.ts": 301, "packages/test-agent/tests/protocol.test.ts": 59, - "packages/test-agent/tests/provider.test.ts": 406, - "packages/test-agent/tests/public-api.test.ts": 468, - "packages/test-agent/tests/route-slot.test.ts": 58, - "packages/test-agent/tests/smoke.test.ts": 15313, - "packages/test-agent/tests/template.test.ts": 300, - "packages/test-agent/tests/worker-lifecycle.test.ts": 9013, - "packages/test-support/tests/journal.test.ts": 43, - "packages/testing/tests/agent-composition.test.ts": 647, - "packages/testing/tests/assert-throws.test.ts": 2226, - "packages/testing/tests/assert.test.ts": 57, - "packages/testing/tests/assertions.test.ts": 2970, - "packages/testing/tests/boundary-contract.test.ts": 1636, - "packages/testing/tests/cli.test.ts": 5466, - "packages/testing/tests/execution-harness.test.ts": 6964, - "packages/testing/tests/replay.test.ts": 2384, - "packages/testing/tests/smoke.test.ts": 1920, - "packages/testing/tests/test-component.test.ts": 3161, - "packages/testing/tests/testing-activation.test.ts": 2784, - "packages/testing/tests/testing-boundary.test.ts": 1217, - "packages/testing/tests/testing-mode.test.ts": 3289, - "packages/testing/tests/use-testing.test.ts": 2005, - "packages/web/tests/assets.test.ts": 33, - "packages/web/tests/client-logic.test.ts": 59, - "packages/web/tests/compile.test.ts": 1011, - "packages/web/tests/component.test.ts": 1564, - "packages/web/tests/declaration.test.ts": 695, - "packages/web/tests/document.test.ts": 851, - "packages/web/tests/elicitation.test.ts": 559, - "packages/web/tests/live-form.test.ts": 500, - "packages/web/tests/markdown.test.ts": 144, - "packages/web/tests/opener.test.ts": 514, - "packages/web/tests/page.test.ts": 33, - "packages/web/tests/responder.test.ts": 813, - "packages/web/tests/server-lifecycle.test.ts": 625, - "packages/web/tests/server.test.ts": 1125, - "packages/workflow/tests/generated-observations.test.ts": 546, - "packages/workflow/tests/git-host-effect.test.ts": 1558, + "packages/test-agent/tests/provider.test.ts": 426, + "packages/test-agent/tests/public-api.test.ts": 481, + "packages/test-agent/tests/route-slot.test.ts": 59, + "packages/test-agent/tests/smoke.test.ts": 15562, + "packages/test-agent/tests/template.test.ts": 297, + "packages/test-agent/tests/worker-lifecycle.test.ts": 9227, + "packages/test-support/tests/journal.test.ts": 45, + "packages/testing/tests/agent-composition.test.ts": 648, + "packages/testing/tests/assert-throws.test.ts": 2474, + "packages/testing/tests/assert.test.ts": 58, + "packages/testing/tests/assertions.test.ts": 3296, + "packages/testing/tests/boundary-contract.test.ts": 1697, + "packages/testing/tests/cli.test.ts": 5502, + "packages/testing/tests/execution-harness.test.ts": 7006, + "packages/testing/tests/replay.test.ts": 2332, + "packages/testing/tests/smoke.test.ts": 1916, + "packages/testing/tests/test-component.test.ts": 3085, + "packages/testing/tests/testing-activation.test.ts": 2644, + "packages/testing/tests/testing-boundary.test.ts": 1124, + "packages/testing/tests/testing-mode.test.ts": 3344, + "packages/testing/tests/use-testing.test.ts": 1961, + "packages/web/tests/assets.test.ts": 37, + "packages/web/tests/client-logic.test.ts": 87, + "packages/web/tests/compile.test.ts": 953, + "packages/web/tests/component.test.ts": 1436, + "packages/web/tests/declaration.test.ts": 674, + "packages/web/tests/document.test.ts": 787, + "packages/web/tests/elicitation.test.ts": 577, + "packages/web/tests/live-form.test.ts": 504, + "packages/web/tests/markdown.test.ts": 150, + "packages/web/tests/opener.test.ts": 511, + "packages/web/tests/page.test.ts": 35, + "packages/web/tests/responder.test.ts": 891, + "packages/web/tests/server-lifecycle.test.ts": 652, + "packages/web/tests/server.test.ts": 1195, + "packages/workflow/tests/generated-observations.test.ts": 556, + "packages/workflow/tests/git-host-effect.test.ts": 1615, "packages/workflow/tests/git.test.ts": 69, - "packages/workflow/tests/issue-github.test.ts": 314, - "packages/workflow/tests/issue-markdown.test.ts": 8942, - "packages/workflow/tests/issue-records.test.ts": 302, - "packages/workflow/tests/pull-request-github.test.ts": 84, - "packages/workflow/tests/pull-request-records.test.ts": 316, - "packages/workflow/tests/retained-run.test.ts": 1202, - "packages/workflow/tests/selection-authentication.test.ts": 39, - "packages/workflow/tests/service-denial.test.ts": 61, - "packages/workflow/tests/workflow-bundle.test.ts": 738, - "packages/workflow/tests/workflow-definition.test.ts": 356, - "packages/workflow/tests/workflow-fork.test.ts": 308, - "packages/workflow/tests/workflow-run.test.ts": 1103, - "packages/workflow/tests/workspace-effect.test.ts": 1841, - "scripts/tests/adapter-vendor.test.ts": 164, - "scripts/tests/bootstrap-npm-package.test.ts": 5508, + "packages/workflow/tests/issue-github.test.ts": 298, + "packages/workflow/tests/issue-markdown.test.ts": 9015, + "packages/workflow/tests/issue-records.test.ts": 306, + "packages/workflow/tests/pull-request-github.test.ts": 87, + "packages/workflow/tests/pull-request-records.test.ts": 326, + "packages/workflow/tests/retained-run.test.ts": 1272, + "packages/workflow/tests/selection-authentication.test.ts": 41, + "packages/workflow/tests/service-denial.test.ts": 71, + "packages/workflow/tests/workflow-bundle.test.ts": 772, + "packages/workflow/tests/workflow-definition.test.ts": 342, + "packages/workflow/tests/workflow-fork.test.ts": 328, + "packages/workflow/tests/workflow-run.test.ts": 1075, + "packages/workflow/tests/workspace-effect.test.ts": 1767, + "scripts/tests/adapter-vendor.test.ts": 160, + "scripts/tests/bootstrap-npm-package.test.ts": 5560, "scripts/tests/bump-version.test.ts": 81, - "scripts/tests/changed-paths.test.ts": 42, - "scripts/tests/ci-workflow.test.ts": 1319, + "scripts/tests/changed-paths.test.ts": 41, + "scripts/tests/ci-workflow.test.ts": 1357, "scripts/tests/consumer-cycle.test.ts": 105, - "scripts/tests/filesystem-contract-workflow.test.ts": 85, - "scripts/tests/main-green.test.ts": 284, - "scripts/tests/main-health.test.ts": 111, - "scripts/tests/no-module-scoped-registry.test.ts": 924, - "scripts/tests/no-redundant-test-scope.test.ts": 5114, - "scripts/tests/no-sync-filesystem.test.ts": 4621, - "scripts/tests/no-yield-in-finally.test.ts": 900, + "scripts/tests/filesystem-contract-workflow.test.ts": 80, + "scripts/tests/main-green.test.ts": 291, + "scripts/tests/main-health.test.ts": 115, + "scripts/tests/no-module-scoped-registry.test.ts": 927, + "scripts/tests/no-redundant-test-scope.test.ts": 5143, + "scripts/tests/no-sync-filesystem.test.ts": 4690, + "scripts/tests/no-yield-in-finally.test.ts": 920, "scripts/tests/oxlint-policy.test.ts": 10652, - "scripts/tests/packaged-document.test.ts": 39, - "scripts/tests/prefer-effection-operation.test.ts": 5674, - "scripts/tests/prefer-effection-result.test.ts": 4193, - "scripts/tests/publish-workflow-membership.test.ts": 55, - "scripts/tests/review-infrastructure.test.ts": 1971, - "scripts/tests/runtime-exclusions.test.ts": 289, - "scripts/tests/runtime-tests.test.ts": 78, - "scripts/tests/staged-write.test.ts": 67, - "scripts/tests/test-file-discovery.test.ts": 232, - "scripts/tests/test-shards.test.ts": 47, - "scripts/tests/test-weights.test.ts": 211, - "scripts/tests/tracked.test.ts": 42, + "scripts/tests/packaged-document.test.ts": 64, + "scripts/tests/prefer-effection-operation.test.ts": 5790, + "scripts/tests/prefer-effection-result.test.ts": 4177, + "scripts/tests/publish-workflow-membership.test.ts": 74, + "scripts/tests/review-infrastructure.test.ts": 1864, + "scripts/tests/runtime-exclusions.test.ts": 306, + "scripts/tests/runtime-tests.test.ts": 82, + "scripts/tests/scope-bound-event-registration.test.ts": 4539, + "scripts/tests/staged-write.test.ts": 70, + "scripts/tests/test-file-discovery.test.ts": 242, + "scripts/tests/test-shards.test.ts": 46, + "scripts/tests/test-weights.test.ts": 206, + "scripts/tests/tracked.test.ts": 40, "scripts/tests/verify-coordinator.test.ts": 224, - "scripts/tests/web-client-module.test.ts": 81, - "scripts/tests/workspace.test.ts": 76 + "scripts/tests/web-client-module.test.ts": 51, + "scripts/tests/workspace.test.ts": 78 } } }