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 +109 -33
- package/dist/cli.mjs.map +1 -1
- package/dist/runner.mjs +1 -1
- package/package.json +1 -1
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 "
|
|
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
|
-
-
|
|
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
|
|
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: [
|
|
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
|
-
...
|
|
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
|
-
|
|
93200
|
-
|
|
93201
|
-
|
|
93202
|
-
|
|
93203
|
-
|
|
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
|
-
...
|
|
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
|
-
...
|
|
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
|
-
|
|
96370
|
-
|
|
96371
|
-
|
|
96372
|
-
|
|
96373
|
-
|
|
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
|
-
...
|
|
96608
|
+
...parsedConflictFields(parsed.contract_conflicts),
|
|
96533
96609
|
telemetry
|
|
96534
96610
|
};
|
|
96535
96611
|
} catch (err) {
|