@nathapp/nax 0.67.18 → 0.68.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/nax.js +298 -369
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -16763,7 +16763,6 @@ var init_schemas_debate = __esm(() => {
|
|
|
16763
16763
|
exports_external.object({ kind: exports_external.literal("majority-fail-closed") }),
|
|
16764
16764
|
exports_external.object({ kind: exports_external.literal("majority-fail-open") }),
|
|
16765
16765
|
exports_external.object({ kind: exports_external.literal("judge") }),
|
|
16766
|
-
exports_external.object({ kind: exports_external.literal("dialogue-verdict") }),
|
|
16767
16766
|
exports_external.object({
|
|
16768
16767
|
kind: exports_external.literal("verifier-pick"),
|
|
16769
16768
|
patch: exports_external.object({
|
|
@@ -17187,7 +17186,7 @@ var init_schemas_infra = __esm(() => {
|
|
|
17187
17186
|
});
|
|
17188
17187
|
|
|
17189
17188
|
// src/config/schemas-review.ts
|
|
17190
|
-
var SemanticReviewConfigSchema,
|
|
17189
|
+
var SemanticReviewConfigSchema, AdversarialReviewConfigSchema, ReviewConfigSchema;
|
|
17191
17190
|
var init_schemas_review = __esm(() => {
|
|
17192
17191
|
init_zod();
|
|
17193
17192
|
init_schemas_model();
|
|
@@ -17206,11 +17205,6 @@ var init_schemas_review = __esm(() => {
|
|
|
17206
17205
|
}),
|
|
17207
17206
|
excludePatterns: exports_external.array(exports_external.string()).optional()
|
|
17208
17207
|
});
|
|
17209
|
-
ReviewDialogueConfigSchema = exports_external.object({
|
|
17210
|
-
enabled: exports_external.boolean().default(false),
|
|
17211
|
-
maxClarificationsPerAttempt: exports_external.number().int().min(0).max(10).default(2),
|
|
17212
|
-
maxDialogueMessages: exports_external.number().int().min(5).max(100).default(20)
|
|
17213
|
-
});
|
|
17214
17208
|
AdversarialReviewConfigSchema = exports_external.object({
|
|
17215
17209
|
model: ConfiguredModelSchema.default("balanced"),
|
|
17216
17210
|
diffMode: exports_external.enum(["embedded", "ref"]).default("ref"),
|
|
@@ -17242,6 +17236,7 @@ var init_schemas_review = __esm(() => {
|
|
|
17242
17236
|
}),
|
|
17243
17237
|
audit: exports_external.object({ enabled: exports_external.boolean().default(false) }).default({ enabled: false }),
|
|
17244
17238
|
blockingThreshold: exports_external.enum(["error", "warning", "info"]).default("error"),
|
|
17239
|
+
pluginMode: exports_external.enum(["observational", "gating"]).default("observational"),
|
|
17245
17240
|
semantic: SemanticReviewConfigSchema.optional(),
|
|
17246
17241
|
adversarial: AdversarialReviewConfigSchema.optional()
|
|
17247
17242
|
});
|
|
@@ -17426,6 +17421,7 @@ var init_schemas3 = __esm(() => {
|
|
|
17426
17421
|
commands: {},
|
|
17427
17422
|
audit: { enabled: false },
|
|
17428
17423
|
blockingThreshold: "error",
|
|
17424
|
+
pluginMode: "observational",
|
|
17429
17425
|
semantic: {
|
|
17430
17426
|
model: "balanced",
|
|
17431
17427
|
diffMode: "ref",
|
|
@@ -18748,10 +18744,10 @@ function _applyLegacyReviewExecutionShim(conf, warn = (msg) => {
|
|
|
18748
18744
|
const review = result.review ?? conf.review;
|
|
18749
18745
|
if (review && typeof review === "object") {
|
|
18750
18746
|
let newReview = review;
|
|
18751
|
-
const
|
|
18752
|
-
if (
|
|
18753
|
-
warn(
|
|
18754
|
-
const {
|
|
18747
|
+
const LEGACY_PLUGIN_MODE_VALUE = "per-story";
|
|
18748
|
+
if ("pluginMode" in review && review.pluginMode === LEGACY_PLUGIN_MODE_VALUE) {
|
|
18749
|
+
warn('review.pluginMode: "per-story" is a legacy value that has been removed. Remove it from your config (or set to "observational"/"gating").');
|
|
18750
|
+
const { pluginMode: _pm, ...rest } = review;
|
|
18755
18751
|
newReview = rest;
|
|
18756
18752
|
}
|
|
18757
18753
|
const dialogue = newReview.dialogue;
|
|
@@ -30228,9 +30224,6 @@ function resolvePersonas(debaters, stage, autoPersona) {
|
|
|
30228
30224
|
return { ...d, persona: assigned };
|
|
30229
30225
|
});
|
|
30230
30226
|
}
|
|
30231
|
-
function buildDebaterLabel(debater) {
|
|
30232
|
-
return debater.persona ? `${debater.agent} (${debater.persona})` : debater.agent;
|
|
30233
|
-
}
|
|
30234
30227
|
var PERSONA_FRAGMENTS, PLAN_ROTATION, REVIEW_ROTATION;
|
|
30235
30228
|
var init_personas = __esm(() => {
|
|
30236
30229
|
PERSONA_FRAGMENTS = {
|
|
@@ -31242,7 +31235,7 @@ ${STEP2}${frameworkLine}
|
|
|
31242
31235
|
${STEP3_HEADER}
|
|
31243
31236
|
${STEP3_SHARED_RULES}
|
|
31244
31237
|
- **File output (REQUIRED)**: Write the acceptance test file DIRECTLY to the path shown below. Do NOT output the test code in your response. After writing the file, reply with a brief confirmation.
|
|
31245
|
-
- **Path anchor (CRITICAL)**: Write the test file to this exact path: \`${p.targetTestFilePath}\`.
|
|
31238
|
+
- **Path anchor (CRITICAL \u2014 do NOT deviate)**: Write the test file to this exact path: \`${p.targetTestFilePath}\`. This path is intentional and computed by the orchestrator \u2014 do not change it based on what you observe in the project. In particular: if you see a \`.nax/features/\` directory at the repo root, that is for stories scoped to the repo root. When a story belongs to a specific package (e.g. \`packages/core\`), its acceptance test lives inside that package's \`.nax/features/\` directory so the test runner can resolve the package's imports correctly. The package root is 3 levels above the test file (\`../../../\` relative to the test file).
|
|
31246
31239
|
- **Process cwd**: When spawning child processes to invoke a CLI or binary, set the working directory to the **package root** (\`join(import.meta.dir, "../../..")\`) as your default \u2014 unless your Step 2 exploration reveals the CLI uses a different working directory convention (e.g. reads config from \`~/.config/\`, or resolves paths relative to a flag value). Always check how the CLI resolves file paths before assuming.${implSection}`;
|
|
31247
31240
|
}
|
|
31248
31241
|
buildGeneratorFromSpecPrompt(p) {
|
|
@@ -32482,33 +32475,6 @@ function llmFindingToReviewFinding(f, opts = {}) {
|
|
|
32482
32475
|
function llmFindingsToReviewFindings(findings, opts = {}) {
|
|
32483
32476
|
return findings.map((f) => llmFindingToReviewFinding(f, opts));
|
|
32484
32477
|
}
|
|
32485
|
-
function findingToReviewFinding(f, opts = {}) {
|
|
32486
|
-
const narrowed = narrowSeverity(f.severity);
|
|
32487
|
-
const ruleId = f.rule?.trim() ? f.rule.trim() : deriveRuleId(f.category, f.message);
|
|
32488
|
-
const result = {
|
|
32489
|
-
ruleId,
|
|
32490
|
-
severity: narrowed,
|
|
32491
|
-
file: f.file ?? "",
|
|
32492
|
-
line: f.line ?? 0,
|
|
32493
|
-
message: f.message
|
|
32494
|
-
};
|
|
32495
|
-
if (f.category)
|
|
32496
|
-
result.category = f.category;
|
|
32497
|
-
const effectiveSource = opts.source ?? f.source;
|
|
32498
|
-
if (effectiveSource)
|
|
32499
|
-
result.source = effectiveSource;
|
|
32500
|
-
const meta3 = { ...f.meta ?? {} };
|
|
32501
|
-
if (f.suggestion)
|
|
32502
|
-
meta3.suggestion = f.suggestion;
|
|
32503
|
-
if (f.severity !== narrowed)
|
|
32504
|
-
meta3.originalSeverity = f.severity;
|
|
32505
|
-
if (Object.keys(meta3).length > 0)
|
|
32506
|
-
result.meta = meta3;
|
|
32507
|
-
return result;
|
|
32508
|
-
}
|
|
32509
|
-
function findingsToReviewFindings(findings, opts = {}) {
|
|
32510
|
-
return findings.map((f) => findingToReviewFinding(f, opts));
|
|
32511
|
-
}
|
|
32512
32478
|
var SEVERITY_MAP, RULE_ID_SLUG_TOKENS = 6;
|
|
32513
32479
|
var init_finding_projection = __esm(() => {
|
|
32514
32480
|
SEVERITY_MAP = {
|
|
@@ -33716,6 +33682,35 @@ function acFailureToFinding(acId, output) {
|
|
|
33716
33682
|
fixTarget: "source"
|
|
33717
33683
|
};
|
|
33718
33684
|
}
|
|
33685
|
+
function executionFailureToFinding(params) {
|
|
33686
|
+
const tail = tailLines(params.output, 40);
|
|
33687
|
+
const exitStr = params.exitCode !== undefined ? ` (exit ${params.exitCode})` : "";
|
|
33688
|
+
const message = `Test runner exited non-zero without structured failures${exitStr}. Command: \`${params.command}\`
|
|
33689
|
+
|
|
33690
|
+
--- runner output (last 40 lines) ---
|
|
33691
|
+
${tail}`;
|
|
33692
|
+
return {
|
|
33693
|
+
source: "test-runner",
|
|
33694
|
+
severity: "error",
|
|
33695
|
+
category: "execution-failed",
|
|
33696
|
+
message,
|
|
33697
|
+
fixTarget: "source",
|
|
33698
|
+
meta: {
|
|
33699
|
+
command: params.command,
|
|
33700
|
+
exitCode: params.exitCode,
|
|
33701
|
+
packageDir: params.packageDir,
|
|
33702
|
+
cwd: params.cwd
|
|
33703
|
+
}
|
|
33704
|
+
};
|
|
33705
|
+
}
|
|
33706
|
+
function tailLines(s, n) {
|
|
33707
|
+
if (!s)
|
|
33708
|
+
return "(no output)";
|
|
33709
|
+
const lines = s.split(`
|
|
33710
|
+
`);
|
|
33711
|
+
return lines.slice(Math.max(0, lines.length - n)).join(`
|
|
33712
|
+
`);
|
|
33713
|
+
}
|
|
33719
33714
|
function acSentinelToFinding(sentinel, _output) {
|
|
33720
33715
|
if (sentinel === "AC-HOOK") {
|
|
33721
33716
|
return {
|
|
@@ -35612,7 +35607,9 @@ var init_autofix_implementer = __esm(() => {
|
|
|
35612
35607
|
session: { role: "implementer", lifetime: "warm" },
|
|
35613
35608
|
config: autofixConfigSelector,
|
|
35614
35609
|
build(input, _ctx) {
|
|
35615
|
-
const
|
|
35610
|
+
const verifierFindings = input.findings?.filter((f) => f.source === "tdd-verifier");
|
|
35611
|
+
const useVerifierContext = verifierFindings !== undefined && verifierFindings.length > 0 && verifierFindings.length === input.findings?.length;
|
|
35612
|
+
const prompt = useVerifierContext ? RectifierPromptBuilder.verifierContext(verifierFindings) : RectifierPromptBuilder.reviewRectification(input.failedChecks, input.story, {
|
|
35616
35613
|
blockingThreshold: input.blockingThreshold
|
|
35617
35614
|
});
|
|
35618
35615
|
return {
|
|
@@ -35840,6 +35837,29 @@ var init_debate_stateful = __esm(() => {
|
|
|
35840
35837
|
};
|
|
35841
35838
|
});
|
|
35842
35839
|
|
|
35840
|
+
// src/debate/selectors/judge.ts
|
|
35841
|
+
var RESOLVER_FALLBACK_AGENT = "synthesis", RESOLVER_FALLBACK_MODEL = "fast", judgeSelector = async (ctx) => {
|
|
35842
|
+
const resolverAgent = ctx.stageConfig.resolver.agent ?? RESOLVER_FALLBACK_AGENT;
|
|
35843
|
+
const resolverModel = ctx.stageConfig.resolver.model ?? RESOLVER_FALLBACK_MODEL;
|
|
35844
|
+
const proposals = ctx.proposals.map((p) => p.output);
|
|
35845
|
+
const output = await callOp(ctx.callContext, judgeOp, {
|
|
35846
|
+
proposals,
|
|
35847
|
+
critiques: ctx.critiques,
|
|
35848
|
+
debaters: ctx.debaters,
|
|
35849
|
+
resolverAgent,
|
|
35850
|
+
resolverModel,
|
|
35851
|
+
timeoutSeconds: ctx.stageConfig.timeoutSeconds
|
|
35852
|
+
});
|
|
35853
|
+
return {
|
|
35854
|
+
outcome: output.trim() ? "passed" : "failed",
|
|
35855
|
+
output
|
|
35856
|
+
};
|
|
35857
|
+
};
|
|
35858
|
+
var init_judge = __esm(() => {
|
|
35859
|
+
init_operations();
|
|
35860
|
+
init_operations();
|
|
35861
|
+
});
|
|
35862
|
+
|
|
35843
35863
|
// src/debate/selectors/majority.ts
|
|
35844
35864
|
function stripMarkdownFence(text) {
|
|
35845
35865
|
const match = text.match(/^```(?:json)?\s*\n?([\s\S]*?)\n?```\s*$/);
|
|
@@ -35881,125 +35901,6 @@ var majorityFailClosedSelector = async (ctx) => {
|
|
|
35881
35901
|
return { outcome: computeMajority(proposalOutputs, true) };
|
|
35882
35902
|
};
|
|
35883
35903
|
|
|
35884
|
-
// src/debate/resolvers.ts
|
|
35885
|
-
function majorityResolver(proposals, failOpen) {
|
|
35886
|
-
return computeMajority(proposals, failOpen);
|
|
35887
|
-
}
|
|
35888
|
-
var init_resolvers = __esm(() => {
|
|
35889
|
-
init_prompts();
|
|
35890
|
-
});
|
|
35891
|
-
|
|
35892
|
-
// src/debate/selectors/pick.ts
|
|
35893
|
-
function pickSelectorKind(stageConfig, ctx) {
|
|
35894
|
-
if (stageConfig.selector) {
|
|
35895
|
-
return stageConfig.selector.kind;
|
|
35896
|
-
}
|
|
35897
|
-
if (ctx.reviewerSession && ctx.resolverContextInput) {
|
|
35898
|
-
return "dialogue-verdict";
|
|
35899
|
-
}
|
|
35900
|
-
return pickBaseSelectorKind(stageConfig);
|
|
35901
|
-
}
|
|
35902
|
-
function pickBaseSelectorKind(stageConfig) {
|
|
35903
|
-
switch (stageConfig.resolver.type) {
|
|
35904
|
-
case "synthesis":
|
|
35905
|
-
return "synthesis";
|
|
35906
|
-
case "majority-fail-closed":
|
|
35907
|
-
return "majority-fail-closed";
|
|
35908
|
-
case "majority-fail-open":
|
|
35909
|
-
return "majority-fail-open";
|
|
35910
|
-
case "custom":
|
|
35911
|
-
return "judge";
|
|
35912
|
-
}
|
|
35913
|
-
return "synthesis";
|
|
35914
|
-
}
|
|
35915
|
-
|
|
35916
|
-
// src/debate/selectors/dialogue-verdict.ts
|
|
35917
|
-
var dialogueVerdictSelector = async (ctx) => {
|
|
35918
|
-
if (ctx.reviewerSession && ctx.resolverContextInput) {
|
|
35919
|
-
try {
|
|
35920
|
-
const debateCtx = {
|
|
35921
|
-
resolverType: ctx.stageConfig.resolver.type
|
|
35922
|
-
};
|
|
35923
|
-
if (ctx.stageConfig.resolver.type === "majority-fail-closed" || ctx.stageConfig.resolver.type === "majority-fail-open") {
|
|
35924
|
-
const failOpen = ctx.stageConfig.resolver.type === "majority-fail-open";
|
|
35925
|
-
const rawOutcome = majorityResolver(ctx.proposals.map((p) => p.output), failOpen);
|
|
35926
|
-
let passCount = 0;
|
|
35927
|
-
let failCount = 0;
|
|
35928
|
-
for (const proposal of ctx.proposals) {
|
|
35929
|
-
const parsed = tryParseLLMJson(proposal.output);
|
|
35930
|
-
if (parsed !== null && typeof parsed.passed === "boolean" && parsed.passed) {
|
|
35931
|
-
passCount++;
|
|
35932
|
-
} else if (failOpen) {
|
|
35933
|
-
passCount++;
|
|
35934
|
-
} else {
|
|
35935
|
-
failCount++;
|
|
35936
|
-
}
|
|
35937
|
-
}
|
|
35938
|
-
debateCtx.majorityVote = { passed: rawOutcome === "passed", passCount, failCount };
|
|
35939
|
-
}
|
|
35940
|
-
const story = {
|
|
35941
|
-
id: ctx.resolverContextInput.story.id,
|
|
35942
|
-
title: ctx.resolverContextInput.story.title,
|
|
35943
|
-
description: "",
|
|
35944
|
-
acceptanceCriteria: ctx.resolverContextInput.story.acceptanceCriteria
|
|
35945
|
-
};
|
|
35946
|
-
const rcRecord = ctx.resolverContextInput;
|
|
35947
|
-
const diffContext = ctx.resolverContextInput.diffMode === "ref" ? {
|
|
35948
|
-
mode: "ref",
|
|
35949
|
-
storyGitRef: rcRecord.storyGitRef ?? "",
|
|
35950
|
-
stat: rcRecord.stat ?? undefined,
|
|
35951
|
-
productionExcludePatterns: rcRecord.productionExcludePatterns
|
|
35952
|
-
} : { mode: "embedded", diff: rcRecord.diff ?? "" };
|
|
35953
|
-
const labeledProposals = ctx.labeledProposals ?? ctx.proposals.map((p) => ({
|
|
35954
|
-
debater: p.debater.agent,
|
|
35955
|
-
output: p.output
|
|
35956
|
-
}));
|
|
35957
|
-
let dialogueResult;
|
|
35958
|
-
if (ctx.resolverContextInput.isReReview) {
|
|
35959
|
-
dialogueResult = await ctx.reviewerSession.reReviewDebate(labeledProposals, ctx.critiques, diffContext, debateCtx);
|
|
35960
|
-
} else {
|
|
35961
|
-
dialogueResult = await ctx.reviewerSession.resolveDebate(labeledProposals, ctx.critiques, diffContext, story, ctx.resolverContextInput.semanticConfig, debateCtx);
|
|
35962
|
-
}
|
|
35963
|
-
const outcome = dialogueResult.checkResult.success ? "passed" : "failed";
|
|
35964
|
-
return {
|
|
35965
|
-
outcome,
|
|
35966
|
-
findings: dialogueResult.checkResult.findings,
|
|
35967
|
-
dialogueResult
|
|
35968
|
-
};
|
|
35969
|
-
} catch {}
|
|
35970
|
-
}
|
|
35971
|
-
const baseKind = pickBaseSelectorKind(ctx.stageConfig);
|
|
35972
|
-
const baseSelector = resolveSelector(baseKind);
|
|
35973
|
-
return baseSelector(ctx);
|
|
35974
|
-
};
|
|
35975
|
-
var init_dialogue_verdict = __esm(() => {
|
|
35976
|
-
init_resolvers();
|
|
35977
|
-
init_registry2();
|
|
35978
|
-
});
|
|
35979
|
-
|
|
35980
|
-
// src/debate/selectors/judge.ts
|
|
35981
|
-
var RESOLVER_FALLBACK_AGENT = "synthesis", RESOLVER_FALLBACK_MODEL = "fast", judgeSelector = async (ctx) => {
|
|
35982
|
-
const resolverAgent = ctx.stageConfig.resolver.agent ?? RESOLVER_FALLBACK_AGENT;
|
|
35983
|
-
const resolverModel = ctx.stageConfig.resolver.model ?? RESOLVER_FALLBACK_MODEL;
|
|
35984
|
-
const proposals = ctx.proposals.map((p) => p.output);
|
|
35985
|
-
const output = await callOp(ctx.callContext, judgeOp, {
|
|
35986
|
-
proposals,
|
|
35987
|
-
critiques: ctx.critiques,
|
|
35988
|
-
debaters: ctx.debaters,
|
|
35989
|
-
resolverAgent,
|
|
35990
|
-
resolverModel,
|
|
35991
|
-
timeoutSeconds: ctx.stageConfig.timeoutSeconds
|
|
35992
|
-
});
|
|
35993
|
-
return {
|
|
35994
|
-
outcome: output.trim() ? "passed" : "failed",
|
|
35995
|
-
output
|
|
35996
|
-
};
|
|
35997
|
-
};
|
|
35998
|
-
var init_judge = __esm(() => {
|
|
35999
|
-
init_operations();
|
|
36000
|
-
init_operations();
|
|
36001
|
-
});
|
|
36002
|
-
|
|
36003
35904
|
// src/debate/selectors/synthesis.ts
|
|
36004
35905
|
var RESOLVER_FALLBACK_AGENT2 = "synthesis", RESOLVER_FALLBACK_MODEL2 = "fast", synthesisSelector = async (ctx) => {
|
|
36005
35906
|
const resolverAgent = ctx.stageConfig.resolver.agent ?? RESOLVER_FALLBACK_AGENT2;
|
|
@@ -36176,7 +36077,6 @@ function registerSelector(kind, strategy) {
|
|
|
36176
36077
|
var STRATEGIES;
|
|
36177
36078
|
var init_registry2 = __esm(() => {
|
|
36178
36079
|
init_errors();
|
|
36179
|
-
init_dialogue_verdict();
|
|
36180
36080
|
init_judge();
|
|
36181
36081
|
init_synthesis();
|
|
36182
36082
|
init_verifier_pick();
|
|
@@ -36185,16 +36085,34 @@ var init_registry2 = __esm(() => {
|
|
|
36185
36085
|
registerSelector("majority-fail-closed", majorityFailClosedSelector);
|
|
36186
36086
|
registerSelector("majority-fail-open", majorityFailOpenSelector);
|
|
36187
36087
|
registerSelector("judge", judgeSelector);
|
|
36188
|
-
registerSelector("dialogue-verdict", dialogueVerdictSelector);
|
|
36189
36088
|
registerSelector("verifier-pick", (ctx) => verifierPickSelector(ctx));
|
|
36190
36089
|
});
|
|
36191
36090
|
|
|
36091
|
+
// src/debate/selectors/pick.ts
|
|
36092
|
+
function pickSelectorKind(stageConfig) {
|
|
36093
|
+
if (stageConfig.selector) {
|
|
36094
|
+
return stageConfig.selector.kind;
|
|
36095
|
+
}
|
|
36096
|
+
return pickBaseSelectorKind(stageConfig);
|
|
36097
|
+
}
|
|
36098
|
+
function pickBaseSelectorKind(stageConfig) {
|
|
36099
|
+
switch (stageConfig.resolver.type) {
|
|
36100
|
+
case "synthesis":
|
|
36101
|
+
return "synthesis";
|
|
36102
|
+
case "majority-fail-closed":
|
|
36103
|
+
return "majority-fail-closed";
|
|
36104
|
+
case "majority-fail-open":
|
|
36105
|
+
return "majority-fail-open";
|
|
36106
|
+
case "custom":
|
|
36107
|
+
return "judge";
|
|
36108
|
+
}
|
|
36109
|
+
}
|
|
36110
|
+
|
|
36192
36111
|
// src/debate/selectors/index.ts
|
|
36193
36112
|
var init_selectors2 = __esm(() => {
|
|
36194
36113
|
init_registry2();
|
|
36195
36114
|
init_synthesis();
|
|
36196
36115
|
init_judge();
|
|
36197
|
-
init_dialogue_verdict();
|
|
36198
36116
|
init_verifier_pick();
|
|
36199
36117
|
});
|
|
36200
36118
|
|
|
@@ -36222,14 +36140,10 @@ function buildResolverCallContext(provided, agentManager, storyId, workdir, feat
|
|
|
36222
36140
|
...sessionOverride !== undefined ? { sessionOverride } : {}
|
|
36223
36141
|
};
|
|
36224
36142
|
}
|
|
36225
|
-
async function resolveOutcome(proposalOutputs, critiqueOutputs, stageConfig, config2, callContext, storyId, timeoutMs, workdir, featureName,
|
|
36143
|
+
async function resolveOutcome(proposalOutputs, critiqueOutputs, stageConfig, config2, callContext, storyId, timeoutMs, workdir, featureName, promptSuffix, debaters, agentManager) {
|
|
36226
36144
|
const logger = _debateSessionDeps.getSafeLogger();
|
|
36227
|
-
|
|
36228
|
-
|
|
36229
|
-
}
|
|
36230
|
-
const resolverContextInput = resolverContext ? (({ labeledProposals: _lp, ...rest }) => rest)(resolverContext) : undefined;
|
|
36231
|
-
const kind = pickSelectorKind(stageConfig, { reviewerSession, resolverContextInput });
|
|
36232
|
-
if ((kind === "majority-fail-closed" || kind === "majority-fail-open") && workdir !== undefined && !reviewerSession) {
|
|
36145
|
+
const kind = pickSelectorKind(stageConfig);
|
|
36146
|
+
if ((kind === "majority-fail-closed" || kind === "majority-fail-open") && workdir !== undefined) {
|
|
36233
36147
|
logger?.warn("debate", "majority resolver does not support implementer session resumption \u2014 switch to synthesis or custom resolver for context-aware semantic review");
|
|
36234
36148
|
}
|
|
36235
36149
|
const proposalList = debaters ? debaters.map((debater, i) => ({
|
|
@@ -36256,48 +36170,20 @@ async function resolveOutcome(proposalOutputs, critiqueOutputs, stageConfig, con
|
|
|
36256
36170
|
stageConfig,
|
|
36257
36171
|
config: effectiveConfig,
|
|
36258
36172
|
proposals: proposalList,
|
|
36259
|
-
labeledProposals: resolverContext?.labeledProposals,
|
|
36260
36173
|
critiques: critiqueOutputs,
|
|
36261
36174
|
workdir: workdir ?? "",
|
|
36262
36175
|
featureName: featureName ?? "",
|
|
36263
36176
|
timeoutMs,
|
|
36264
36177
|
agentManager: effectiveAgentManager,
|
|
36265
|
-
reviewerSession,
|
|
36266
|
-
resolverContextInput,
|
|
36267
36178
|
promptSuffix,
|
|
36268
36179
|
debaters: debaters ?? [],
|
|
36269
36180
|
callContext: effectiveCallContext
|
|
36270
36181
|
};
|
|
36271
|
-
const resolverTypeMappedKind = pickBaseSelectorKind(stageConfig);
|
|
36272
|
-
if (kind === "dialogue-verdict") {
|
|
36273
|
-
try {
|
|
36274
|
-
const result2 = await resolveSelector(kind)(selectorCtx);
|
|
36275
|
-
return {
|
|
36276
|
-
outcome: result2.outcome,
|
|
36277
|
-
output: result2.output,
|
|
36278
|
-
findings: result2.findings,
|
|
36279
|
-
dialogueResult: result2.dialogueResult
|
|
36280
|
-
};
|
|
36281
|
-
} catch (err) {
|
|
36282
|
-
logger?.warn("debate", "dialogue-verdict selector failed, falling back to stateless", {
|
|
36283
|
-
storyId,
|
|
36284
|
-
error: err instanceof Error ? err.message : String(err)
|
|
36285
|
-
});
|
|
36286
|
-
const fallbackResult = await resolveSelector(resolverTypeMappedKind)(selectorCtx);
|
|
36287
|
-
return {
|
|
36288
|
-
outcome: fallbackResult.outcome,
|
|
36289
|
-
output: fallbackResult.output,
|
|
36290
|
-
findings: fallbackResult.findings,
|
|
36291
|
-
dialogueResult: fallbackResult.dialogueResult
|
|
36292
|
-
};
|
|
36293
|
-
}
|
|
36294
|
-
}
|
|
36295
36182
|
const result = await resolveSelector(kind)(selectorCtx);
|
|
36296
36183
|
return {
|
|
36297
36184
|
outcome: result.outcome,
|
|
36298
36185
|
output: result.output,
|
|
36299
|
-
findings: result.findings
|
|
36300
|
-
dialogueResult: result.dialogueResult
|
|
36186
|
+
findings: result.findings
|
|
36301
36187
|
};
|
|
36302
36188
|
}
|
|
36303
36189
|
var RESOLVER_FALLBACK_AGENT3 = "synthesis", _debateSessionDeps;
|
|
@@ -36937,6 +36823,46 @@ var init_verdict = __esm(() => {
|
|
|
36937
36823
|
});
|
|
36938
36824
|
|
|
36939
36825
|
// src/operations/verify.ts
|
|
36826
|
+
function buildVerifierFindings(verdict, categorization) {
|
|
36827
|
+
if (categorization.success)
|
|
36828
|
+
return [];
|
|
36829
|
+
switch (categorization.failureCategory) {
|
|
36830
|
+
case "verifier-rejected": {
|
|
36831
|
+
const files = verdict.testModifications.files;
|
|
36832
|
+
return [
|
|
36833
|
+
{
|
|
36834
|
+
source: "tdd-verifier",
|
|
36835
|
+
severity: "error",
|
|
36836
|
+
category: "illegitimate-test-edits",
|
|
36837
|
+
fixTarget: "test",
|
|
36838
|
+
message: files.length > 0 ? `Implementer edited test files illegitimately: ${files.join(", ")}` : "Implementer made illegitimate test modifications",
|
|
36839
|
+
meta: {
|
|
36840
|
+
reasoning: verdict.testModifications.reasoning,
|
|
36841
|
+
files
|
|
36842
|
+
}
|
|
36843
|
+
}
|
|
36844
|
+
];
|
|
36845
|
+
}
|
|
36846
|
+
case "tests-failing": {
|
|
36847
|
+
return [
|
|
36848
|
+
{
|
|
36849
|
+
source: "tdd-verifier",
|
|
36850
|
+
severity: "error",
|
|
36851
|
+
category: "tests-failed",
|
|
36852
|
+
fixTarget: "source",
|
|
36853
|
+
message: `${verdict.tests.failCount} story-scoped test(s) failed (verifier)`,
|
|
36854
|
+
meta: {
|
|
36855
|
+
passCount: verdict.tests.passCount,
|
|
36856
|
+
failCount: verdict.tests.failCount,
|
|
36857
|
+
reasoning: verdict.reasoning
|
|
36858
|
+
}
|
|
36859
|
+
}
|
|
36860
|
+
];
|
|
36861
|
+
}
|
|
36862
|
+
default:
|
|
36863
|
+
return [];
|
|
36864
|
+
}
|
|
36865
|
+
}
|
|
36940
36866
|
function parseVerdictFromStdout(output, _input, _ctx) {
|
|
36941
36867
|
if (!output || !output.trim()) {
|
|
36942
36868
|
throw new ParseValidationError("verifier produced no stdout");
|
|
@@ -36956,6 +36882,7 @@ function parseVerdictFromStdout(output, _input, _ctx) {
|
|
|
36956
36882
|
estimatedCostUsd: 0,
|
|
36957
36883
|
durationMs: 0,
|
|
36958
36884
|
output,
|
|
36885
|
+
normalizedFindings: buildVerifierFindings(verdict, categorization),
|
|
36959
36886
|
...categorization.failureCategory && { failureCategory: categorization.failureCategory },
|
|
36960
36887
|
...categorization.reviewReason && { reviewReason: categorization.reviewReason }
|
|
36961
36888
|
};
|
|
@@ -37028,6 +36955,7 @@ var init_verify = __esm(() => {
|
|
|
37028
36955
|
estimatedCostUsd: 0,
|
|
37029
36956
|
durationMs: 0,
|
|
37030
36957
|
output: "",
|
|
36958
|
+
normalizedFindings: buildVerifierFindings(verdict, categorization),
|
|
37031
36959
|
...categorization.failureCategory && { failureCategory: categorization.failureCategory },
|
|
37032
36960
|
...categorization.reviewReason && { reviewReason: categorization.reviewReason },
|
|
37033
36961
|
...isolation && { isolation }
|
|
@@ -37039,6 +36967,7 @@ var init_verify = __esm(() => {
|
|
|
37039
36967
|
estimatedCostUsd: 0,
|
|
37040
36968
|
durationMs: 0,
|
|
37041
36969
|
output: "",
|
|
36970
|
+
normalizedFindings: [],
|
|
37042
36971
|
reviewReason: "verifier produced unparseable verdict in stdout after retries and no usable verdict file on disk"
|
|
37043
36972
|
};
|
|
37044
36973
|
} finally {
|
|
@@ -37792,7 +37721,9 @@ async function runVerificationCore(options) {
|
|
|
37792
37721
|
success: options.acceptOnTimeout ?? false,
|
|
37793
37722
|
countsTowardEscalation: false,
|
|
37794
37723
|
error: execution.error,
|
|
37795
|
-
output: execution.output
|
|
37724
|
+
output: execution.output,
|
|
37725
|
+
exitCode: execution.exitCode,
|
|
37726
|
+
command: finalCommand
|
|
37796
37727
|
};
|
|
37797
37728
|
}
|
|
37798
37729
|
const exitCode = execution.exitCode ?? 1;
|
|
@@ -37806,7 +37737,9 @@ async function runVerificationCore(options) {
|
|
|
37806
37737
|
error: analysis.error,
|
|
37807
37738
|
output: execution.output,
|
|
37808
37739
|
passCount: analysis.passCount,
|
|
37809
|
-
failCount: analysis.failCount
|
|
37740
|
+
failCount: analysis.failCount,
|
|
37741
|
+
exitCode,
|
|
37742
|
+
command: finalCommand
|
|
37810
37743
|
};
|
|
37811
37744
|
}
|
|
37812
37745
|
return {
|
|
@@ -37815,10 +37748,19 @@ async function runVerificationCore(options) {
|
|
|
37815
37748
|
countsTowardEscalation: true,
|
|
37816
37749
|
output: execution.output,
|
|
37817
37750
|
passCount: analysis.passCount,
|
|
37818
|
-
failCount: analysis.failCount
|
|
37751
|
+
failCount: analysis.failCount,
|
|
37752
|
+
exitCode,
|
|
37753
|
+
command: finalCommand
|
|
37819
37754
|
};
|
|
37820
37755
|
}
|
|
37821
|
-
return {
|
|
37756
|
+
return {
|
|
37757
|
+
status: "SUCCESS",
|
|
37758
|
+
success: true,
|
|
37759
|
+
countsTowardEscalation: true,
|
|
37760
|
+
output: execution.output,
|
|
37761
|
+
exitCode,
|
|
37762
|
+
command: finalCommand
|
|
37763
|
+
};
|
|
37822
37764
|
}
|
|
37823
37765
|
async function fullSuite(options) {
|
|
37824
37766
|
return runVerificationCore(options);
|
|
@@ -37895,7 +37837,9 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37895
37837
|
failed: parsedSummary.failed ?? 0,
|
|
37896
37838
|
output: result.output ?? "",
|
|
37897
37839
|
parsedSummary,
|
|
37898
|
-
timedOut: result.status === "TIMEOUT"
|
|
37840
|
+
timedOut: result.status === "TIMEOUT",
|
|
37841
|
+
exitCode: result.exitCode,
|
|
37842
|
+
command: result.command ?? gateCtx.testCmd
|
|
37899
37843
|
};
|
|
37900
37844
|
}
|
|
37901
37845
|
};
|
|
@@ -37922,6 +37866,13 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37922
37866
|
};
|
|
37923
37867
|
}
|
|
37924
37868
|
const gateCtx = await deps.resolveGateContext(input, ctx);
|
|
37869
|
+
logger.info("verify[regression]", "Running full-suite gate", {
|
|
37870
|
+
storyId: input.story.id,
|
|
37871
|
+
packageDir: input.story.workdir,
|
|
37872
|
+
cwd: input.workdir,
|
|
37873
|
+
command: gateCtx.testCmd,
|
|
37874
|
+
timeoutSeconds: gateCtx.fullSuiteTimeout
|
|
37875
|
+
});
|
|
37925
37876
|
const testResult = await deps.runTests(input, gateCtx);
|
|
37926
37877
|
if (testResult.passed) {
|
|
37927
37878
|
return { success: true, passed: true, status: "passed", estimatedCostUsd: 0, attempts: 0, findings: [] };
|
|
@@ -37955,13 +37906,27 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37955
37906
|
}
|
|
37956
37907
|
const findings = testSummaryToFindings(testResult.parsedSummary);
|
|
37957
37908
|
if (findings.length === 0) {
|
|
37909
|
+
const cmd = testResult.command ?? gateCtx.testCmd;
|
|
37910
|
+
const synth = executionFailureToFinding({
|
|
37911
|
+
command: cmd,
|
|
37912
|
+
exitCode: testResult.exitCode,
|
|
37913
|
+
output: testResult.output,
|
|
37914
|
+
packageDir: input.story.workdir,
|
|
37915
|
+
cwd: input.workdir
|
|
37916
|
+
});
|
|
37917
|
+
logger.warn("verify[regression]", "Full-suite gate execution-failed \u2014 emitting synth finding", {
|
|
37918
|
+
storyId: input.story.id,
|
|
37919
|
+
command: cmd,
|
|
37920
|
+
exitCode: testResult.exitCode,
|
|
37921
|
+
packageDir: input.story.workdir
|
|
37922
|
+
});
|
|
37958
37923
|
return {
|
|
37959
37924
|
success: false,
|
|
37960
37925
|
passed: false,
|
|
37961
37926
|
status: "execution-failed",
|
|
37962
37927
|
estimatedCostUsd: 0,
|
|
37963
37928
|
attempts: 0,
|
|
37964
|
-
findings: []
|
|
37929
|
+
findings: [synth]
|
|
37965
37930
|
};
|
|
37966
37931
|
}
|
|
37967
37932
|
return { success: false, passed: false, status: "failed", estimatedCostUsd: 0, attempts: 0, findings };
|
|
@@ -37973,7 +37938,7 @@ var init_full_suite_gate = __esm(() => {
|
|
|
37973
37938
|
function makeFullSuiteRectifyStrategy(story, config2) {
|
|
37974
37939
|
return {
|
|
37975
37940
|
name: "full-suite-rectify",
|
|
37976
|
-
appliesTo: (finding) => finding.source === "test-runner" && finding.category === "failed-test",
|
|
37941
|
+
appliesTo: (finding) => finding.source === "test-runner" && (finding.category === "failed-test" || finding.category === "execution-failed"),
|
|
37977
37942
|
fixOp: implementerOp,
|
|
37978
37943
|
buildInput: (findings) => ({
|
|
37979
37944
|
story,
|
|
@@ -38016,7 +37981,8 @@ var init__finding_to_check = __esm(() => {
|
|
|
38016
37981
|
"semantic-review": "semantic",
|
|
38017
37982
|
"adversarial-review": "adversarial",
|
|
38018
37983
|
lint: "lint",
|
|
38019
|
-
typecheck: "typecheck"
|
|
37984
|
+
typecheck: "typecheck",
|
|
37985
|
+
"tdd-verifier": "test"
|
|
38020
37986
|
};
|
|
38021
37987
|
});
|
|
38022
37988
|
|
|
@@ -38028,7 +37994,8 @@ function makeAutofixImplementerStrategy(story, config2, sink) {
|
|
|
38028
37994
|
fixOp: implementerRectifyOp,
|
|
38029
37995
|
buildInput: (findings, _prior, _cycleCtx) => ({
|
|
38030
37996
|
failedChecks: findingsToFailedChecks(findings),
|
|
38031
|
-
story
|
|
37997
|
+
story,
|
|
37998
|
+
findings
|
|
38032
37999
|
}),
|
|
38033
38000
|
extractApplied: (output) => {
|
|
38034
38001
|
for (const decl of output.testEditDeclarations) {
|
|
@@ -38051,7 +38018,7 @@ var IMPLEMENTER_SOURCES;
|
|
|
38051
38018
|
var init_autofix_implementer_strategy = __esm(() => {
|
|
38052
38019
|
init__finding_to_check();
|
|
38053
38020
|
init_autofix_implementer();
|
|
38054
|
-
IMPLEMENTER_SOURCES = new Set(["lint", "typecheck", "semantic-review"]);
|
|
38021
|
+
IMPLEMENTER_SOURCES = new Set(["lint", "typecheck", "semantic-review", "tdd-verifier"]);
|
|
38055
38022
|
});
|
|
38056
38023
|
|
|
38057
38024
|
// src/operations/autofix-test-writer-strategy.ts
|
|
@@ -38665,6 +38632,15 @@ var init_verify_scoped = __esm(() => {
|
|
|
38665
38632
|
command: selection.effectiveCommand
|
|
38666
38633
|
});
|
|
38667
38634
|
}
|
|
38635
|
+
const scopedTimeout = ctxConfig.execution?.regressionGate?.timeoutSeconds ?? 600;
|
|
38636
|
+
logger.info("verify[scoped]", "Running scoped tests", {
|
|
38637
|
+
storyId: input.storyId,
|
|
38638
|
+
packageDir: input.packageDir,
|
|
38639
|
+
cwd: input.workdir,
|
|
38640
|
+
command: selection.effectiveCommand,
|
|
38641
|
+
timeoutSeconds: scopedTimeout,
|
|
38642
|
+
isFullSuite: selection.isFullSuite
|
|
38643
|
+
});
|
|
38668
38644
|
const start = Date.now();
|
|
38669
38645
|
const result = await deps.regression({
|
|
38670
38646
|
workdir: input.workdir,
|
|
@@ -38785,6 +38761,9 @@ var init_operations = __esm(() => {
|
|
|
38785
38761
|
});
|
|
38786
38762
|
|
|
38787
38763
|
// src/findings/cycle.ts
|
|
38764
|
+
function normalizeValidateResult(r) {
|
|
38765
|
+
return Array.isArray(r) ? { findings: r, shortCircuited: false } : r;
|
|
38766
|
+
}
|
|
38788
38767
|
function classifySingleSource(before, after) {
|
|
38789
38768
|
const beforeKeys = new Set(before.map(findingKey));
|
|
38790
38769
|
const afterKeys = new Set(after.map(findingKey));
|
|
@@ -38981,11 +38960,12 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
|
|
|
38981
38960
|
});
|
|
38982
38961
|
if (allExhausted) {
|
|
38983
38962
|
let liteFindingsAfter;
|
|
38963
|
+
let liteShortCircuited = false;
|
|
38984
38964
|
try {
|
|
38985
|
-
|
|
38986
|
-
|
|
38987
|
-
|
|
38988
|
-
|
|
38965
|
+
const liteRaw = await cycle.validate(ctx, { mode: "lite", strategiesRun: group.map((s) => s.name) });
|
|
38966
|
+
const liteResult = normalizeValidateResult(liteRaw);
|
|
38967
|
+
liteFindingsAfter = liteResult.findings;
|
|
38968
|
+
liteShortCircuited = liteResult.shortCircuited ?? false;
|
|
38989
38969
|
} catch (err) {
|
|
38990
38970
|
const finishedAt3 = now();
|
|
38991
38971
|
cycle.iterations.push({
|
|
@@ -39023,7 +39003,7 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
|
|
|
39023
39003
|
finishedAt: finishedAt2
|
|
39024
39004
|
});
|
|
39025
39005
|
cycle.findings = liteFindingsAfter;
|
|
39026
|
-
if (liteFindingsAfter.length === 0) {
|
|
39006
|
+
if (liteFindingsAfter.length === 0 && !liteShortCircuited) {
|
|
39027
39007
|
logger?.info("findings.cycle", "cycle exited \u2014 resolved after terminal lite validate", {
|
|
39028
39008
|
storyId,
|
|
39029
39009
|
packageDir,
|
|
@@ -39037,6 +39017,21 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
|
|
|
39037
39017
|
costUsd: totalCostUsd
|
|
39038
39018
|
};
|
|
39039
39019
|
}
|
|
39020
|
+
if (liteShortCircuited) {
|
|
39021
|
+
logger?.info("findings.cycle", "cycle exited \u2014 validate short-circuited", {
|
|
39022
|
+
storyId,
|
|
39023
|
+
packageDir,
|
|
39024
|
+
cycleName,
|
|
39025
|
+
reason: "validate-short-circuit",
|
|
39026
|
+
liteFindingsAfterCount: liteFindingsAfter.length
|
|
39027
|
+
});
|
|
39028
|
+
return {
|
|
39029
|
+
iterations: cycle.iterations,
|
|
39030
|
+
finalFindings: liteFindingsAfter,
|
|
39031
|
+
exitReason: "validate-short-circuit",
|
|
39032
|
+
costUsd: totalCostUsd
|
|
39033
|
+
};
|
|
39034
|
+
}
|
|
39040
39035
|
logger?.info("findings.cycle", "cycle exited \u2014 strategy attempt cap reached (lite validate)", {
|
|
39041
39036
|
storyId,
|
|
39042
39037
|
packageDir,
|
|
@@ -39057,7 +39052,8 @@ async function runFixCycle(cycle, ctx, cycleName, _deps = {}) {
|
|
|
39057
39052
|
let validatorAttempt = 0;
|
|
39058
39053
|
for (;; ) {
|
|
39059
39054
|
try {
|
|
39060
|
-
|
|
39055
|
+
const fullRaw = await cycle.validate(ctx, { mode: "full", strategiesRun: group.map((s) => s.name) });
|
|
39056
|
+
findingsAfter = normalizeValidateResult(fullRaw).findings;
|
|
39061
39057
|
break;
|
|
39062
39058
|
} catch (err) {
|
|
39063
39059
|
if (validatorAttempt >= cycle.config.validatorRetries) {
|
|
@@ -39701,7 +39697,6 @@ async function runSemanticDebate(opts) {
|
|
|
39701
39697
|
agentManager,
|
|
39702
39698
|
featureName,
|
|
39703
39699
|
story,
|
|
39704
|
-
resolverSession,
|
|
39705
39700
|
diffMode,
|
|
39706
39701
|
diff,
|
|
39707
39702
|
stat,
|
|
@@ -39719,10 +39714,9 @@ async function runSemanticDebate(opts) {
|
|
|
39719
39714
|
...configuredStageConfig,
|
|
39720
39715
|
sessionMode: "one-shot",
|
|
39721
39716
|
mode: "panel",
|
|
39722
|
-
selector: { kind:
|
|
39717
|
+
selector: { kind: pickBaseSelectorKind(configuredStageConfig) },
|
|
39723
39718
|
postDebateVerifier: { kind: "review-grounding-filter" }
|
|
39724
39719
|
};
|
|
39725
|
-
const isReReview = resolverSession !== undefined && resolverSession.history.length > 0;
|
|
39726
39720
|
const semanticAgentName = agentManager && typeof agentManager.getDefault === "function" ? agentManager.getDefault() : "claude";
|
|
39727
39721
|
const semanticCallCtx = {
|
|
39728
39722
|
runtime,
|
|
@@ -39739,89 +39733,10 @@ async function runSemanticDebate(opts) {
|
|
|
39739
39733
|
config: naxConfig,
|
|
39740
39734
|
workdir,
|
|
39741
39735
|
featureName,
|
|
39742
|
-
timeoutSeconds: naxConfig.execution?.sessionTimeoutSeconds
|
|
39743
|
-
reviewerSession: resolverSession,
|
|
39744
|
-
resolverContextInput: resolverSession ? {
|
|
39745
|
-
diffMode,
|
|
39746
|
-
...diffMode === "ref" ? { storyGitRef: effectiveRef, stat, productionExcludePatterns } : { diff },
|
|
39747
|
-
story: { id: story.id, title: story.title, acceptanceCriteria: story.acceptanceCriteria },
|
|
39748
|
-
semanticConfig,
|
|
39749
|
-
blockingThreshold,
|
|
39750
|
-
resolverType: reviewStageConfig.resolver.type,
|
|
39751
|
-
isReReview
|
|
39752
|
-
} : undefined
|
|
39736
|
+
timeoutSeconds: naxConfig.execution?.sessionTimeoutSeconds
|
|
39753
39737
|
});
|
|
39754
|
-
const historyLenBefore = resolverSession?.history.length ?? 0;
|
|
39755
39738
|
const debateResult = await debateRunner.run(prompt);
|
|
39756
39739
|
const debateCost = debateResult.totalCostUsd ?? 0;
|
|
39757
|
-
const sessionUsed = resolverSession && resolverSession.history.length > historyLenBefore;
|
|
39758
|
-
if (sessionUsed) {
|
|
39759
|
-
const durationMs2 = Date.now() - startTime;
|
|
39760
|
-
try {
|
|
39761
|
-
const verdict = resolverSession.getVerdict();
|
|
39762
|
-
const findings = verdict.findings ?? [];
|
|
39763
|
-
if (!verdict.passed && findings.length > 0) {
|
|
39764
|
-
logger?.warn("review", `Semantic review failed (debate+dialogue): ${findings.length} findings`, {
|
|
39765
|
-
storyId: story.id,
|
|
39766
|
-
durationMs: durationMs2
|
|
39767
|
-
});
|
|
39768
|
-
recordSemanticDebateAudit({
|
|
39769
|
-
runtime,
|
|
39770
|
-
workdir,
|
|
39771
|
-
storyId: story.id,
|
|
39772
|
-
featureName,
|
|
39773
|
-
parsed: true,
|
|
39774
|
-
passed: false,
|
|
39775
|
-
blockingThreshold,
|
|
39776
|
-
result: {
|
|
39777
|
-
passed: false,
|
|
39778
|
-
findings: findingsToReviewFindings(findings, { source: "semantic-debate-review" })
|
|
39779
|
-
}
|
|
39780
|
-
});
|
|
39781
|
-
return {
|
|
39782
|
-
check: "semantic",
|
|
39783
|
-
success: false,
|
|
39784
|
-
command: "",
|
|
39785
|
-
exitCode: 1,
|
|
39786
|
-
output: `Semantic review failed:
|
|
39787
|
-
|
|
39788
|
-
${findings.map((f) => `${f.rule ?? "semantic"}: ${f.message}`).join(`
|
|
39789
|
-
`)}`,
|
|
39790
|
-
durationMs: durationMs2,
|
|
39791
|
-
findings,
|
|
39792
|
-
cost: debateCost
|
|
39793
|
-
};
|
|
39794
|
-
}
|
|
39795
|
-
const label = verdict.passed ? "Semantic review passed (debate+dialogue)" : "Semantic review passed (debate+dialogue, all findings non-blocking)";
|
|
39796
|
-
logger?.info("review", label, { storyId: story.id, durationMs: durationMs2 });
|
|
39797
|
-
recordSemanticDebateAudit({
|
|
39798
|
-
runtime,
|
|
39799
|
-
workdir,
|
|
39800
|
-
storyId: story.id,
|
|
39801
|
-
featureName,
|
|
39802
|
-
parsed: true,
|
|
39803
|
-
passed: true,
|
|
39804
|
-
blockingThreshold,
|
|
39805
|
-
result: {
|
|
39806
|
-
passed: true,
|
|
39807
|
-
findings: findingsToReviewFindings(findings, { source: "semantic-debate-review" })
|
|
39808
|
-
}
|
|
39809
|
-
});
|
|
39810
|
-
return {
|
|
39811
|
-
check: "semantic",
|
|
39812
|
-
success: true,
|
|
39813
|
-
command: "",
|
|
39814
|
-
exitCode: 0,
|
|
39815
|
-
output: label,
|
|
39816
|
-
durationMs: durationMs2,
|
|
39817
|
-
cost: debateCost
|
|
39818
|
-
};
|
|
39819
|
-
} catch {
|
|
39820
|
-
logger?.warn("review", "getVerdict() failed after debate+dialogue \u2014 falling back to stateless verdict", {
|
|
39821
|
-
storyId: story.id
|
|
39822
|
-
});
|
|
39823
|
-
}
|
|
39824
|
-
}
|
|
39825
39740
|
const resolverPassed = debateResult.outcome === "passed";
|
|
39826
39741
|
const allFindings = [];
|
|
39827
39742
|
for (const p of debateResult.proposals) {
|
|
@@ -39941,6 +39856,7 @@ ${formatFindings2(debateBlocking)}`,
|
|
|
39941
39856
|
};
|
|
39942
39857
|
}
|
|
39943
39858
|
var init_semantic_debate = __esm(() => {
|
|
39859
|
+
init_debate();
|
|
39944
39860
|
init_logger2();
|
|
39945
39861
|
init_ac_quote_validator();
|
|
39946
39862
|
init_finding_projection();
|
|
@@ -39975,7 +39891,6 @@ async function runSemanticReview(opts) {
|
|
|
39975
39891
|
agentManager,
|
|
39976
39892
|
naxConfig,
|
|
39977
39893
|
featureName,
|
|
39978
|
-
resolverSession,
|
|
39979
39894
|
priorSemanticIterations,
|
|
39980
39895
|
blockingThreshold,
|
|
39981
39896
|
featureContextMarkdown,
|
|
@@ -40109,7 +40024,6 @@ async function runSemanticReview(opts) {
|
|
|
40109
40024
|
agentManager: effectiveAgentManager,
|
|
40110
40025
|
featureName,
|
|
40111
40026
|
story,
|
|
40112
|
-
resolverSession,
|
|
40113
40027
|
diffMode,
|
|
40114
40028
|
diff,
|
|
40115
40029
|
stat,
|
|
@@ -40476,7 +40390,6 @@ async function runReview(opts) {
|
|
|
40476
40390
|
naxConfig,
|
|
40477
40391
|
retrySkipChecks,
|
|
40478
40392
|
featureName,
|
|
40479
|
-
resolverSession,
|
|
40480
40393
|
priorFailures,
|
|
40481
40394
|
priorSemanticIterations,
|
|
40482
40395
|
featureContextMarkdown,
|
|
@@ -40556,7 +40469,6 @@ async function runReview(opts) {
|
|
|
40556
40469
|
agentManager,
|
|
40557
40470
|
naxConfig,
|
|
40558
40471
|
featureName,
|
|
40559
|
-
resolverSession,
|
|
40560
40472
|
priorSemanticIterations,
|
|
40561
40473
|
blockingThreshold: config2.blockingThreshold,
|
|
40562
40474
|
featureContextMarkdown,
|
|
@@ -41494,6 +41406,26 @@ Tests are failing. Fix the source so all tests pass \u2014 not just the ones lis
|
|
|
41494
41406
|
parts.push(escapeHatchFor(opts.story));
|
|
41495
41407
|
return parts.join("");
|
|
41496
41408
|
}
|
|
41409
|
+
static verifierContext(findings) {
|
|
41410
|
+
if (findings.length === 0) {
|
|
41411
|
+
return "The verifier found no issues.";
|
|
41412
|
+
}
|
|
41413
|
+
const lines = [
|
|
41414
|
+
`Fix the following ${findings.length} verifier finding${findings.length === 1 ? "" : "s"}:
|
|
41415
|
+
`
|
|
41416
|
+
];
|
|
41417
|
+
for (const f of findings) {
|
|
41418
|
+
const reasoning = f.meta?.reasoning ?? "";
|
|
41419
|
+
const detail = reasoning ? ` Reasoning: ${reasoning}
|
|
41420
|
+
` : "";
|
|
41421
|
+
lines.push(`- [${f.category}] ${f.message}
|
|
41422
|
+
${detail}`);
|
|
41423
|
+
}
|
|
41424
|
+
lines.push(`
|
|
41425
|
+
Fix the implementation to resolve all verifier findings.`);
|
|
41426
|
+
return lines.join(`
|
|
41427
|
+
`);
|
|
41428
|
+
}
|
|
41497
41429
|
static failingTestContext(findings) {
|
|
41498
41430
|
if (findings.length === 0) {
|
|
41499
41431
|
return "The full test suite has failing tests. Fix the implementation to make all tests pass.";
|
|
@@ -45977,17 +45909,6 @@ function createDebaterCallContext(ctx, agentName) {
|
|
|
45977
45909
|
}
|
|
45978
45910
|
};
|
|
45979
45911
|
}
|
|
45980
|
-
function buildResolverContext(successfulProposals, resolverContextInput) {
|
|
45981
|
-
if (!resolverContextInput)
|
|
45982
|
-
return;
|
|
45983
|
-
return {
|
|
45984
|
-
...resolverContextInput,
|
|
45985
|
-
labeledProposals: successfulProposals.map((proposal) => ({
|
|
45986
|
-
debater: buildDebaterLabel(proposal.debater),
|
|
45987
|
-
output: proposal.output
|
|
45988
|
-
}))
|
|
45989
|
-
};
|
|
45990
|
-
}
|
|
45991
45912
|
async function runZeroSuccessFallback(ctx, prompt, firstDebater) {
|
|
45992
45913
|
if (!firstDebater)
|
|
45993
45914
|
return null;
|
|
@@ -46016,7 +45937,6 @@ var init_runner_stateful_helpers = __esm(() => {
|
|
|
46016
45937
|
init_call();
|
|
46017
45938
|
init_debate_stateful();
|
|
46018
45939
|
init_prompts();
|
|
46019
|
-
init_personas();
|
|
46020
45940
|
DEFAULT_ABORT_SIGNAL = new AbortController().signal;
|
|
46021
45941
|
});
|
|
46022
45942
|
|
|
@@ -46138,13 +46058,7 @@ async function runHybrid(ctx, prompt) {
|
|
|
46138
46058
|
}
|
|
46139
46059
|
}
|
|
46140
46060
|
const proposalOutputs = successfulResults.map((p) => p.output);
|
|
46141
|
-
const resolveResult = await resolveOutcome(proposalOutputs, rebuttals.map((r) => r.output), ctx.stageConfig, ctx.config, { ...ctx.callContext, scopeId: ctx.resolverCallContext?.scopeId ?? ctx.callContext.scopeId }, ctx.storyId, ctx.timeoutSeconds * 1000, ctx.workdir, ctx.featureName,
|
|
46142
|
-
...ctx.resolverContextInput,
|
|
46143
|
-
labeledProposals: successfulResults.map((p) => ({
|
|
46144
|
-
debater: buildDebaterLabel(p.debater),
|
|
46145
|
-
output: p.output
|
|
46146
|
-
}))
|
|
46147
|
-
} : undefined, undefined, successfulResults.map((p) => p.debater), agentManager);
|
|
46061
|
+
const resolveResult = await resolveOutcome(proposalOutputs, rebuttals.map((r) => r.output), ctx.stageConfig, ctx.config, { ...ctx.callContext, scopeId: ctx.resolverCallContext?.scopeId ?? ctx.callContext.scopeId }, ctx.storyId, ctx.timeoutSeconds * 1000, ctx.workdir, ctx.featureName, undefined, successfulResults.map((p) => p.debater), agentManager);
|
|
46148
46062
|
return {
|
|
46149
46063
|
storyId: ctx.storyId,
|
|
46150
46064
|
stage: ctx.stage,
|
|
@@ -46573,9 +46487,7 @@ async function scoreAndDispatchVerifierPick(resolved, rebuttalSettled, ctx, opts
|
|
|
46573
46487
|
timeoutMs: (ctx.stageConfig.timeoutSeconds ?? 600) * 1000,
|
|
46574
46488
|
agentManager,
|
|
46575
46489
|
debaters: resolved.map((e) => e.debater),
|
|
46576
|
-
callContext: ctx.callContext
|
|
46577
|
-
...ctx.reviewerSession ? { reviewerSession: ctx.reviewerSession } : {},
|
|
46578
|
-
...ctx.resolverContextInput ? { resolverContextInput: ctx.resolverContextInput } : {}
|
|
46490
|
+
callContext: ctx.callContext
|
|
46579
46491
|
};
|
|
46580
46492
|
const manifest = extractManifestFromContext(scoringCtx);
|
|
46581
46493
|
const scored = await Promise.all(rebutProposals.map(async (p) => ({ proposal: p, score: await computeScore(p, manifest) })));
|
|
@@ -46654,9 +46566,7 @@ async function finalizePlanRun(ctx, opts, successful, rebuttalList, outputPaths,
|
|
|
46654
46566
|
timeoutMs: (ctx.stageConfig.timeoutSeconds ?? 600) * 1000,
|
|
46655
46567
|
agentManager,
|
|
46656
46568
|
debaters: finalizedProposals.map((p) => p.debater),
|
|
46657
|
-
callContext: ctx.callContext
|
|
46658
|
-
...ctx.reviewerSession ? { reviewerSession: ctx.reviewerSession } : {},
|
|
46659
|
-
...ctx.resolverContextInput ? { resolverContextInput: ctx.resolverContextInput } : {}
|
|
46569
|
+
callContext: ctx.callContext
|
|
46660
46570
|
};
|
|
46661
46571
|
const manifest = extractManifestFromContext(selectorCtx);
|
|
46662
46572
|
const scored = await Promise.all(selectorCtx.proposals.map(async (proposal) => ({ proposal, score: await computeScore(proposal, manifest) })));
|
|
@@ -46670,7 +46580,7 @@ async function finalizePlanRun(ctx, opts, successful, rebuttalList, outputPaths,
|
|
|
46670
46580
|
const outcome = selectorKind === "verifier-pick" ? {
|
|
46671
46581
|
outcome: "passed",
|
|
46672
46582
|
output: selectionSummary.winnerOutput ?? finalizedProposals[0]?.output
|
|
46673
|
-
} : await resolveOutcome(proposalOutputs, critiqueOutputs, ctx.stageConfig, ctx.config, ctx.callContext, ctx.storyId, resolverTimeoutMs, opts.workdir, opts.feature,
|
|
46583
|
+
} : await resolveOutcome(proposalOutputs, critiqueOutputs, ctx.stageConfig, ctx.config, ctx.callContext, ctx.storyId, resolverTimeoutMs, opts.workdir, opts.feature, buildPlanSynthesisSuffix(opts.specContent), finalizedProposals.map((p) => p.debater), agentManager);
|
|
46674
46584
|
let finalOutcome = outcome.outcome;
|
|
46675
46585
|
let winningOutput = outcome.output ?? finalizedProposals[0]?.output;
|
|
46676
46586
|
winningOutput = await readWinnerOutput(selectionSummary.winnerOutputPath ?? outputPaths[0], winningOutput);
|
|
@@ -46711,7 +46621,6 @@ async function finalizePlanRun(ctx, opts, successful, rebuttalList, outputPaths,
|
|
|
46711
46621
|
var _runPlanDeps, FILE_OUTPUT_INSTRUCTION = "Write the complete PRD JSON to this file path and then reply with a short confirmation:";
|
|
46712
46622
|
var init_runner_plan_helpers = __esm(() => {
|
|
46713
46623
|
init_pre_phase();
|
|
46714
|
-
init_runner_stateful_helpers();
|
|
46715
46624
|
init_verifier_pick();
|
|
46716
46625
|
init_session_helpers();
|
|
46717
46626
|
init_verifiers();
|
|
@@ -46967,9 +46876,7 @@ async function runPlan(ctx, taskContext, outputFormat, opts) {
|
|
|
46967
46876
|
stage: ctx.stage,
|
|
46968
46877
|
stageConfig: ctx.stageConfig,
|
|
46969
46878
|
config: ctx.config,
|
|
46970
|
-
callContext: ctx.callContext
|
|
46971
|
-
reviewerSession: ctx.reviewerSession,
|
|
46972
|
-
resolverContextInput: ctx.resolverContextInput
|
|
46879
|
+
callContext: ctx.callContext
|
|
46973
46880
|
}, { workdir: opts.workdir, feature: opts.feature, specContent: opts.specContent }, successful, rebuttalList, outputPaths, totalCostUsd, agentManager, selectorKind, includeHybridRebuttals);
|
|
46974
46881
|
}
|
|
46975
46882
|
var DEFAULT_MAX_CONCURRENT_DEBATERS = 2;
|
|
@@ -47103,7 +47010,7 @@ async function runStateful(ctx, prompt) {
|
|
|
47103
47010
|
}).then((result) => ({ ...result, resolvedIndex: proposal.resolvedIndex }))), concurrencyLimit)).flatMap((result) => result.status === "fulfilled" && result.value.success ? [{ debater: resolved[result.value.resolvedIndex].debater, round: 1, output: result.value.rebut }] : []) : [];
|
|
47104
47011
|
throwIfAborted2();
|
|
47105
47012
|
const proposalOutputs = successfulProposals.map((proposal) => proposal.output);
|
|
47106
|
-
const outcome = await resolveOutcome(proposalOutputs, rebuttals.map((rebuttal) => rebuttal.output), ctx.stageConfig, ctx.config, { ...ctx.callContext, scopeId: ctx.resolverCallContext?.scopeId ?? ctx.callContext.scopeId }, ctx.storyId, ctx.timeoutSeconds * 1000, ctx.workdir, ctx.featureName,
|
|
47013
|
+
const outcome = await resolveOutcome(proposalOutputs, rebuttals.map((rebuttal) => rebuttal.output), ctx.stageConfig, ctx.config, { ...ctx.callContext, scopeId: ctx.resolverCallContext?.scopeId ?? ctx.callContext.scopeId }, ctx.storyId, ctx.timeoutSeconds * 1000, ctx.workdir, ctx.featureName, undefined, successfulProposals.map((proposal) => proposal.debater), ctx.agentManager);
|
|
47107
47014
|
logger?.info("debate", "debate:result", {
|
|
47108
47015
|
storyId: ctx.storyId,
|
|
47109
47016
|
stage: ctx.stage,
|
|
@@ -47146,8 +47053,6 @@ class DebateRunner {
|
|
|
47146
47053
|
featureName;
|
|
47147
47054
|
timeoutSeconds;
|
|
47148
47055
|
sessionManager;
|
|
47149
|
-
reviewerSession;
|
|
47150
|
-
resolverContextInput;
|
|
47151
47056
|
constructor(opts) {
|
|
47152
47057
|
this.ctx = opts.ctx;
|
|
47153
47058
|
this.stage = opts.stage;
|
|
@@ -47157,8 +47062,6 @@ class DebateRunner {
|
|
|
47157
47062
|
this.featureName = opts.featureName ?? opts.stage;
|
|
47158
47063
|
this.timeoutSeconds = opts.timeoutSeconds ?? opts.stageConfig.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS;
|
|
47159
47064
|
this.sessionManager = opts.sessionManager ?? opts.ctx.runtime?.sessionManager;
|
|
47160
|
-
this.reviewerSession = opts.reviewerSession;
|
|
47161
|
-
this.resolverContextInput = opts.resolverContextInput;
|
|
47162
47065
|
}
|
|
47163
47066
|
async run(prompt) {
|
|
47164
47067
|
const sessionMode = this.stageConfig.sessionMode ?? "one-shot";
|
|
@@ -47352,14 +47255,7 @@ ${prompt}`;
|
|
|
47352
47255
|
critiqueOutputs = critiqueSettled.filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
47353
47256
|
}
|
|
47354
47257
|
const proposalOutputs = successful.map((p) => p.output);
|
|
47355
|
-
const
|
|
47356
|
-
...this.resolverContextInput,
|
|
47357
|
-
labeledProposals: successful.map((s) => ({
|
|
47358
|
-
debater: buildDebaterLabel(s.debater),
|
|
47359
|
-
output: s.output
|
|
47360
|
-
}))
|
|
47361
|
-
} : undefined;
|
|
47362
|
-
const selectorOutcome = await resolveOutcome(proposalOutputs, critiqueOutputs, this.stageConfig, this.config, { ...this.ctx, scopeId: resolverScope.scopeId }, this.ctx.storyId ?? "", this.timeoutSeconds * 1000, this.workdir, this.featureName, this.reviewerSession, fullResolverContext, undefined, successful.map((s) => s.debater), agentManager);
|
|
47258
|
+
const selectorOutcome = await resolveOutcome(proposalOutputs, critiqueOutputs, this.stageConfig, this.config, { ...this.ctx, scopeId: resolverScope.scopeId }, this.ctx.storyId ?? "", this.timeoutSeconds * 1000, this.workdir, this.featureName, undefined, successful.map((s) => s.debater), agentManager);
|
|
47363
47259
|
let finalOutcome = selectorOutcome.outcome;
|
|
47364
47260
|
if (config2.postDebateVerifier) {
|
|
47365
47261
|
const verifierCtx = {
|
|
@@ -47369,8 +47265,8 @@ ${prompt}`;
|
|
|
47369
47265
|
selectorResult: selectorOutcome,
|
|
47370
47266
|
workdir: this.workdir,
|
|
47371
47267
|
ctx: { ...this.ctx, scopeId: verifierScope.scopeId },
|
|
47372
|
-
acceptanceCriteria:
|
|
47373
|
-
blockingThreshold:
|
|
47268
|
+
acceptanceCriteria: undefined,
|
|
47269
|
+
blockingThreshold: undefined
|
|
47374
47270
|
};
|
|
47375
47271
|
const verifierResult = await resolvePostDebateVerifier(config2.postDebateVerifier.kind)(verifierCtx);
|
|
47376
47272
|
finalOutcome = verifierResult.outcome;
|
|
@@ -47407,9 +47303,7 @@ ${prompt}`;
|
|
|
47407
47303
|
agentManager: this.ctx.runtime.agentManager,
|
|
47408
47304
|
sessionManager: this.sessionManager ?? this.ctx.runtime.sessionManager,
|
|
47409
47305
|
runtime: this.ctx.runtime,
|
|
47410
|
-
abortSignal: this.ctx.runtime.signal
|
|
47411
|
-
reviewerSession: this.reviewerSession,
|
|
47412
|
-
resolverContextInput: this.resolverContextInput
|
|
47306
|
+
abortSignal: this.ctx.runtime.signal
|
|
47413
47307
|
};
|
|
47414
47308
|
}
|
|
47415
47309
|
toPlanCtx() {
|
|
@@ -47443,6 +47337,11 @@ var init_runner3 = __esm(() => {
|
|
|
47443
47337
|
init_verifiers();
|
|
47444
47338
|
});
|
|
47445
47339
|
|
|
47340
|
+
// src/debate/resolvers.ts
|
|
47341
|
+
var init_resolvers = __esm(() => {
|
|
47342
|
+
init_prompts();
|
|
47343
|
+
});
|
|
47344
|
+
|
|
47446
47345
|
// src/debate/index.ts
|
|
47447
47346
|
var init_debate = __esm(() => {
|
|
47448
47347
|
init_runner3();
|
|
@@ -51491,9 +51390,9 @@ var init_acceptance2 = __esm(() => {
|
|
|
51491
51390
|
function logTestOutput(logger, stage, output, opts = {}) {
|
|
51492
51391
|
if (!logger || !output)
|
|
51493
51392
|
return;
|
|
51494
|
-
const
|
|
51393
|
+
const tailLines2 = opts.tailLines ?? 20;
|
|
51495
51394
|
const lines = output.split(`
|
|
51496
|
-
`).slice(-
|
|
51395
|
+
`).slice(-tailLines2).join(`
|
|
51497
51396
|
`);
|
|
51498
51397
|
logger.debug(stage, "Test output (tail)", {
|
|
51499
51398
|
...opts.storyId !== undefined && { storyId: opts.storyId },
|
|
@@ -52970,7 +52869,7 @@ function extractPhaseFindings(output) {
|
|
|
52970
52869
|
return [];
|
|
52971
52870
|
}
|
|
52972
52871
|
const record2 = output;
|
|
52973
|
-
const rawArray = Array.isArray(record2.normalizedFindings) ? record2.normalizedFindings : Array.isArray(record2.findings) ? record2.findings : [];
|
|
52872
|
+
const rawArray = Array.isArray(record2.normalizedFindings) && record2.normalizedFindings.length > 0 ? record2.normalizedFindings : Array.isArray(record2.findings) ? record2.findings : [];
|
|
52974
52873
|
const findings = rawArray.filter(isFinding);
|
|
52975
52874
|
const success2 = "success" in record2 ? record2.success === true : ("passed" in record2) ? record2.passed === true : findings.length === 0;
|
|
52976
52875
|
return success2 ? [] : findings;
|
|
@@ -53260,7 +53159,7 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
53260
53159
|
config: { maxAttemptsTotal: rectification.maxAttempts, validatorRetries: 1 },
|
|
53261
53160
|
validate: async (_validateCtx, opts) => {
|
|
53262
53161
|
if (ctx.runtime.signal?.aborted)
|
|
53263
|
-
return [];
|
|
53162
|
+
return { findings: [], shortCircuited: false };
|
|
53264
53163
|
const lite = (opts?.mode ?? "full") === "lite";
|
|
53265
53164
|
const phases = phasesToRevalidate(opts?.strategiesRun, validationPhases);
|
|
53266
53165
|
getSafeLogger()?.debug("story-orchestrator", "rectification validate scope", {
|
|
@@ -53270,6 +53169,7 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
53270
53169
|
phasesSelected: phases.map((p) => p.kind)
|
|
53271
53170
|
});
|
|
53272
53171
|
const findings = [];
|
|
53172
|
+
let shortCircuited = false;
|
|
53273
53173
|
for (const phase of phases) {
|
|
53274
53174
|
if (lite && phase.kind === "full-suite-gate") {
|
|
53275
53175
|
continue;
|
|
@@ -53284,10 +53184,12 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
53284
53184
|
storyId: ctx.storyId,
|
|
53285
53185
|
phase: phase.slot.op.name
|
|
53286
53186
|
});
|
|
53187
|
+
shortCircuited = true;
|
|
53287
53188
|
break;
|
|
53288
53189
|
}
|
|
53289
53190
|
}
|
|
53290
|
-
|
|
53191
|
+
const validated = rectification.postValidate ? await rectification.postValidate(findings, _validateCtx) : findings;
|
|
53192
|
+
return { findings: validated, shortCircuited };
|
|
53291
53193
|
}
|
|
53292
53194
|
};
|
|
53293
53195
|
const cycleResult = await _storyOrchestratorDeps.runFixCycle(cycle, ctx, "story-orchestrator-rectification", { callOp: wrappedCallOp });
|
|
@@ -53319,6 +53221,9 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
53319
53221
|
if (EXHAUSTED_EXIT_REASONS.has(cycleResult.exitReason) && cycleResult.finalFindings.length > 0) {
|
|
53320
53222
|
return { rectificationExhausted: true, unfixedFindings: cycleResult.finalFindings };
|
|
53321
53223
|
}
|
|
53224
|
+
if (cycleResult.exitReason === "validate-short-circuit") {
|
|
53225
|
+
return { liteScopeIncomplete: true };
|
|
53226
|
+
}
|
|
53322
53227
|
return {};
|
|
53323
53228
|
}
|
|
53324
53229
|
|
|
@@ -53363,7 +53268,7 @@ class ExecutionPlan {
|
|
|
53363
53268
|
}
|
|
53364
53269
|
}
|
|
53365
53270
|
const rectResult = await runRectification(this.ctx, this.state, phaseCosts, phaseOutputs);
|
|
53366
|
-
if (this.state.rectification && !rectResult.rectificationExhausted) {
|
|
53271
|
+
if (this.state.rectification && (!rectResult.rectificationExhausted || rectResult.liteScopeIncomplete)) {
|
|
53367
53272
|
let resumeRectifyUsed = false;
|
|
53368
53273
|
for (const phase of collectOrderedPhases(this.state)) {
|
|
53369
53274
|
const name = phase.slot.op.name;
|
|
@@ -53527,7 +53432,8 @@ var init_story_orchestrator = __esm(() => {
|
|
|
53527
53432
|
"max-attempts-per-strategy",
|
|
53528
53433
|
"bail-when",
|
|
53529
53434
|
"no-strategy",
|
|
53530
|
-
"agent-gave-up"
|
|
53435
|
+
"agent-gave-up",
|
|
53436
|
+
"validate-short-circuit"
|
|
53531
53437
|
]);
|
|
53532
53438
|
TDD_OP_NAMES = new Set(["test-writer", "implementer", "verifier"]);
|
|
53533
53439
|
STRICT_VERDICT_PHASE_NAMES = new Set([
|
|
@@ -57943,7 +57849,7 @@ var package_default;
|
|
|
57943
57849
|
var init_package = __esm(() => {
|
|
57944
57850
|
package_default = {
|
|
57945
57851
|
name: "@nathapp/nax",
|
|
57946
|
-
version: "0.
|
|
57852
|
+
version: "0.68.0",
|
|
57947
57853
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
57948
57854
|
type: "module",
|
|
57949
57855
|
bin: {
|
|
@@ -58038,8 +57944,8 @@ var init_version = __esm(() => {
|
|
|
58038
57944
|
NAX_VERSION = package_default.version;
|
|
58039
57945
|
NAX_COMMIT = (() => {
|
|
58040
57946
|
try {
|
|
58041
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
58042
|
-
return "
|
|
57947
|
+
if (/^[0-9a-f]{6,10}$/.test("d56db412"))
|
|
57948
|
+
return "d56db412";
|
|
58043
57949
|
} catch {}
|
|
58044
57950
|
try {
|
|
58045
57951
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -59388,6 +59294,18 @@ async function handleRunCompletion(options) {
|
|
|
59388
59294
|
}
|
|
59389
59295
|
}
|
|
59390
59296
|
}
|
|
59297
|
+
let pluginGateFailed = false;
|
|
59298
|
+
const deferredReview = options.deferredReview;
|
|
59299
|
+
if (deferredReview?.anyFailed) {
|
|
59300
|
+
const failedReviewers = deferredReview.reviewerResults.filter((r) => !r.passed).map((r) => r.name);
|
|
59301
|
+
pluginGateFailed = config2.review.pluginMode === "gating";
|
|
59302
|
+
logger?.warn("review", "Deferred plugin reviewer(s) reported failures", {
|
|
59303
|
+
storyId: runId,
|
|
59304
|
+
failedReviewers,
|
|
59305
|
+
pluginMode: config2.review.pluginMode,
|
|
59306
|
+
gating: pluginGateFailed
|
|
59307
|
+
});
|
|
59308
|
+
}
|
|
59391
59309
|
const aggSnap = options.runtime.costAggregator.snapshot();
|
|
59392
59310
|
const aggregatorTotal = aggSnap.totalCostUsd;
|
|
59393
59311
|
const reportedTotal = Math.max(totalCost, aggregatorTotal);
|
|
@@ -59536,7 +59454,8 @@ async function handleRunCompletion(options) {
|
|
|
59536
59454
|
failed: finalCounts.failed,
|
|
59537
59455
|
skipped: finalCounts.skipped,
|
|
59538
59456
|
pending: finalCounts.pending
|
|
59539
|
-
}
|
|
59457
|
+
},
|
|
59458
|
+
pluginGateFailed
|
|
59540
59459
|
};
|
|
59541
59460
|
}
|
|
59542
59461
|
var _runCompletionDeps;
|
|
@@ -98101,12 +98020,13 @@ async function runCompletionPhase(options) {
|
|
|
98101
98020
|
skipRegression: regressionAlreadyPassed,
|
|
98102
98021
|
sessionManager: options.sessionManager,
|
|
98103
98022
|
pluginProviderCache: options.pluginProviderCache,
|
|
98023
|
+
deferredReview: options.deferredReview,
|
|
98104
98024
|
runtime: options.runtime,
|
|
98105
98025
|
abortSignal: options.abortSignal
|
|
98106
98026
|
});
|
|
98107
|
-
const { durationMs, runCompletedAt, finalCounts, reportedTotal } = completionResult;
|
|
98027
|
+
const { durationMs, runCompletedAt, finalCounts, reportedTotal, pluginGateFailed } = completionResult;
|
|
98108
98028
|
if (options.featureDir) {
|
|
98109
|
-
const finalStatus = isComplete(options.prd) ? "completed" : "failed";
|
|
98029
|
+
const finalStatus = isComplete(options.prd) && !pluginGateFailed ? "completed" : "failed";
|
|
98110
98030
|
options.statusWriter.setRunStatus(finalStatus);
|
|
98111
98031
|
await options.statusWriter.writeFeatureStatus(options.featureDir, reportedTotal, options.iterations);
|
|
98112
98032
|
}
|
|
@@ -98136,7 +98056,8 @@ async function runCompletionPhase(options) {
|
|
|
98136
98056
|
return {
|
|
98137
98057
|
durationMs,
|
|
98138
98058
|
runCompletedAt,
|
|
98139
|
-
acceptancePassed
|
|
98059
|
+
acceptancePassed,
|
|
98060
|
+
pluginGateFailed
|
|
98140
98061
|
};
|
|
98141
98062
|
}
|
|
98142
98063
|
|
|
@@ -98228,7 +98149,14 @@ async function runExecutionPhase(options, prd, pluginRegistry) {
|
|
|
98228
98149
|
storiesCompleted,
|
|
98229
98150
|
totalCost
|
|
98230
98151
|
});
|
|
98231
|
-
return {
|
|
98152
|
+
return {
|
|
98153
|
+
prd,
|
|
98154
|
+
iterations,
|
|
98155
|
+
storiesCompleted,
|
|
98156
|
+
totalCost,
|
|
98157
|
+
allStoryMetrics,
|
|
98158
|
+
deferredReview: unifiedResult.deferredReview
|
|
98159
|
+
};
|
|
98232
98160
|
}
|
|
98233
98161
|
|
|
98234
98162
|
// src/execution/runner-setup.ts
|
|
@@ -98392,13 +98320,14 @@ async function run(options) {
|
|
|
98392
98320
|
sessionManager,
|
|
98393
98321
|
agentManager,
|
|
98394
98322
|
pluginProviderCache,
|
|
98323
|
+
deferredReview: executionResult.deferredReview,
|
|
98395
98324
|
runtime,
|
|
98396
98325
|
abortSignal: shutdownController.signal
|
|
98397
98326
|
});
|
|
98398
|
-
const { durationMs, acceptancePassed } = completionResult;
|
|
98327
|
+
const { durationMs, acceptancePassed, pluginGateFailed } = completionResult;
|
|
98399
98328
|
runCompleted = true;
|
|
98400
98329
|
return {
|
|
98401
|
-
success: isComplete(prd) && acceptancePassed,
|
|
98330
|
+
success: isComplete(prd) && acceptancePassed && !pluginGateFailed,
|
|
98402
98331
|
iterations,
|
|
98403
98332
|
storiesCompleted,
|
|
98404
98333
|
totalCost,
|