@rulvar/cli 1.200.0 → 1.202.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { r as runCli, t as processIo } from "./io-C7TUZgVv.js";
2
+ import { r as runCli, t as processIo } from "./io-CAD1flsO.js";
3
3
  import { sanitizeTerminalText } from "@rulvar/core";
4
4
  import { inspect } from "node:util";
5
5
  //#region src/cli.ts
package/dist/index.d.ts CHANGED
@@ -49,6 +49,18 @@ declare function inspectCommand(argv: string[], context: CommandContext): Promis
49
49
  */
50
50
  declare function invoiceCommand(argv: string[], context: CommandContext): Promise<number>;
51
51
  /**
52
+ * cost-audit (RV1910): the denominator diagnostic over one stored run.
53
+ * The four-role benchmark's recovery run produced four mutually
54
+ * inconsistent cost views; the lifecycle now admits one, and this
55
+ * command VERIFIES it on a concrete journal instead of trusting the
56
+ * doctrine: the roster is closed (every agent entry terminal), the
57
+ * settle is recorded and is the billing boundary, and the settled
58
+ * fold, the invoice totals and the wire cardinality agree. Exit 1
59
+ * with the failing checks named when any diverge, which is exactly
60
+ * what a pre-RV1904 journal (the benchmark's own) reports.
61
+ */
62
+ declare function costAuditCommand(argv: string[], context: CommandContext): Promise<number>;
63
+ /**
52
64
  * rulvar preflight (the experiment-review P2.2; grammar in grammar.ts):
53
65
  * the effective-config linter and dry-run estimator. Loads the SAME
54
66
  * config, module, and run-profile merge `rulvar run` would assemble,
@@ -463,4 +475,4 @@ declare function toOtel(run: {
463
475
  result: Promise<RunOutcome<unknown>>;
464
476
  }, tracer: TracerLike, options?: ToOtelOptions): Promise<number>;
465
477
  //#endregion
466
- export { type AssembledCli, type CliConfig, type CliIo, type CommandContext, type CreateServerOptions, type CreateWorkerOptions, DEFAULT_MAX_BUFFERED_EVENTS_PER_RUN, DEFAULT_MAX_PENDING_EVENTS_PER_CLIENT, DEFAULT_STORE_DIR, DEFAULT_WORKER_TTL_MS, HELP, type KbSweepCliConfig, type LoadedWorkflowModule, type OtelContextApi, type PreflightDeclaration, type RulvarServer, type SpanLike, type ToOtelOptions, type TracerLike, type Worker, assembleEngine, attachProgress, createServer, createWorker, driveRun, inspectCommand, invoiceCommand, loadCliConfig, loadWorkflowModule, looksLikeFile, preflightCommand, processIo, renderEventLine, reportOutcome, resumeCommand, runCli, runCommand, runsLsCommand, strictExitCode, toOtel };
478
+ export { type AssembledCli, type CliConfig, type CliIo, type CommandContext, type CreateServerOptions, type CreateWorkerOptions, DEFAULT_MAX_BUFFERED_EVENTS_PER_RUN, DEFAULT_MAX_PENDING_EVENTS_PER_CLIENT, DEFAULT_STORE_DIR, DEFAULT_WORKER_TTL_MS, HELP, type KbSweepCliConfig, type LoadedWorkflowModule, type OtelContextApi, type PreflightDeclaration, type RulvarServer, type SpanLike, type ToOtelOptions, type TracerLike, type Worker, assembleEngine, attachProgress, costAuditCommand, createServer, createWorker, driveRun, inspectCommand, invoiceCommand, loadCliConfig, loadWorkflowModule, looksLikeFile, preflightCommand, processIo, renderEventLine, reportOutcome, resumeCommand, runCli, runCommand, runsLsCommand, strictExitCode, toOtel };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as loadCliConfig, a as invoiceCommand, c as runCommand, d as reportOutcome, f as strictExitCode, g as assembleEngine, h as DEFAULT_STORE_DIR, i as inspectCommand, l as runsLsCommand, m as renderEventLine, n as HELP, o as preflightCommand, p as attachProgress, r as runCli, s as resumeCommand, t as processIo, u as driveRun, v as loadWorkflowModule, y as looksLikeFile } from "./io-C7TUZgVv.js";
1
+ import { _ as assembleEngine, a as inspectCommand, b as looksLikeFile, c as resumeCommand, d as driveRun, f as reportOutcome, g as DEFAULT_STORE_DIR, h as renderEventLine, i as costAuditCommand, l as runCommand, m as attachProgress, n as HELP, o as invoiceCommand, p as strictExitCode, r as runCli, s as preflightCommand, t as processIo, u as runsLsCommand, v as loadCliConfig, y as loadWorkflowModule } from "./io-CAD1flsO.js";
2
2
  import { ConfigError, JournalCompatibilityError, LeaseHeldError, Replayer, RulvarError, buildDeriverRegistry, compileSecretMasker, costReportFromJournal, journalPricingSnapshot, maskSecrets, normalizeEntry, persistedTerminalEnvelope, readRunMeta, scanJournalCompatibility, validateDetachedResolution } from "@rulvar/core";
3
3
  //#region src/server.ts
4
4
  /**
@@ -1108,4 +1108,4 @@ async function toOtel(run, tracer, options = {}) {
1108
1108
  return created;
1109
1109
  }
1110
1110
  //#endregion
1111
- export { DEFAULT_MAX_BUFFERED_EVENTS_PER_RUN, DEFAULT_MAX_PENDING_EVENTS_PER_CLIENT, DEFAULT_STORE_DIR, DEFAULT_WORKER_TTL_MS, HELP, assembleEngine, attachProgress, createServer, createWorker, driveRun, inspectCommand, invoiceCommand, loadCliConfig, loadWorkflowModule, looksLikeFile, preflightCommand, processIo, renderEventLine, reportOutcome, resumeCommand, runCli, runCommand, runsLsCommand, strictExitCode, toOtel };
1111
+ export { DEFAULT_MAX_BUFFERED_EVENTS_PER_RUN, DEFAULT_MAX_PENDING_EVENTS_PER_CLIENT, DEFAULT_STORE_DIR, DEFAULT_WORKER_TTL_MS, HELP, assembleEngine, attachProgress, costAuditCommand, createServer, createWorker, driveRun, inspectCommand, invoiceCommand, loadCliConfig, loadWorkflowModule, looksLikeFile, preflightCommand, processIo, renderEventLine, reportOutcome, resumeCommand, runCli, runCommand, runsLsCommand, strictExitCode, toOtel };
@@ -558,6 +558,11 @@ const GRAMMAR = {
558
558
  positionals: ["<runId>"],
559
559
  flags: [STORE, { name: "json" }]
560
560
  },
561
+ "cost-audit": {
562
+ command: "cost-audit",
563
+ positionals: ["<runId>"],
564
+ flags: [STORE, { name: "json" }]
565
+ },
561
566
  plan: {
562
567
  command: "plan",
563
568
  positionals: ["\"<goal>\""],
@@ -689,6 +694,7 @@ function helpCommandLines() {
689
694
  GRAMMAR["runs audit"],
690
695
  GRAMMAR.inspect,
691
696
  GRAMMAR.invoice,
697
+ GRAMMAR["cost-audit"],
692
698
  GRAMMAR.plan,
693
699
  GRAMMAR.preflight
694
700
  ];
@@ -1278,6 +1284,90 @@ async function invoiceCommand(argv, context) {
1278
1284
  for (const item of invoice.unpriced) context.io.out(`unpriced: ${item.model} (${item.usage.inputTokens + item.usage.outputTokens} tok)`);
1279
1285
  return 0;
1280
1286
  }
1287
+ /**
1288
+ * cost-audit (RV1910): the denominator diagnostic over one stored run.
1289
+ * The four-role benchmark's recovery run produced four mutually
1290
+ * inconsistent cost views; the lifecycle now admits one, and this
1291
+ * command VERIFIES it on a concrete journal instead of trusting the
1292
+ * doctrine: the roster is closed (every agent entry terminal), the
1293
+ * settle is recorded and is the billing boundary, and the settled
1294
+ * fold, the invoice totals and the wire cardinality agree. Exit 1
1295
+ * with the failing checks named when any diverge, which is exactly
1296
+ * what a pre-RV1904 journal (the benchmark's own) reports.
1297
+ */
1298
+ async function costAuditCommand(argv, context) {
1299
+ const parsed = parseCommand(GRAMMAR["cost-audit"], argv);
1300
+ const runId = parsed.positionals[0];
1301
+ const store = parsed.values.store;
1302
+ const json = parsed.values.json === true;
1303
+ const assembled = assembleEngine({
1304
+ config: await loadCliConfig(context.cwd),
1305
+ ...store === void 0 ? {} : { storePath: store },
1306
+ cwd: context.cwd
1307
+ });
1308
+ if (await readRunMeta(assembled.store, runId) === void 0) throw new ConfigError(`run '${runId}' not found in the store`);
1309
+ const entries = await assembled.store.load(runId);
1310
+ const snapshot = journalPricingSnapshot(entries);
1311
+ const composed = snapshot === void 0 ? assembled.priceUsd : snapshot.composedPriceUsd(assembled.priceUsd);
1312
+ const report = costReportFromJournal(entries, composed);
1313
+ const invoice = invoiceFromJournal(entries, composed);
1314
+ const terminalRefs = new Set(entries.filter((entry) => entry.kind === "agent" && entry.status !== "running").map((entry) => entry.ref));
1315
+ const openAgents = entries.filter((entry) => entry.kind === "agent" && entry.status === "running" && !terminalRefs.has(entry.seq));
1316
+ const settle = [...entries].reverse().find((entry) => entry.kind === "decision" && entry.value?.decisionType === "run_settle");
1317
+ const agentsAfterSettle = settle === void 0 ? [] : entries.filter((entry) => entry.kind === "agent" && entry.seq > settle.seq);
1318
+ const grossDelta = Math.abs(report.grossUsd - invoice.totalUsd);
1319
+ const checks = [
1320
+ {
1321
+ name: "roster-closed",
1322
+ pass: openAgents.length === 0,
1323
+ detail: openAgents.length === 0 ? "every agent entry has a terminal" : `${String(openAgents.length)} agent entr${openAgents.length === 1 ? "y" : "ies"} still running (seq ${openAgents.map((entry) => entry.seq).join(", ")})`
1324
+ },
1325
+ {
1326
+ name: "settle-recorded",
1327
+ pass: settle !== void 0,
1328
+ detail: settle === void 0 ? "no run_settle decision" : `run_settle at seq ${String(settle.seq)}`
1329
+ },
1330
+ {
1331
+ name: "settle-is-billing-boundary",
1332
+ pass: agentsAfterSettle.length === 0,
1333
+ detail: agentsAfterSettle.length === 0 ? "no agent entry follows the settle" : `${String(agentsAfterSettle.length)} agent entr${agentsAfterSettle.length === 1 ? "y" : "ies"} after the settle (seq ${agentsAfterSettle.map((entry) => entry.seq).join(", ")}), the benchmark recovery shape`
1334
+ },
1335
+ {
1336
+ name: "fold-matches-invoice",
1337
+ pass: grossDelta < 1e-9,
1338
+ detail: `settled gross $${report.grossUsd.toFixed(7)} vs invoice total $${invoice.totalUsd.toFixed(7)}`
1339
+ },
1340
+ {
1341
+ name: "wires-match",
1342
+ pass: (report.wireRequests ?? -1) === invoice.cardinality.wireRequests,
1343
+ detail: `fold wires ${String(report.wireRequests ?? "absent")} vs invoice wires ${String(invoice.cardinality.wireRequests)}`
1344
+ }
1345
+ ];
1346
+ const failed = checks.filter((check) => !check.pass);
1347
+ if (json) {
1348
+ context.io.out(JSON.stringify({
1349
+ runId,
1350
+ verdict: failed.length === 0 ? "one-denominator" : "divergent",
1351
+ settled: {
1352
+ totalUsd: report.totalUsd,
1353
+ grossUsd: report.grossUsd,
1354
+ wireRequests: report.wireRequests ?? null
1355
+ },
1356
+ invoice: {
1357
+ totalUsd: invoice.totalUsd,
1358
+ rows: invoice.rows.length,
1359
+ wireRequests: invoice.cardinality.wireRequests
1360
+ },
1361
+ checks
1362
+ }, null, 2));
1363
+ return failed.length === 0 ? 0 : 1;
1364
+ }
1365
+ context.io.out(`run ${runId}: cost audit (${failed.length === 0 ? "one denominator" : "DIVERGENT"})`);
1366
+ context.io.out(`settled: gross $${report.grossUsd.toFixed(4)} | net $${report.totalUsd.toFixed(4)} | wires ${String(report.wireRequests ?? "absent")}`);
1367
+ context.io.out(`invoice: total $${invoice.totalUsd.toFixed(4)} | rows ${String(invoice.rows.length)} | wires ${String(invoice.cardinality.wireRequests)}`);
1368
+ for (const check of checks) context.io.out(` [${check.pass ? "pass" : "FAIL"}] ${check.name}: ${check.detail}`);
1369
+ return failed.length === 0 ? 0 : 1;
1370
+ }
1281
1371
  /** Formats an optional USD number for the preflight text rows. */
1282
1372
  function usdOf(value) {
1283
1373
  return value === void 0 ? "n/a" : `$${value.toFixed(4)}`;
@@ -1890,6 +1980,10 @@ billable provider call (failed and retried attempts included) with the
1890
1980
  provider's response id when the adapter surfaced one, plus the
1891
1981
  gross/net ledger totals (gross includes abandoned subtrees, exactly
1892
1982
  what the provider bills); --json emits the machine-readable form.
1983
+ cost-audit verifies the one-denominator contract on a stored run: the
1984
+ roster is closed, the settle is the billing boundary, and the settled
1985
+ fold, the invoice totals and the wire cardinality agree; exit 1 with
1986
+ the failing checks named when any diverge.
1893
1987
  preflight is the effective-config linter and dry-run estimator: it
1894
1988
  assembles the SAME options rulvar run would (config, module exports,
1895
1989
  --profile, --budget-usd) but constructs no engine and dispatches
@@ -1937,6 +2031,7 @@ async function runCli(argv, options) {
1937
2031
  }
1938
2032
  case "inspect": return await inspectCommand(rest, context);
1939
2033
  case "invoice": return await invoiceCommand(rest, context);
2034
+ case "cost-audit": return await costAuditCommand(rest, context);
1940
2035
  case "plan": return await planCommand(rest, context);
1941
2036
  case "preflight": return await preflightCommand(rest, context);
1942
2037
  case "kb": return await kbCommand(rest, context);
@@ -1988,4 +2083,4 @@ function processIo() {
1988
2083
  };
1989
2084
  }
1990
2085
  //#endregion
1991
- export { loadCliConfig as _, invoiceCommand as a, runCommand as c, reportOutcome as d, strictExitCode as f, assembleEngine as g, DEFAULT_STORE_DIR as h, inspectCommand as i, runsLsCommand as l, renderEventLine as m, HELP as n, preflightCommand as o, attachProgress as p, runCli as r, resumeCommand as s, processIo as t, driveRun as u, loadWorkflowModule as v, looksLikeFile as y };
2086
+ export { assembleEngine as _, inspectCommand as a, looksLikeFile as b, resumeCommand as c, driveRun as d, reportOutcome as f, DEFAULT_STORE_DIR as g, renderEventLine as h, costAuditCommand as i, runCommand as l, attachProgress as m, HELP as n, invoiceCommand as o, strictExitCode as p, runCli as r, preflightCommand as s, processIo as t, runsLsCommand as u, loadCliConfig as v, loadWorkflowModule as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/cli",
3
- "version": "1.200.0",
3
+ "version": "1.202.0",
4
4
  "description": "Rulvar shell: run/resume/runs/inspect/plan/kb commands, TUI progress, createServer, createWorker, OTel exporter.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -22,17 +22,17 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@rulvar/core": "1.200.0"
25
+ "@rulvar/core": "1.202.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.20.1",
29
29
  "tsdown": "^0.22.14",
30
30
  "typescript": "~6.0.3",
31
- "@rulvar/store-sqlite": "1.200.0",
32
- "@rulvar/plan": "1.200.0",
33
- "@rulvar/planner": "1.200.0",
34
- "@rulvar/evals": "1.200.0",
35
- "@rulvar/testing": "1.200.0"
31
+ "@rulvar/store-sqlite": "1.202.0",
32
+ "@rulvar/planner": "1.202.0",
33
+ "@rulvar/evals": "1.202.0",
34
+ "@rulvar/testing": "1.202.0",
35
+ "@rulvar/plan": "1.202.0"
36
36
  },
37
37
  "bin": {
38
38
  "rulvar": "./dist/cli.js"