baro-ai 0.133.1 → 0.133.2

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.mjs CHANGED
@@ -91240,6 +91240,30 @@ function parseContractConflicts(value) {
91240
91240
  }
91241
91241
  return conflicts;
91242
91242
  }
91243
+ function parseUnavailableChecks(value) {
91244
+ if (!Array.isArray(value)) return [];
91245
+ const seen = /* @__PURE__ */ new Set();
91246
+ const checks = [];
91247
+ for (const entry of value) {
91248
+ if (typeof entry !== "object" || entry === null) continue;
91249
+ const { criterion, reason, kind } = entry;
91250
+ if (kind !== "check_unavailable") continue;
91251
+ if (typeof criterion !== "string" || !criterion.trim() || seen.has(criterion)) continue;
91252
+ if (typeof reason !== "string" || !reason.trim()) continue;
91253
+ seen.add(criterion);
91254
+ checks.push({ criterion, reason: reason.trim().slice(0, MAX_CONFLICT_REASON_CHARS) });
91255
+ if (checks.length >= MAX_CONTRACT_CONFLICTS) break;
91256
+ }
91257
+ return checks;
91258
+ }
91259
+ function parsedConflictFields(value) {
91260
+ const conflicts = parseContractConflicts(value);
91261
+ const unavailable = parseUnavailableChecks(value);
91262
+ return {
91263
+ ...conflicts.length > 0 ? { contractConflicts: conflicts } : {},
91264
+ ...unavailable.length > 0 ? { unavailableChecks: unavailable } : {}
91265
+ };
91266
+ }
91243
91267
  function applyContractConflicts(evaluation, criteria, enabled = CONTRACT_CONFLICTS_ENABLED) {
91244
91268
  const conflicts = (enabled ? evaluation.contractConflicts ?? [] : []).filter(
91245
91269
  (conflict) => criteria.includes(conflict.criterion)
@@ -91269,9 +91293,10 @@ or
91269
91293
  const remediationRule = options.remediationGroups ? `
91270
91294
  - For "fail", "remediation_groups" is required and must partition "violated_criteria" exactly once. Every group needs a concise "root_cause" and one or more exact failed criterion strings. For "pass" or "inconclusive", omit "remediation_groups".` : "";
91271
91295
  const conflictsRule = options.contractConflicts ? `
91272
- - "contract_conflicts" (optional, default []) lists criteria this story cannot satisfy as written, each as {"criterion":"exact criterion string","kind":"outside_write_surface" or "contradiction","reason":"\u2026"}. Use "outside_write_surface" only when meeting the criterion requires changing files outside the "## Write surface" Baro lists for this story, and name those files. Use "contradiction" only when no change could meet it together with another of this story's criteria, and quote that other criterion.
91296
+ - "contract_conflicts" (optional, default []) lists criteria this story cannot satisfy as written, each as {"criterion":"exact criterion string","kind":"outside_write_surface", "contradiction" or "check_unavailable","reason":"\u2026"}. Use "outside_write_surface" only when meeting the criterion requires changing files outside the "## Write surface" Baro lists for this story, and name those files. Use "contradiction" only when no change could meet it together with another of this story's criteria, and quote that other criterion.
91273
91297
  - A conflicted criterion is not this story's to meet: leave it out of "violated_criteria" and decide "verdict" on every other criterion. Baro moves an "outside_write_surface" criterion to a follow-up story that may change those files, and records a "contradiction" for the run-level reviews.
91274
- - Never list a criterion the story could meet within its write surface but did not, or one that merely lacks evidence: those are violations. Without a "## Write surface" section, only the contradiction case applies.` : "";
91298
+ - A command whose runtime status reads "could not start" did not run: its tool is not installed in this worktree. That is a fact about the environment, not about the work. When the only thing a criterion lacks is a passing run of such a command, use kind "check_unavailable" and name the command; leave the criterion out of "violated_criteria". Never use it for a command that ran and failed, or when no command is marked "could not start".
91299
+ - Never list a criterion the story could meet within its write surface but did not, or one that merely lacks evidence: those are violations. Without a "## Write surface" section, only the contradiction and check_unavailable cases apply.` : "";
91275
91300
  return `You are a strict acceptance-criteria evaluator. You will receive:
91276
91301
  1. A list of acceptance criteria that must ALL be satisfied.
91277
91302
  2. Optionally, the accepted architecture decisions the agent was bound to.
@@ -91648,6 +91673,8 @@ var MAX_FINGERPRINT_PATHS = 5e3;
91648
91673
  var MAX_FINGERPRINT_FILE_BYTES = 64 * 1024 * 1024;
91649
91674
  var MAX_FINGERPRINT_TOTAL_BYTES = 256 * 1024 * 1024;
91650
91675
  var CRITIC_MAX_PROMPT_CHARS = 14e4;
91676
+ var COULD_NOT_START_STATUS = "could not start; the command's tool is not available in this worktree";
91677
+ var TOOL_UNAVAILABLE_ISSUE = "a verification command could not start: its tool is not available in the worktree";
91651
91678
  var PublishedNoteCollector = class extends BusMember {
91652
91679
  constructor(maxNotesPerStory = 6) {
91653
91680
  super();
@@ -91768,7 +91795,8 @@ var CriticCommandEvidenceCollector = class extends BusMember {
91768
91795
  entry.fingerprint,
91769
91796
  currentFingerprint
91770
91797
  );
91771
- const status = output === null ? "pending/no output observed" : commandOutputLooksFailed(output) ? "completed; output indicates failure" : "completed; consult captured output for the result";
91798
+ const toolUnavailable = output !== null && outputLooksToolUnavailable(output);
91799
+ const status = output === null ? "pending/no output observed" : toolUnavailable ? COULD_NOT_START_STATUS : commandOutputLooksFailed(output) ? "completed; output indicates failure" : "completed; consult captured output for the result";
91772
91800
  return {
91773
91801
  chronologicalIndex: index,
91774
91802
  command: entry.command,
@@ -91776,7 +91804,8 @@ var CriticCommandEvidenceCollector = class extends BusMember {
91776
91804
  command: entry.command,
91777
91805
  terminal: output !== null,
91778
91806
  freshness: freshness.state,
91779
- sandboxBlocked: output !== null && outputLooksSandboxBlocked(output)
91807
+ sandboxBlocked: output !== null && outputLooksSandboxBlocked(output),
91808
+ toolUnavailable
91780
91809
  },
91781
91810
  rendered: [
91782
91811
  `### Command ${index + 1}`,
@@ -92278,7 +92307,8 @@ async function prepareCriticEvaluation(criteria, resultText, agentId, source, es
92278
92307
  issues,
92279
92308
  staleCommands: staleCommandsToRerun(commandEvidence, issues),
92280
92309
  repositoryFingerprint: issues.length === 0 ? afterFingerprint.value : null,
92281
- established
92310
+ established,
92311
+ unavailableCommands: (commandEvidence.commands ?? []).filter((command) => command.toolUnavailable && command.freshness === "fresh").map((command) => command.command)
92282
92312
  };
92283
92313
  }
92284
92314
  function mergeSegmentVerdicts(verdicts) {
@@ -92301,6 +92331,11 @@ function mergeSegmentVerdicts(verdicts) {
92301
92331
  verdicts.flatMap((verdict) => verdict.contractConflicts ?? []).map((conflict) => [conflict.criterion, conflict])
92302
92332
  ).values()
92303
92333
  ];
92334
+ const unavailable = [
92335
+ ...new Map(
92336
+ verdicts.flatMap((verdict) => verdict.unavailableChecks ?? []).map((check) => [check.criterion, check])
92337
+ ).values()
92338
+ ];
92304
92339
  const reasoning = decisive.length > 0 ? decisive.map(({ verdict, pass }) => `[pass ${pass}] ${verdict.reasoning}`).join(" ") : first.reasoning;
92305
92340
  return {
92306
92341
  ...first,
@@ -92308,7 +92343,32 @@ function mergeSegmentVerdicts(verdicts) {
92308
92343
  verdict: decisive.length > 0 ? "fail" : "pass",
92309
92344
  reasoning,
92310
92345
  violatedCriteria: violated,
92311
- ...conflicts.length > 0 ? { contractConflicts: conflicts } : {}
92346
+ ...conflicts.length > 0 ? { contractConflicts: conflicts } : {},
92347
+ ...unavailable.length > 0 ? { unavailableChecks: unavailable } : {}
92348
+ };
92349
+ }
92350
+ var EVIDENCE_UNAVAILABLE_MARKER = "[acceptance evidence unavailable]";
92351
+ function applyUnavailableChecks(evaluation, criteria, unavailableCommands) {
92352
+ const { unavailableChecks, ...rest } = evaluation;
92353
+ const settled = rest;
92354
+ const claims = (unavailableChecks ?? []).filter(({ criterion }) => criteria.includes(criterion));
92355
+ if (claims.length === 0 || (settled.status ?? "evaluated") !== "evaluated") return settled;
92356
+ const claimed = new Set(claims.map(({ criterion }) => criterion));
92357
+ if (unavailableCommands.length === 0) {
92358
+ return {
92359
+ ...settled,
92360
+ verdict: "fail",
92361
+ violatedCriteria: [.../* @__PURE__ */ new Set([...settled.violatedCriteria, ...claimed])]
92362
+ };
92363
+ }
92364
+ const violated = settled.violatedCriteria.filter((criterion) => !claimed.has(criterion));
92365
+ if (violated.length > 0) return { ...settled, verdict: "fail", violatedCriteria: violated };
92366
+ return {
92367
+ ...settled,
92368
+ status: "inconclusive",
92369
+ verdict: "fail",
92370
+ reasoning: `Critic could not evaluate the candidate: ${claims.length} ${claims.length === 1 ? "criterion needs" : "criteria need"} a command that could not start in this worktree (${unavailableCommands.map((command) => boundText(command, 120)).join("; ")}). ` + settled.reasoning,
92371
+ violatedCriteria: [EVIDENCE_UNAVAILABLE_MARKER]
92312
92372
  };
92313
92373
  }
92314
92374
  function inconclusiveEvidenceVerdict(issues) {
@@ -92317,7 +92377,7 @@ function inconclusiveEvidenceVerdict(issues) {
92317
92377
  status: "inconclusive",
92318
92378
  verdict: "fail",
92319
92379
  reasoning: `Critic could not evaluate the candidate: ${detail}`,
92320
- violatedCriteria: ["[acceptance evidence unavailable]"]
92380
+ violatedCriteria: [EVIDENCE_UNAVAILABLE_MARKER]
92321
92381
  };
92322
92382
  }
92323
92383
  function buildEvalPrompt(criteria, resultText, commandEvidence = null, repositoryEvidence = null, decisionDocument = null, segment, publishedNotes = [], hostRunsWholeTreeVerification = false, altitudeSection = null, writeSurface = null, established = []) {
@@ -92510,7 +92570,7 @@ function evidenceReadinessIssues(commandEvidence, repositoryEvidence) {
92510
92570
  issues.push("no terminal shell command evidence was observed");
92511
92571
  } else if (commandEvidence.commands && commandEvidence.commands.length > 0) {
92512
92572
  const hasUsableFreshTerminalCommand = commandEvidence.commands.some(
92513
- (command) => command.freshness === "fresh" && command.terminal && !command.sandboxBlocked
92573
+ (command) => command.freshness === "fresh" && command.terminal && !command.sandboxBlocked && !command.toolUnavailable
92514
92574
  );
92515
92575
  if (!hasUsableFreshTerminalCommand) {
92516
92576
  if (commandEvidence.commands.some(
@@ -92526,8 +92586,13 @@ function evidenceReadinessIssues(commandEvidence, repositoryEvidence) {
92526
92586
  )) {
92527
92587
  issues.push("verification command was blocked by the sandbox");
92528
92588
  }
92589
+ if (commandEvidence.commands.some(
92590
+ (command) => command.toolUnavailable
92591
+ )) {
92592
+ issues.push(TOOL_UNAVAILABLE_ISSUE);
92593
+ }
92529
92594
  if (!issues.some(
92530
- (issue2) => issue2 === STALE_COMMAND_EVIDENCE || issue2 === "a verification command has no terminal output" || issue2 === "verification command was blocked by the sandbox"
92595
+ (issue2) => issue2 === STALE_COMMAND_EVIDENCE || issue2 === "a verification command has no terminal output" || issue2 === "verification command was blocked by the sandbox" || issue2 === TOOL_UNAVAILABLE_ISSUE
92531
92596
  )) {
92532
92597
  issues.push("command evidence has no usable fresh terminal command");
92533
92598
  }
@@ -92563,11 +92628,13 @@ function parseRenderedCommandEvidence(evidence) {
92563
92628
  const command = /^command:\s*(.+)$/m.exec(metadata)?.[1]?.trim() ?? "";
92564
92629
  const freshnessText = /^freshness:\s*(.+)$/m.exec(metadata)?.[1]?.trim();
92565
92630
  const freshness = freshnessText?.startsWith("fresh") === true ? "fresh" : freshnessText?.startsWith("STALE/UNVERIFIABLE") === true ? "unverifiable" : "stale";
92631
+ const toolUnavailable = runtime === COULD_NOT_START_STATUS || outputLooksToolUnavailable(output);
92566
92632
  return {
92567
92633
  command,
92568
- terminal: runtime?.startsWith("completed;") === true,
92634
+ terminal: runtime?.startsWith("completed;") === true || toolUnavailable,
92569
92635
  freshness,
92570
- sandboxBlocked: outputLooksSandboxBlocked(output)
92636
+ sandboxBlocked: outputLooksSandboxBlocked(output),
92637
+ toolUnavailable
92571
92638
  };
92572
92639
  });
92573
92640
  }
@@ -93040,6 +93107,11 @@ function shellCommandSegments(command) {
93040
93107
  (segment) => segment.trim().replace(/^\(+\s*/u, "").replace(/^(?:[A-Za-z_][A-Za-z0-9_]*=[^\s]+\s+)+/u, "")
93041
93108
  );
93042
93109
  }
93110
+ function outputLooksToolUnavailable(output) {
93111
+ return /\b(?:exit(?:ed)?(?: with)? (?:code|status)|status=)\s*127\b|(?:^|\n)\s*(?:(?:ba|z|da)?sh|npm error|npx)(?::\s*(?:line\s*)?\d+)?:\s.*(?:command not found|: not found)\b|\bcommand not found: \S+|\bis not recognized as an internal or external command\b|\bspawn \S+ ENOENT\b/i.test(
93112
+ output
93113
+ );
93114
+ }
93043
93115
  function outputLooksSandboxBlocked(output) {
93044
93116
  return /sandbox-exec|operation not permitted|permission denied|seatbelt|denied by sandbox/i.test(
93045
93117
  output
@@ -93143,13 +93215,12 @@ var OneShotCritic = class extends BusMember {
93143
93215
  /** Turn raw evaluator text into a verdict; throw to mark inconclusive. */
93144
93216
  parseVerdict(text3) {
93145
93217
  const parsed = JSON.parse(extractVerdictJson(text3.trim()));
93146
- const conflicts = parseContractConflicts(parsed.contract_conflicts);
93147
93218
  return {
93148
93219
  status: "evaluated",
93149
93220
  verdict: parsed.verdict === "pass" ? "pass" : "fail",
93150
93221
  reasoning: parsed.reasoning ?? "",
93151
93222
  violatedCriteria: Array.isArray(parsed.violated_criteria) ? parsed.violated_criteria : [],
93152
- ...conflicts.length > 0 ? { contractConflicts: conflicts } : {}
93223
+ ...parsedConflictFields(parsed.contract_conflicts)
93153
93224
  };
93154
93225
  }
93155
93226
  /**
@@ -93196,15 +93267,19 @@ var OneShotCritic = class extends BusMember {
93196
93267
  staleCommands = preparation.staleCommands;
93197
93268
  preparationReady = preparation.status === "ready";
93198
93269
  evaluation = preparationReady ? honorEstablished(
93199
- applyContractConflicts(
93200
- mergeSegmentVerdicts(
93201
- await Promise.all(
93202
- preparation.prompts.map(
93203
- (prompt) => this.evaluate(prompt, agentId, turn)
93270
+ applyUnavailableChecks(
93271
+ applyContractConflicts(
93272
+ mergeSegmentVerdicts(
93273
+ await Promise.all(
93274
+ preparation.prompts.map(
93275
+ (prompt) => this.evaluate(prompt, agentId, turn)
93276
+ )
93204
93277
  )
93205
- )
93278
+ ),
93279
+ criteria
93206
93280
  ),
93207
- criteria
93281
+ criteria,
93282
+ preparation.unavailableCommands
93208
93283
  ),
93209
93284
  preparation.established
93210
93285
  ) : inconclusiveEvidenceVerdict(preparation.issues);
@@ -93420,13 +93495,12 @@ var Critic = class extends OneShotCritic {
93420
93495
  }
93421
93496
  const verdictJson = extractVerdictJson(verdictText);
93422
93497
  const parsed = JSON.parse(verdictJson);
93423
- const conflicts = parseContractConflicts(parsed.contract_conflicts);
93424
93498
  return {
93425
93499
  status: "evaluated",
93426
93500
  verdict: parsed.verdict === "pass" ? "pass" : "fail",
93427
93501
  reasoning: parsed.reasoning ?? "",
93428
93502
  violatedCriteria: Array.isArray(parsed.violated_criteria) ? parsed.violated_criteria : [],
93429
- ...conflicts.length > 0 ? { contractConflicts: conflicts } : {},
93503
+ ...parsedConflictFields(parsed.contract_conflicts),
93430
93504
  telemetry
93431
93505
  };
93432
93506
  } catch (err) {
@@ -95763,13 +95837,12 @@ ${prompt}`,
95763
95837
  if (!isCodexVerdict(parsed)) {
95764
95838
  throw new Error("Codex critic returned an invalid verdict object");
95765
95839
  }
95766
- const conflicts = parseContractConflicts(parsed.contract_conflicts);
95767
95840
  return {
95768
95841
  status: "evaluated",
95769
95842
  verdict: parsed.verdict,
95770
95843
  reasoning: parsed.reasoning,
95771
95844
  violatedCriteria: [...parsed.violated_criteria],
95772
- ...conflicts.length > 0 ? { contractConflicts: conflicts } : {}
95845
+ ...parsedConflictFields(parsed.contract_conflicts)
95773
95846
  };
95774
95847
  }
95775
95848
  };
@@ -96366,15 +96439,19 @@ var CriticOpenAI = class extends BusMember {
96366
96439
  (fingerprint) => this.ledger.established(agentId, fingerprint)
96367
96440
  );
96368
96441
  const evaluation = preparation.status === "ready" ? honorEstablished(
96369
- applyContractConflicts(
96370
- mergeSegmentVerdicts(
96371
- await Promise.all(
96372
- preparation.prompts.map(
96373
- (prompt) => this.evaluate(prompt, agentId, turn, correlation)
96442
+ applyUnavailableChecks(
96443
+ applyContractConflicts(
96444
+ mergeSegmentVerdicts(
96445
+ await Promise.all(
96446
+ preparation.prompts.map(
96447
+ (prompt) => this.evaluate(prompt, agentId, turn, correlation)
96448
+ )
96374
96449
  )
96375
- )
96450
+ ),
96451
+ criteria
96376
96452
  ),
96377
- criteria
96453
+ criteria,
96454
+ preparation.unavailableCommands
96378
96455
  ),
96379
96456
  preparation.established
96380
96457
  ) : inconclusiveEvidenceVerdict(preparation.issues);
@@ -96523,13 +96600,12 @@ var CriticOpenAI = class extends BusMember {
96523
96600
  }
96524
96601
  const verdictJson = extractVerdictJson(assistantText);
96525
96602
  const parsed = JSON.parse(verdictJson);
96526
- const conflicts = parseContractConflicts(parsed.contract_conflicts);
96527
96603
  return {
96528
96604
  status: "evaluated",
96529
96605
  verdict: parsed.verdict === "pass" ? "pass" : "fail",
96530
96606
  reasoning: parsed.reasoning ?? "",
96531
96607
  violatedCriteria: Array.isArray(parsed.violated_criteria) ? parsed.violated_criteria : [],
96532
- ...conflicts.length > 0 ? { contractConflicts: conflicts } : {},
96608
+ ...parsedConflictFields(parsed.contract_conflicts),
96533
96609
  telemetry
96534
96610
  };
96535
96611
  } catch (err) {