import assert from "node:assert/strict"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import test from "node:test"; import { adaptiveBatchSize, batchContract, commandBudget, completedBatch, } from "../../../tools/web/wbv2-batch-contract.mjs"; import { createFailureLedgerSession } from "../../../tools/web/wbv2-failure-ledger.mjs"; test("batch contract is stable and completion is idempotent", () => { const module = { moduleId: "FCURVE", coverageBindings: ["rna:a", "rna:b"] }; const contract = batchContract("WBV2-P1-001", module); assert.equal(contract.selectedCount, 2); assert.match(contract.batchId, /^WBV2-P1-001:FCURVE:[a-f0-9]{16}$/u); assert.equal(completedBatch({ status: "done", batchId: contract.batchId, selectedRecordIds: contract.selectedRecordIds }, "WBV2-P1-001", module), true); }); test("adaptive batches follow the three-cycle fast and slow paths", () => { assert.equal(adaptiveBatchSize({ currentSize: 24, maxSize: 32, history: [{ durationMs: 120_000, commands: 10, focusedGateFailure: false }] }), 28); assert.equal(adaptiveBatchSize({ currentSize: 24, maxSize: 32, history: [{ durationMs: 901_000, commands: 10 }] }), 12); assert.equal(adaptiveBatchSize({ currentSize: 24, maxSize: 32, remaining: 5, history: [] }), 5); }); test("command budget separates exploration from execution", () => { assert.equal(commandBudget(["cat file", "npm run build"]).withinBudget, true); assert.equal(commandBudget(Array.from({ length: 49 }, () => "npm run focused")).withinBudget, false); assert.equal(commandBudget(Array.from({ length: 17 }, () => "rg pattern")).withinBudget, false); }); test("failure ledger hydrates completed cycles and flushes once", () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), "wbv2-fast-path-ledger-")); const logPath = "tests/golden/WBV2/cycle.log"; fs.mkdirSync(path.dirname(path.join(root, logPath)), { recursive: true }); fs.writeFileSync(path.join(root, logPath), 'prefix {"event":"cycle.completed","failure":{"task":"T","phase":"gate","reason":"failed"}}\n'); const session = createFailureLedgerSession(root, { logPaths: [logPath] }); assert.equal(session.ledger.entries.length, 1); session.record({ task: "T2", phase: "gate", reason: "failed" }); assert.equal(fs.existsSync(path.join(root, "tests/golden/WBV2/failure-ledger.json")), false); session.flush(); const written = JSON.parse(fs.readFileSync(path.join(root, "tests/golden/WBV2/failure-ledger.json"), "utf8")); assert.equal(written.entries.length, 2); assert.deepEqual(written.hydratedLogs, [logPath]); });