@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.
Files changed (2) hide show
  1. package/dist/nax.js +108 -50
  2. 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: "fresh" },
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: "fresh" },
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 THREE_SESSION_STRATEGIES.has(story.routing?.testStrategy ?? "") ? "four" : "three";
41105
+ return isThreeSessionStrategy(story.routing?.testStrategy) ? "four" : "three";
41082
41106
  }
41083
41107
  function escapeHatchFor(story) {
41084
- const isTdd = THREE_SESSION_STRATEGIES.has(story.routing?.testStrategy ?? "");
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
- 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.
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.`, THREE_SESSION_STRATEGIES, CONTRADICTION_ESCAPE_HATCH, MAX_STRUCTURED_FINDINGS = 10, RAW_WITH_FINDINGS_LIMIT = 1000, RAW_FALLBACK_LIMIT = 4000;
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. Do NOT change test files or test behavior \u2014 see the ${exCount} narrow exceptions appended below. Commit your changes when all checks pass.`);
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
- const last = iterations[iterations.length - 1];
53628
- if (last && last.findingsAfter.length > last.findingsBefore.length) {
53629
- return `failure count increased: ${last.findingsBefore.length} -> ${last.findingsAfter.length}`;
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 phases = phasesToRevalidate(opts?.strategiesRun, validationPhases);
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
- strategies.push(makeAutofixTestWriterStrategy(story, config2, sink));
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.3",
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("a1007103"))
58453
- return "a1007103";
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)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nathapp/nax",
3
- "version": "0.68.3",
3
+ "version": "0.68.5",
4
4
  "description": "AI Coding Agent Orchestrator — loops until done",
5
5
  "type": "module",
6
6
  "bin": {