@nathapp/nax 0.68.3 → 0.68.5
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 +108 -50
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -16837,6 +16837,7 @@ var init_schemas_execution = __esm(() => {
|
|
|
16837
16837
|
fullSuiteTimeoutSeconds: exports_external.number().int().min(10).max(600).default(120),
|
|
16838
16838
|
maxFailureSummaryChars: exports_external.number().int().min(500).max(1e4).default(2000),
|
|
16839
16839
|
abortOnIncreasingFailures: exports_external.boolean().default(true),
|
|
16840
|
+
consecutiveIncreasesToBail: exports_external.number().int().min(1).max(10).default(2),
|
|
16840
16841
|
escalateOnExhaustion: exports_external.boolean().optional().default(true),
|
|
16841
16842
|
rethinkAtAttempt: exports_external.number().int().min(1).default(2),
|
|
16842
16843
|
urgencyAtAttempt: exports_external.number().int().min(1).default(3)
|
|
@@ -17321,6 +17322,7 @@ var init_schemas3 = __esm(() => {
|
|
|
17321
17322
|
fullSuiteTimeoutSeconds: 300,
|
|
17322
17323
|
maxFailureSummaryChars: 2000,
|
|
17323
17324
|
abortOnIncreasingFailures: true,
|
|
17325
|
+
consecutiveIncreasesToBail: 2,
|
|
17324
17326
|
escalateOnExhaustion: true,
|
|
17325
17327
|
rethinkAtAttempt: 2,
|
|
17326
17328
|
urgencyAtAttempt: 3
|
|
@@ -19086,6 +19088,12 @@ function resolveTestStrategy(raw) {
|
|
|
19086
19088
|
return "three-session-tdd-lite";
|
|
19087
19089
|
return "test-after";
|
|
19088
19090
|
}
|
|
19091
|
+
function isThreeSessionStrategy(strategy) {
|
|
19092
|
+
return strategy !== undefined && THREE_SESSION_STRATEGIES.has(strategy);
|
|
19093
|
+
}
|
|
19094
|
+
function isSingleSessionTestOwningStrategy(strategy) {
|
|
19095
|
+
return strategy !== undefined && SINGLE_SESSION_TEST_OWNING_STRATEGIES.has(strategy);
|
|
19096
|
+
}
|
|
19089
19097
|
function getAcQualityRules(profile) {
|
|
19090
19098
|
const langSection = profile?.language ? LANGUAGE_PATTERNS[profile.language] : undefined;
|
|
19091
19099
|
const typeSection = profile?.type ? TYPE_PATTERNS[profile.type] : undefined;
|
|
@@ -19098,7 +19106,7 @@ function getAcQualityRules(profile) {
|
|
|
19098
19106
|
|
|
19099
19107
|
${extras}`;
|
|
19100
19108
|
}
|
|
19101
|
-
var VALID_TEST_STRATEGIES, COMPLEXITY_GUIDE = `## Complexity Classification Guide
|
|
19109
|
+
var VALID_TEST_STRATEGIES, THREE_SESSION_STRATEGIES, SINGLE_SESSION_TEST_OWNING_STRATEGIES, COMPLEXITY_GUIDE = `## Complexity Classification Guide
|
|
19102
19110
|
|
|
19103
19111
|
Classify each story's complexity based on scope and risk \u2014 NOT acceptance criteria count.
|
|
19104
19112
|
A story with 10 simple "add field" ACs is simpler than one with 3 ACs involving concurrent
|
|
@@ -19239,6 +19247,11 @@ var init_test_strategy = __esm(() => {
|
|
|
19239
19247
|
"three-session-tdd",
|
|
19240
19248
|
"three-session-tdd-lite"
|
|
19241
19249
|
];
|
|
19250
|
+
THREE_SESSION_STRATEGIES = new Set([
|
|
19251
|
+
"three-session-tdd",
|
|
19252
|
+
"three-session-tdd-lite"
|
|
19253
|
+
]);
|
|
19254
|
+
SINGLE_SESSION_TEST_OWNING_STRATEGIES = new Set(["tdd-simple", "test-after"]);
|
|
19242
19255
|
LANGUAGE_PATTERNS = {
|
|
19243
19256
|
go: `### Go-Specific AC Patterns
|
|
19244
19257
|
|
|
@@ -36046,7 +36059,7 @@ var init_autofix_test_writer = __esm(() => {
|
|
|
36046
36059
|
kind: "run",
|
|
36047
36060
|
name: "autofix-test-writer",
|
|
36048
36061
|
stage: "rectification",
|
|
36049
|
-
session: { role: "test-writer", lifetime: "
|
|
36062
|
+
session: { role: "test-writer", lifetime: "warm" },
|
|
36050
36063
|
config: autofixConfigSelector,
|
|
36051
36064
|
build(input, _ctx) {
|
|
36052
36065
|
const prompt = RectifierPromptBuilder.testWriterRectification(input.failedChecks, input.story, {
|
|
@@ -36838,18 +36851,36 @@ var init__session_output = __esm(() => {
|
|
|
36838
36851
|
EMPTY = { success: false, filesChanged: [], output: "", parsed: false };
|
|
36839
36852
|
});
|
|
36840
36853
|
|
|
36854
|
+
// src/operations/execution-gates.ts
|
|
36855
|
+
function shouldRunReview(config2) {
|
|
36856
|
+
return config2.review?.enabled === true;
|
|
36857
|
+
}
|
|
36858
|
+
function shouldRunRectification(config2) {
|
|
36859
|
+
return config2.execution?.rectification?.enabled === true;
|
|
36860
|
+
}
|
|
36861
|
+
function shouldKeepSessionOpen(config2, role) {
|
|
36862
|
+
return SESSION_CONTINUITY_ROLES.has(role) && (shouldRunReview(config2) || shouldRunRectification(config2));
|
|
36863
|
+
}
|
|
36864
|
+
var SESSION_CONTINUITY_ROLES;
|
|
36865
|
+
var init_execution_gates = __esm(() => {
|
|
36866
|
+
init_config();
|
|
36867
|
+
SESSION_CONTINUITY_ROLES = new Set(["implementer", "test-writer"]);
|
|
36868
|
+
});
|
|
36869
|
+
|
|
36841
36870
|
// src/operations/write-test.ts
|
|
36842
36871
|
var testWriterOp;
|
|
36843
36872
|
var init_write_test = __esm(() => {
|
|
36844
36873
|
init_config();
|
|
36845
36874
|
init_isolation();
|
|
36846
36875
|
init__session_output();
|
|
36876
|
+
init_execution_gates();
|
|
36847
36877
|
testWriterOp = {
|
|
36848
36878
|
kind: "run",
|
|
36849
36879
|
name: "test-writer",
|
|
36850
36880
|
stage: "run",
|
|
36851
|
-
session: { role: "test-writer", lifetime: "
|
|
36881
|
+
session: { role: "test-writer", lifetime: "warm" },
|
|
36852
36882
|
config: tddConfigSelector,
|
|
36883
|
+
keepOpen: (_input, ctx) => shouldKeepSessionOpen(ctx.config, "test-writer"),
|
|
36853
36884
|
build(input, _ctx) {
|
|
36854
36885
|
if (input.promptMarkdown?.trim()) {
|
|
36855
36886
|
return {
|
|
@@ -36896,20 +36927,6 @@ var init_write_test = __esm(() => {
|
|
|
36896
36927
|
};
|
|
36897
36928
|
});
|
|
36898
36929
|
|
|
36899
|
-
// src/operations/execution-gates.ts
|
|
36900
|
-
function shouldRunReview(config2) {
|
|
36901
|
-
return config2.review?.enabled === true;
|
|
36902
|
-
}
|
|
36903
|
-
function shouldRunRectification(config2) {
|
|
36904
|
-
return config2.execution?.rectification?.enabled === true;
|
|
36905
|
-
}
|
|
36906
|
-
function shouldKeepSessionOpen(config2, role) {
|
|
36907
|
-
return role === "implementer" && (shouldRunReview(config2) || shouldRunRectification(config2));
|
|
36908
|
-
}
|
|
36909
|
-
var init_execution_gates = __esm(() => {
|
|
36910
|
-
init_config();
|
|
36911
|
-
});
|
|
36912
|
-
|
|
36913
36930
|
// src/operations/implement.ts
|
|
36914
36931
|
var implementerOp;
|
|
36915
36932
|
var init_implement = __esm(() => {
|
|
@@ -38416,10 +38433,11 @@ var init__finding_to_check = __esm(() => {
|
|
|
38416
38433
|
});
|
|
38417
38434
|
|
|
38418
38435
|
// src/operations/autofix-implementer-strategy.ts
|
|
38419
|
-
function makeAutofixImplementerStrategy(story, config2, sink) {
|
|
38436
|
+
function makeAutofixImplementerStrategy(story, config2, sink, opts = {}) {
|
|
38437
|
+
const claimsAdversarial = opts.includeAdversarialReview === true;
|
|
38420
38438
|
return {
|
|
38421
38439
|
name: "autofix-implementer",
|
|
38422
|
-
appliesTo: (f) => f.fixTarget === "source" && IMPLEMENTER_SOURCES.has(f.source),
|
|
38440
|
+
appliesTo: (f) => f.fixTarget === "source" && IMPLEMENTER_SOURCES.has(f.source) || claimsAdversarial && f.source === "adversarial-review",
|
|
38423
38441
|
fixOp: implementerRectifyOp,
|
|
38424
38442
|
buildInput: (findings, _prior, _cycleCtx) => ({
|
|
38425
38443
|
failedChecks: findingsToFailedChecks(findings),
|
|
@@ -41077,11 +41095,19 @@ ${exceptions.join(`
|
|
|
41077
41095
|
|
|
41078
41096
|
`)}`;
|
|
41079
41097
|
}
|
|
41098
|
+
function implementerOwnsTests(story) {
|
|
41099
|
+
return isSingleSessionTestOwningStrategy(story.routing?.testStrategy);
|
|
41100
|
+
}
|
|
41101
|
+
function testEditHeadline(story, prohibition) {
|
|
41102
|
+
return implementerOwnsTests(story) ? SINGLE_SESSION_PERMIT_HEADLINE : prohibition;
|
|
41103
|
+
}
|
|
41080
41104
|
function exceptionCountWord(story) {
|
|
41081
|
-
return
|
|
41105
|
+
return isThreeSessionStrategy(story.routing?.testStrategy) ? "four" : "three";
|
|
41082
41106
|
}
|
|
41083
41107
|
function escapeHatchFor(story) {
|
|
41084
|
-
|
|
41108
|
+
if (implementerOwnsTests(story))
|
|
41109
|
+
return SINGLE_SESSION_TEST_EDIT_POLICY;
|
|
41110
|
+
const isTdd = isThreeSessionStrategy(story.routing?.testStrategy);
|
|
41085
41111
|
return buildEscapeHatch({ includeMockHandoff: isTdd });
|
|
41086
41112
|
}
|
|
41087
41113
|
function noTestIsolationBlock(story) {
|
|
@@ -41152,7 +41178,7 @@ ${errors3}
|
|
|
41152
41178
|
2. Only fix findings that are actually valid problems
|
|
41153
41179
|
3. Do NOT add keys, functions, or imports that already exist \u2014 check first
|
|
41154
41180
|
|
|
41155
|
-
Do NOT change test files or test behavior \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below
|
|
41181
|
+
${testEditHeadline(story, `Do NOT change test files or test behavior \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below.`)}
|
|
41156
41182
|
Do NOT add new features \u2014 only fix valid issues.
|
|
41157
41183
|
Commit your fixes when done.${scopeConstraint}${noTestIsolationBlock(story)}${escapeHatchFor(story)}`;
|
|
41158
41184
|
}
|
|
@@ -41206,6 +41232,7 @@ Commit your fixes when done.${scopeConstraint}${noTestIsolationBlock(story)}${es
|
|
|
41206
41232
|
}
|
|
41207
41233
|
function mechanicalRectification(checks3, story, scopeConstraint, opts) {
|
|
41208
41234
|
const errors3 = formatCheckErrors(checks3, opts);
|
|
41235
|
+
const scopeDirective = implementerOwnsTests(story) ? `Fix all errors listed above that are within this story's scope. ${SINGLE_SESSION_PERMIT_HEADLINE}` : `Fix all errors listed above that are within this story's scope \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below for sibling-story spillover. Do NOT change test files or test behavior except via those exceptions.`;
|
|
41209
41236
|
return `You are fixing lint/typecheck errors from a code review.
|
|
41210
41237
|
|
|
41211
41238
|
Story: ${story.title} (${story.id})
|
|
@@ -41214,7 +41241,7 @@ The following quality checks failed after implementation:
|
|
|
41214
41241
|
|
|
41215
41242
|
${errors3}
|
|
41216
41243
|
|
|
41217
|
-
|
|
41244
|
+
${scopeDirective}
|
|
41218
41245
|
Do NOT add new features \u2014 only fix the quality check errors.
|
|
41219
41246
|
After fixing, re-run the failing check(s) to verify they pass, then commit your changes.${scopeConstraint}${noTestIsolationBlock(story)}${escapeHatchFor(story)}`;
|
|
41220
41247
|
}
|
|
@@ -41285,11 +41312,28 @@ REASON: <one paragraph: which mock is wrong vs which dispatch the new code uses,
|
|
|
41285
41312
|
Rules:
|
|
41286
41313
|
- Do NOT make any edits yourself; the test-writer will fulfill.
|
|
41287
41314
|
- Do NOT also emit \`UNRESOLVED:\` in the same turn \u2014 this declaration IS the handoff.
|
|
41288
|
-
- FILES must list real test files. Each path must exist and be a test file.`,
|
|
41315
|
+
- FILES must list real test files. Each path must exist and be a test file.`, SINGLE_SESSION_PERMIT_HEADLINE = "You authored these tests in the same session as the implementation, so you MAY edit test files \u2014 but ONLY to resolve a genuine contradiction between a test and this story's acceptance criteria (or between two acceptance criteria). NEVER weaken, delete, loosen, or skip a test merely to make it pass. See the test-edit guidance appended below.", SINGLE_SESSION_TEST_EDIT_POLICY = `
|
|
41316
|
+
|
|
41317
|
+
## Test-edit guidance (single-session implementer)
|
|
41318
|
+
|
|
41319
|
+
You wrote both the tests and the implementation for this story in one session, so no
|
|
41320
|
+
separate test-writer owns the test contract. You therefore MAY edit test files during
|
|
41321
|
+
rectification \u2014 subject to these limits:
|
|
41322
|
+
|
|
41323
|
+
- Edit a test ONLY to resolve a genuine contradiction between the test and an acceptance
|
|
41324
|
+
criterion, a contradiction between two acceptance criteria, or a clear defect in a test
|
|
41325
|
+
you authored (wrong arity/type, impossible setup, or asserting behavior the ACs do not require).
|
|
41326
|
+
- NEVER weaken, delete, loosen, or \`skip\` a test simply because the implementation fails it.
|
|
41327
|
+
A failing test usually means the SOURCE is wrong \u2014 fix the source first.
|
|
41328
|
+
- The semantic and adversarial reviewers still gate correctness; gaming a test to pass will be caught.
|
|
41329
|
+
|
|
41330
|
+
If two findings or two acceptance criteria contradict each other and you cannot satisfy
|
|
41331
|
+
both even after adjusting tests, do not guess. Emit:
|
|
41332
|
+
UNRESOLVED: <which findings/ACs conflicted and why they cannot both be satisfied>`, CONTRADICTION_ESCAPE_HATCH, MAX_STRUCTURED_FINDINGS = 10, RAW_WITH_FINDINGS_LIMIT = 1000, RAW_FALLBACK_LIMIT = 4000;
|
|
41289
41333
|
var init_rectifier_builder_helpers = __esm(() => {
|
|
41334
|
+
init_config();
|
|
41290
41335
|
init_review();
|
|
41291
41336
|
init_sections2();
|
|
41292
|
-
THREE_SESSION_STRATEGIES = new Set(["three-session-tdd", "three-session-tdd-lite"]);
|
|
41293
41337
|
CONTRADICTION_ESCAPE_HATCH = buildEscapeHatch({ includeMockHandoff: false });
|
|
41294
41338
|
});
|
|
41295
41339
|
|
|
@@ -41375,11 +41419,13 @@ class RectifierPromptBuilder {
|
|
|
41375
41419
|
const parts = [];
|
|
41376
41420
|
const attemptWord = maxAttempts === 1 ? "1 attempt" : `${maxAttempts} attempts`;
|
|
41377
41421
|
const exCount = story ? exceptionCountWord(story) : "three";
|
|
41422
|
+
const prohibition = `Do NOT change test files or test behavior \u2014 see the ${exCount} narrow exceptions appended below.`;
|
|
41423
|
+
const testDirective = story ? testEditHeadline(story, prohibition) : prohibition;
|
|
41378
41424
|
parts.push(`Review failed after your implementation. Fix the following issues (${attemptWord} available before escalation):
|
|
41379
41425
|
`);
|
|
41380
41426
|
parts.push(renderPrioritizedFailures(failedChecks));
|
|
41381
41427
|
parts.push(`
|
|
41382
|
-
Fix in priority order. After fixing each priority, re-run the failing check(s) at that level to verify they pass before moving on.
|
|
41428
|
+
Fix in priority order. After fixing each priority, re-run the failing check(s) at that level to verify they pass before moving on. ${testDirective} Commit your changes when all checks pass.`);
|
|
41383
41429
|
parts.push(story ? escapeHatchFor(story) : CONTRADICTION_ESCAPE_HATCH);
|
|
41384
41430
|
const guardrails = buildBehavioralGuardrailsSection("implementer", guardrailLevel ?? "lite");
|
|
41385
41431
|
if (guardrails) {
|
|
@@ -41642,7 +41688,7 @@ ${testCommands}
|
|
|
41642
41688
|
6. Ensure ALL tests pass before completing.
|
|
41643
41689
|
|
|
41644
41690
|
**IMPORTANT:**
|
|
41645
|
-
- Do NOT modify test files \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below if you believe a test has a lint error, a PRD-contract mismatch, or belongs to a sibling story
|
|
41691
|
+
- ${testEditHeadline(story, `Do NOT modify test files \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below if you believe a test has a lint error, a PRD-contract mismatch, or belongs to a sibling story.`)}
|
|
41646
41692
|
- Do NOT loosen assertions to mask implementation bugs.
|
|
41647
41693
|
- Focus on fixing the source code to meet the test requirements.
|
|
41648
41694
|
- When running tests, run ONLY the failing test files shown above${cmd ? ` \u2014 NEVER run \`${cmd}\` without a file filter` : " \u2014 never run the full test suite without a file filter"}.
|
|
@@ -41742,7 +41788,7 @@ ${errors3}${reasoningSection}${historySection}
|
|
|
41742
41788
|
2. Only fix findings that are actually valid problems
|
|
41743
41789
|
3. Do NOT add keys, functions, or imports that already exist \u2014 check first
|
|
41744
41790
|
|
|
41745
|
-
Do NOT change test files or test behavior \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below
|
|
41791
|
+
${testEditHeadline(story, `Do NOT change test files or test behavior \u2014 see the ${exceptionCountWord(story)} narrow exceptions appended below.`)}
|
|
41746
41792
|
Do NOT add new features \u2014 only fix valid issues.
|
|
41747
41793
|
Commit your fixes when done.${scopeConstraint}${escapeHatchFor(story)}`;
|
|
41748
41794
|
}
|
|
@@ -41836,7 +41882,7 @@ Tests are failing. Fix the source so all tests pass \u2014 not just the ones lis
|
|
|
41836
41882
|
4. Do not declare done until step 3 shows 0 failures.
|
|
41837
41883
|
|
|
41838
41884
|
**IMPORTANT:**
|
|
41839
|
-
- Do NOT modify test files \u2014 see the ${exceptionCountWord(opts.story)} narrow exceptions appended below if you believe a test has a lint error, a PRD-contract mismatch, or belongs to a sibling story
|
|
41885
|
+
- ${testEditHeadline(opts.story, `Do NOT modify test files \u2014 see the ${exceptionCountWord(opts.story)} narrow exceptions appended below if you believe a test has a lint error, a PRD-contract mismatch, or belongs to a sibling story.`)}
|
|
41840
41886
|
- Do NOT loosen assertions to mask implementation bugs.
|
|
41841
41887
|
- Focus on fixing the source code to meet the test requirements.`);
|
|
41842
41888
|
parts.push(escapeHatchFor(opts.story));
|
|
@@ -53401,6 +53447,11 @@ function phasesToRevalidate(strategiesRun, allPhases) {
|
|
|
53401
53447
|
}
|
|
53402
53448
|
return allPhases.filter((p) => needed.has(p.kind));
|
|
53403
53449
|
}
|
|
53450
|
+
function orderGateLast(phases) {
|
|
53451
|
+
const rest = phases.filter((p) => p.kind !== "full-suite-gate");
|
|
53452
|
+
const gates = phases.filter((p) => p.kind === "full-suite-gate");
|
|
53453
|
+
return [...rest, ...gates];
|
|
53454
|
+
}
|
|
53404
53455
|
function toReviewDecisionPayload(opName, output) {
|
|
53405
53456
|
if (output === null || output === undefined || typeof output !== "object")
|
|
53406
53457
|
return null;
|
|
@@ -53615,18 +53666,24 @@ async function runPhase(ctx, slot, phaseCosts, phaseOutputs, isThreeSession = fa
|
|
|
53615
53666
|
scope.close();
|
|
53616
53667
|
}
|
|
53617
53668
|
}
|
|
53618
|
-
function withIncreasingFailuresBail(strategies, enabled) {
|
|
53669
|
+
function withIncreasingFailuresBail(strategies, enabled, consecutiveIncreases) {
|
|
53619
53670
|
if (!enabled)
|
|
53620
53671
|
return strategies;
|
|
53672
|
+
const threshold = Math.max(1, consecutiveIncreases);
|
|
53621
53673
|
return strategies.map((strategy) => ({
|
|
53622
53674
|
...strategy,
|
|
53623
53675
|
bailWhen: (iterations) => {
|
|
53624
53676
|
const userReason = strategy.bailWhen?.(iterations) ?? null;
|
|
53625
53677
|
if (userReason !== null)
|
|
53626
53678
|
return userReason;
|
|
53627
|
-
|
|
53628
|
-
|
|
53629
|
-
|
|
53679
|
+
if (iterations.length < threshold)
|
|
53680
|
+
return null;
|
|
53681
|
+
const trailing = iterations.slice(-threshold);
|
|
53682
|
+
const allRegressed = trailing.every((it) => it.findingsAfter.length > it.findingsBefore.length);
|
|
53683
|
+
if (allRegressed) {
|
|
53684
|
+
const first = trailing[0];
|
|
53685
|
+
const last = trailing[trailing.length - 1];
|
|
53686
|
+
return `failure count increased for ${threshold} consecutive iteration(s): ${first.findingsBefore.length} -> ${last.findingsAfter.length}`;
|
|
53630
53687
|
}
|
|
53631
53688
|
return null;
|
|
53632
53689
|
}
|
|
@@ -53656,13 +53713,14 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
53656
53713
|
const cycle = {
|
|
53657
53714
|
findings: [...initialFindings],
|
|
53658
53715
|
iterations: [],
|
|
53659
|
-
strategies: withIncreasingFailuresBail(rectification.strategies, rectification.abortOnIncreasingFailures),
|
|
53716
|
+
strategies: withIncreasingFailuresBail(rectification.strategies, rectification.abortOnIncreasingFailures, rectification.consecutiveIncreasesToBail ?? 1),
|
|
53660
53717
|
config: { maxAttemptsTotal: rectification.maxAttempts, validatorRetries: 1 },
|
|
53661
53718
|
validate: async (_validateCtx, opts) => {
|
|
53662
53719
|
if (ctx.runtime.signal?.aborted)
|
|
53663
53720
|
return { findings: [], shortCircuited: false };
|
|
53664
53721
|
const lite = (opts?.mode ?? "full") === "lite";
|
|
53665
|
-
const
|
|
53722
|
+
const selected = phasesToRevalidate(opts?.strategiesRun, validationPhases);
|
|
53723
|
+
const phases = lite ? orderGateLast(selected) : selected;
|
|
53666
53724
|
getSafeLogger()?.debug("story-orchestrator", "rectification validate scope", {
|
|
53667
53725
|
storyId: ctx.storyId,
|
|
53668
53726
|
mode: opts?.mode ?? "full",
|
|
@@ -53672,9 +53730,6 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs) {
|
|
|
53672
53730
|
const findings = [];
|
|
53673
53731
|
let shortCircuited = false;
|
|
53674
53732
|
for (const phase of phases) {
|
|
53675
|
-
if (lite && phase.kind === "full-suite-gate") {
|
|
53676
|
-
continue;
|
|
53677
|
-
}
|
|
53678
53733
|
await runPhase(ctx, phase.slot, phaseCosts, phaseOutputs);
|
|
53679
53734
|
if (shouldSkipPhaseForRectification(phase, state, phaseOutputs))
|
|
53680
53735
|
continue;
|
|
@@ -53990,9 +54045,6 @@ var init_story_orchestrator = __esm(() => {
|
|
|
53990
54045
|
|
|
53991
54046
|
// src/execution/build-plan-for-strategy.ts
|
|
53992
54047
|
import { join as join46 } from "path";
|
|
53993
|
-
function isThreeSessionStrategy(strategy) {
|
|
53994
|
-
return THREE_SESSION_STRATEGIES2.has(strategy);
|
|
53995
|
-
}
|
|
53996
54048
|
function requiresInitialRefCapture(strategy) {
|
|
53997
54049
|
return isThreeSessionStrategy(strategy);
|
|
53998
54050
|
}
|
|
@@ -54051,8 +54103,12 @@ async function buildPlanForStrategy(ctx, story, config2, testStrategy, inputs) {
|
|
|
54051
54103
|
strategies.push(makeFullSuiteRectifyStrategy(story, config2));
|
|
54052
54104
|
}
|
|
54053
54105
|
if (config2.quality.autofix?.enabled !== false) {
|
|
54054
|
-
strategies.push(makeAutofixImplementerStrategy(story, config2, sink
|
|
54055
|
-
|
|
54106
|
+
strategies.push(makeAutofixImplementerStrategy(story, config2, sink, {
|
|
54107
|
+
includeAdversarialReview: !isThreeSession
|
|
54108
|
+
}));
|
|
54109
|
+
if (isThreeSession) {
|
|
54110
|
+
strategies.push(makeAutofixTestWriterStrategy(story, config2, sink));
|
|
54111
|
+
}
|
|
54056
54112
|
}
|
|
54057
54113
|
const postValidate = async (findings, _validateCtx) => {
|
|
54058
54114
|
if (sink.testEdits.length === 0 && sink.mockHandoffs.length === 0)
|
|
@@ -54078,14 +54134,13 @@ async function buildPlanForStrategy(ctx, story, config2, testStrategy, inputs) {
|
|
|
54078
54134
|
}
|
|
54079
54135
|
return builder.build(ctx, { isThreeSession });
|
|
54080
54136
|
}
|
|
54081
|
-
var THREE_SESSION_STRATEGIES2;
|
|
54082
54137
|
var init_build_plan_for_strategy = __esm(() => {
|
|
54138
|
+
init_config();
|
|
54083
54139
|
init_operations();
|
|
54084
54140
|
init_execution_gates();
|
|
54085
54141
|
init_full_suite_rectify();
|
|
54086
54142
|
init_test_runners();
|
|
54087
54143
|
init_story_orchestrator();
|
|
54088
|
-
THREE_SESSION_STRATEGIES2 = new Set(["three-session-tdd", "three-session-tdd-lite"]);
|
|
54089
54144
|
});
|
|
54090
54145
|
|
|
54091
54146
|
// src/execution/plan-inputs.ts
|
|
@@ -54285,7 +54340,8 @@ async function assemblePlanInputsFromCtx(ctx) {
|
|
|
54285
54340
|
const rectificationInput = ctx.config.execution?.rectification?.enabled === true ? {
|
|
54286
54341
|
maxAttempts: ctx.config.execution.rectification.maxAttemptsTotal,
|
|
54287
54342
|
strategies: [],
|
|
54288
|
-
abortOnIncreasingFailures: ctx.config.execution.rectification.abortOnIncreasingFailures
|
|
54343
|
+
abortOnIncreasingFailures: ctx.config.execution.rectification.abortOnIncreasingFailures,
|
|
54344
|
+
consecutiveIncreasesToBail: ctx.config.execution.rectification.consecutiveIncreasesToBail
|
|
54289
54345
|
} : undefined;
|
|
54290
54346
|
return {
|
|
54291
54347
|
story,
|
|
@@ -54304,12 +54360,12 @@ async function assemblePlanInputsFromCtx(ctx) {
|
|
|
54304
54360
|
};
|
|
54305
54361
|
}
|
|
54306
54362
|
var init_plan_inputs = __esm(() => {
|
|
54363
|
+
init_config();
|
|
54307
54364
|
init_context();
|
|
54308
54365
|
init_errors();
|
|
54309
54366
|
init_prompts();
|
|
54310
54367
|
init_review();
|
|
54311
54368
|
init_resolver();
|
|
54312
|
-
init_build_plan_for_strategy();
|
|
54313
54369
|
});
|
|
54314
54370
|
|
|
54315
54371
|
// src/pipeline/stages/execution-helpers.ts
|
|
@@ -54836,6 +54892,7 @@ var init_post_run = __esm(() => {
|
|
|
54836
54892
|
// src/pipeline/stages/execution.ts
|
|
54837
54893
|
var RUNTIME_CRASH_CODES, executionStage, _executionDeps;
|
|
54838
54894
|
var init_execution = __esm(() => {
|
|
54895
|
+
init_config();
|
|
54839
54896
|
init_agents();
|
|
54840
54897
|
init_errors();
|
|
54841
54898
|
init_build_plan_for_strategy();
|
|
@@ -58354,7 +58411,7 @@ var package_default;
|
|
|
58354
58411
|
var init_package = __esm(() => {
|
|
58355
58412
|
package_default = {
|
|
58356
58413
|
name: "@nathapp/nax",
|
|
58357
|
-
version: "0.68.
|
|
58414
|
+
version: "0.68.5",
|
|
58358
58415
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
58359
58416
|
type: "module",
|
|
58360
58417
|
bin: {
|
|
@@ -58449,8 +58506,8 @@ var init_version = __esm(() => {
|
|
|
58449
58506
|
NAX_VERSION = package_default.version;
|
|
58450
58507
|
NAX_COMMIT = (() => {
|
|
58451
58508
|
try {
|
|
58452
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
58453
|
-
return "
|
|
58509
|
+
if (/^[0-9a-f]{6,10}$/.test("1056817e"))
|
|
58510
|
+
return "1056817e";
|
|
58454
58511
|
} catch {}
|
|
58455
58512
|
try {
|
|
58456
58513
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -96908,6 +96965,7 @@ var FIELD_DESCRIPTIONS = {
|
|
|
96908
96965
|
"execution.rectification.fullSuiteTimeoutSeconds": "Timeout for full test suite run in seconds",
|
|
96909
96966
|
"execution.rectification.maxFailureSummaryChars": "Max characters in failure summary",
|
|
96910
96967
|
"execution.rectification.abortOnIncreasingFailures": "Abort if failure count increases",
|
|
96968
|
+
"execution.rectification.consecutiveIncreasesToBail": "Consecutive regressing iterations required before abortOnIncreasingFailures bails (default: 2; 1 = legacy behaviour)",
|
|
96911
96969
|
"execution.rectification.escalateOnExhaustion": "Enable model tier escalation when attempts are exhausted with remaining failures",
|
|
96912
96970
|
"execution.rectification.rethinkAtAttempt": "Attempt number at which 'rethink your approach' language is injected into the prompt (default: 2)",
|
|
96913
96971
|
"execution.rectification.urgencyAtAttempt": "Attempt number at which 'final chance before escalation' urgency is added (default: 3)",
|