@nathapp/nax 0.83.1 → 0.83.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/nax.js +151 -7
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -2668,7 +2668,7 @@ var package_default;
|
|
|
2668
2668
|
var init_package = __esm(() => {
|
|
2669
2669
|
package_default = {
|
|
2670
2670
|
name: "@nathapp/nax",
|
|
2671
|
-
version: "0.83.
|
|
2671
|
+
version: "0.83.2",
|
|
2672
2672
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
2673
2673
|
type: "module",
|
|
2674
2674
|
bin: {
|
|
@@ -57251,8 +57251,8 @@ var init_version = __esm(() => {
|
|
|
57251
57251
|
NAX_AI_VERSION = CATALOG_VERSION;
|
|
57252
57252
|
NAX_COMMIT = (() => {
|
|
57253
57253
|
try {
|
|
57254
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
57255
|
-
return "
|
|
57254
|
+
if (/^[0-9a-f]{6,10}$/.test("bcfcddb0"))
|
|
57255
|
+
return "bcfcddb0";
|
|
57256
57256
|
} catch {}
|
|
57257
57257
|
try {
|
|
57258
57258
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -92508,6 +92508,78 @@ var init_run_phase = __esm(() => {
|
|
|
92508
92508
|
];
|
|
92509
92509
|
});
|
|
92510
92510
|
|
|
92511
|
+
// src/execution/story-orchestrator/review-pair.ts
|
|
92512
|
+
function shouldRunReviewsConcurrently(reviewConfig, phases) {
|
|
92513
|
+
const adversarial = reviewConfig?.adversarial;
|
|
92514
|
+
const maxConcurrentSessions = adversarial?.maxConcurrentSessions ?? 2;
|
|
92515
|
+
return adversarial?.parallel === true && maxConcurrentSessions >= 2 && phases.some((phase) => phase.kind === "semantic-review") && phases.some((phase) => phase.kind === "adversarial-review");
|
|
92516
|
+
}
|
|
92517
|
+
async function runReviewPair(ctx, pair, tracking, isThreeSession = false, progress) {
|
|
92518
|
+
getSafeLogger()?.info("story-orchestrator", "Running semantic-review and adversarial-review concurrently", {
|
|
92519
|
+
storyId: ctx.storyId
|
|
92520
|
+
});
|
|
92521
|
+
const outcomes = await Promise.allSettled(pair.map((phase, index) => _reviewPairDeps.runPhase(ctx, phase.slot, tracking.phaseCosts, tracking.phaseOutputs, isThreeSession, progress ? { index: index === 0 ? progress.indices[0] : progress.indices[1], total: progress.total } : undefined)));
|
|
92522
|
+
const logger = getSafeLogger();
|
|
92523
|
+
for (const [index, outcome] of outcomes.entries()) {
|
|
92524
|
+
if (outcome.status === "rejected") {
|
|
92525
|
+
logger?.error("story-orchestrator", "Phase threw unexpected error", {
|
|
92526
|
+
storyId: ctx.storyId,
|
|
92527
|
+
phase: index === 0 ? pair[0].kind : pair[1].kind,
|
|
92528
|
+
error: errorMessage(outcome.reason)
|
|
92529
|
+
});
|
|
92530
|
+
}
|
|
92531
|
+
}
|
|
92532
|
+
const semanticOutcome = outcomes[0];
|
|
92533
|
+
if (semanticOutcome?.status === "rejected")
|
|
92534
|
+
throw semanticOutcome.reason;
|
|
92535
|
+
const adversarialOutcome = outcomes[1];
|
|
92536
|
+
if (adversarialOutcome?.status === "rejected")
|
|
92537
|
+
throw adversarialOutcome.reason;
|
|
92538
|
+
}
|
|
92539
|
+
var _reviewPairDeps;
|
|
92540
|
+
var init_review_pair = __esm(() => {
|
|
92541
|
+
init_logger2();
|
|
92542
|
+
init_run_phase();
|
|
92543
|
+
_reviewPairDeps = { runPhase };
|
|
92544
|
+
});
|
|
92545
|
+
|
|
92546
|
+
// src/execution/story-orchestrator/revalidation-reviews.ts
|
|
92547
|
+
async function dispatchRevalidationPhase(ctx, phase, phases, tracking, isThreeSession) {
|
|
92548
|
+
const reviewConfig = ctx.config?.review ?? ctx.packageView.config.review;
|
|
92549
|
+
if (phase.kind === "semantic-review" && shouldRunReviewsConcurrently(reviewConfig, phases)) {
|
|
92550
|
+
const semantic = phase;
|
|
92551
|
+
const adversarial = phases.find((candidate) => candidate.kind === "adversarial-review");
|
|
92552
|
+
if (adversarial) {
|
|
92553
|
+
await runReviewPair(ctx, [semantic, adversarial], tracking, isThreeSession);
|
|
92554
|
+
return ["semantic-review", "adversarial-review"];
|
|
92555
|
+
}
|
|
92556
|
+
}
|
|
92557
|
+
await runPhase(ctx, phase.slot, tracking.phaseCosts, tracking.phaseOutputs, isThreeSession);
|
|
92558
|
+
return [phase.kind];
|
|
92559
|
+
}
|
|
92560
|
+
function phasesForRevalidation(ctx, phases) {
|
|
92561
|
+
const reviewConfig = ctx.config?.review ?? ctx.packageView.config.review;
|
|
92562
|
+
return shouldRunReviewsConcurrently(reviewConfig, phases) ? phases.filter((phase) => phase.kind !== "adversarial-review") : phases;
|
|
92563
|
+
}
|
|
92564
|
+
function collectPairedReviewFindings(options) {
|
|
92565
|
+
if (options.dispatched.length < 2)
|
|
92566
|
+
return false;
|
|
92567
|
+
const phase = options.phases.find((item) => item.kind === "adversarial-review");
|
|
92568
|
+
if (!phase)
|
|
92569
|
+
return false;
|
|
92570
|
+
const output = options.phaseOutputs[phase.slot.op.name];
|
|
92571
|
+
options.findings.push(...extractPhaseFindings(output));
|
|
92572
|
+
return !phasePassed(phase.slot.op.name, output, options.storyId);
|
|
92573
|
+
}
|
|
92574
|
+
function isRevalidationFailure(options) {
|
|
92575
|
+
return !phasePassed(options.phase.slot.op.name, options.output, options.storyId) && !options.quarantinedOnly || options.pairedReviewFailed;
|
|
92576
|
+
}
|
|
92577
|
+
var init_revalidation_reviews = __esm(() => {
|
|
92578
|
+
init_phase_eval();
|
|
92579
|
+
init_review_pair();
|
|
92580
|
+
init_run_phase();
|
|
92581
|
+
});
|
|
92582
|
+
|
|
92511
92583
|
// src/execution/story-orchestrator/rectification.ts
|
|
92512
92584
|
function shouldSkipPhaseForRectification(input) {
|
|
92513
92585
|
const { phase, state, phaseOutputs, nbfPath } = input;
|
|
@@ -92663,6 +92735,7 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
|
|
|
92663
92735
|
const extra = overrides?.extraRevalidationKinds ? validationPhases.filter((p) => overrides.extraRevalidationKinds?.includes(p.kind) && !selected.some((s) => s.kind === p.kind)) : [];
|
|
92664
92736
|
const selectedWithExtra = [...selected, ...extra];
|
|
92665
92737
|
const phases = lite ? orderGateLast(selectedWithExtra) : selectedWithExtra;
|
|
92738
|
+
const dispatchPhases = phasesForRevalidation(ctx, phases);
|
|
92666
92739
|
getSafeLogger()?.debug("story-orchestrator", "rectification validate scope", {
|
|
92667
92740
|
storyId: ctx.storyId,
|
|
92668
92741
|
mode: opts?.mode ?? "full",
|
|
@@ -92671,8 +92744,8 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
|
|
|
92671
92744
|
});
|
|
92672
92745
|
const findings = [];
|
|
92673
92746
|
let shortCircuited = false;
|
|
92674
|
-
for (const phase of
|
|
92675
|
-
await
|
|
92747
|
+
for (const phase of dispatchPhases) {
|
|
92748
|
+
const dispatched = await dispatchRevalidationPhase(ctx, phase, phases, { phaseCosts, phaseOutputs }, overrides?.isThreeSession);
|
|
92676
92749
|
if (shouldSkipPhaseForRectification({ phase, state, phaseOutputs, nbfPath })) {
|
|
92677
92750
|
const carvedOutFindings = selectRegressedGateFindings(extractPhaseFindings(phaseOutputs[phase.slot.op.name]), overrides?.gateBaselineKeys ?? new Set, ctx.runtime.quarantineMemo);
|
|
92678
92751
|
if (carvedOutFindings.length > 0) {
|
|
@@ -92699,8 +92772,15 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
|
|
|
92699
92772
|
const phaseFindings = extractPhaseFindings(output);
|
|
92700
92773
|
const blockingFindings = nbfPath ? phaseFindings.filter((finding) => !isQuarantinedFlake(finding, nbfFlakeTriage?.memo ?? ctx.runtime.quarantineMemo)) : phaseFindings;
|
|
92701
92774
|
findings.push(...blockingFindings);
|
|
92775
|
+
const pairedReviewFailed = collectPairedReviewFindings({
|
|
92776
|
+
dispatched,
|
|
92777
|
+
phases,
|
|
92778
|
+
phaseOutputs,
|
|
92779
|
+
findings,
|
|
92780
|
+
storyId: ctx.storyId
|
|
92781
|
+
});
|
|
92702
92782
|
const quarantinedOnly = nbfPath && isQuarantinedOnlyGateFailure(phase, phaseFindings, blockingFindings);
|
|
92703
|
-
if (
|
|
92783
|
+
if (isRevalidationFailure({ phase, output, storyId: ctx.storyId, quarantinedOnly, pairedReviewFailed })) {
|
|
92704
92784
|
getSafeLogger()?.warn("story-orchestrator", "Short-circuiting revalidation on phase failure", {
|
|
92705
92785
|
storyId: ctx.storyId,
|
|
92706
92786
|
phase: phase.slot.op.name
|
|
@@ -92784,6 +92864,7 @@ var init_rectification = __esm(() => {
|
|
|
92784
92864
|
init_nbf_flake_triage();
|
|
92785
92865
|
init_no_progress_bail();
|
|
92786
92866
|
init_phase_eval();
|
|
92867
|
+
init_revalidation_reviews();
|
|
92787
92868
|
init_run_phase();
|
|
92788
92869
|
init_types12();
|
|
92789
92870
|
});
|
|
@@ -92837,14 +92918,76 @@ async function recordGreenCheckpoint(plan, phaseName) {
|
|
|
92837
92918
|
}
|
|
92838
92919
|
}
|
|
92839
92920
|
}
|
|
92921
|
+
async function runCanonicalReviewPair(options) {
|
|
92922
|
+
const { plan, tracking, semantic, adversarial, indices, total } = options;
|
|
92923
|
+
const { ctx, isThreeSession } = plan;
|
|
92924
|
+
const reviews = [semantic, adversarial];
|
|
92925
|
+
try {
|
|
92926
|
+
await runReviewPair(ctx, reviews, tracking, isThreeSession, { indices, total });
|
|
92927
|
+
} catch (error48) {
|
|
92928
|
+
for (const review of reviews) {
|
|
92929
|
+
const name = review.slot.op.name;
|
|
92930
|
+
if (name in tracking.phaseOutputs && phasePassed(name, tracking.phaseOutputs[name], ctx.storyId)) {
|
|
92931
|
+
await recordGreenCheckpoint(plan, name);
|
|
92932
|
+
}
|
|
92933
|
+
}
|
|
92934
|
+
throw error48;
|
|
92935
|
+
}
|
|
92936
|
+
let shortCircuitPhase;
|
|
92937
|
+
for (const review of reviews) {
|
|
92938
|
+
const name = review.slot.op.name;
|
|
92939
|
+
if (phasePassed(name, tracking.phaseOutputs[name], ctx.storyId)) {
|
|
92940
|
+
await recordGreenCheckpoint(plan, name);
|
|
92941
|
+
} else {
|
|
92942
|
+
shortCircuitPhase = name;
|
|
92943
|
+
if (name !== "semantic-review") {
|
|
92944
|
+
getSafeLogger()?.warn("story-orchestrator", "Short-circuiting on phase failure", {
|
|
92945
|
+
storyId: ctx.storyId,
|
|
92946
|
+
phase: name
|
|
92947
|
+
});
|
|
92948
|
+
break;
|
|
92949
|
+
}
|
|
92950
|
+
getSafeLogger()?.warn("story-orchestrator", "semantic-review failed \u2014 continuing to adversarial-review for a second opinion", { storyId: ctx.storyId, phase: name });
|
|
92951
|
+
}
|
|
92952
|
+
}
|
|
92953
|
+
return shortCircuitPhase;
|
|
92954
|
+
}
|
|
92840
92955
|
async function runCanonicalLoop(plan, tracking, orderedPhases) {
|
|
92841
92956
|
const { ctx, isThreeSession } = plan;
|
|
92842
92957
|
const { phaseCosts, phaseOutputs } = tracking;
|
|
92843
92958
|
const logger = getSafeLogger();
|
|
92844
92959
|
let shortCircuitPhase;
|
|
92960
|
+
const skippedPhaseIndexes = new Set;
|
|
92961
|
+
const runnablePhases = orderedPhases.filter((phase, index) => {
|
|
92962
|
+
const name = phase.slot.op.name;
|
|
92963
|
+
const alreadyPassed = name in phaseOutputs && phasePassed(name, phaseOutputs[name], ctx.storyId);
|
|
92964
|
+
if (alreadyPassed)
|
|
92965
|
+
skippedPhaseIndexes.add(index);
|
|
92966
|
+
return !alreadyPassed;
|
|
92967
|
+
});
|
|
92968
|
+
const reviewConfig = ctx.config?.review ?? ctx.packageView.config.review;
|
|
92969
|
+
const pairReviews = shouldRunReviewsConcurrently(reviewConfig, runnablePhases);
|
|
92970
|
+
const phasesByKind = new Map(orderedPhases.map((phase, index) => [phase.kind, { phase, index }]));
|
|
92971
|
+
let pairedAdversarialIndex;
|
|
92845
92972
|
for (const [phaseIndex, phase] of orderedPhases.entries()) {
|
|
92846
92973
|
const name = phase.slot.op.name;
|
|
92847
|
-
if (
|
|
92974
|
+
if (phaseIndex === pairedAdversarialIndex)
|
|
92975
|
+
continue;
|
|
92976
|
+
if (skippedPhaseIndexes.has(phaseIndex))
|
|
92977
|
+
continue;
|
|
92978
|
+
const adversarial = phasesByKind.get("adversarial-review");
|
|
92979
|
+
if (pairReviews && phase.kind === "semantic-review" && adversarial && adversarial.index > phaseIndex) {
|
|
92980
|
+
pairedAdversarialIndex = adversarial.index;
|
|
92981
|
+
shortCircuitPhase = await runCanonicalReviewPair({
|
|
92982
|
+
plan,
|
|
92983
|
+
tracking,
|
|
92984
|
+
semantic: phase,
|
|
92985
|
+
adversarial: adversarial.phase,
|
|
92986
|
+
indices: [phaseIndex + 1, adversarial.index + 1],
|
|
92987
|
+
total: orderedPhases.length
|
|
92988
|
+
});
|
|
92989
|
+
if (shortCircuitPhase === "adversarial-review")
|
|
92990
|
+
break;
|
|
92848
92991
|
continue;
|
|
92849
92992
|
}
|
|
92850
92993
|
try {
|
|
@@ -93005,6 +93148,7 @@ var init_execution_plan_phases = __esm(() => {
|
|
|
93005
93148
|
init_phase_eval();
|
|
93006
93149
|
init_phase_state();
|
|
93007
93150
|
init_rectification();
|
|
93151
|
+
init_review_pair();
|
|
93008
93152
|
init_run_phase();
|
|
93009
93153
|
});
|
|
93010
93154
|
|