agentxchain 2.155.14 → 2.155.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentxchain",
3
- "version": "2.155.14",
3
+ "version": "2.155.16",
4
4
  "description": "CLI for AgentXchain — governed multi-agent software delivery",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4497,11 +4497,14 @@ function _acceptGovernedTurnLocked(root, config, opts) {
4497
4497
  }
4498
4498
  }
4499
4499
 
4500
+ const idleExpansionResultSummary = summarizeIdleExpansionResult(turnResult);
4501
+ const isIdleExpansionNewIntakeProposal = idleExpansionResultSummary?.kind === 'new_intake_intent';
4502
+
4500
4503
  // ── Gate semantic coverage validation (BUG-36) ────────────────────────────
4501
4504
  // When a turn proposes a phase transition, pre-evaluate the gate. If the gate
4502
4505
  // would fail AND the failing files are not in files_changed, reject the turn
4503
4506
  // early — the agent didn't do the work required for the transition.
4504
- if (turnResult.phase_transition_request) {
4507
+ if (turnResult.phase_transition_request && !isIdleExpansionNewIntakeProposal) {
4505
4508
  const preGateResult = evaluatePhaseExit({
4506
4509
  state,
4507
4510
  config,
@@ -4885,7 +4888,6 @@ function _acceptGovernedTurnLocked(root, config, opts) {
4885
4888
  }
4886
4889
 
4887
4890
  const acceptedSequence = (state.turn_sequence || 0) + 1;
4888
- const idleExpansionResultSummary = summarizeIdleExpansionResult(turnResult);
4889
4891
  const historyEntry = {
4890
4892
  turn_id: turnResult.turn_id,
4891
4893
  run_id: turnResult.run_id,
@@ -5023,17 +5025,21 @@ function _acceptGovernedTurnLocked(root, config, opts) {
5023
5025
  const remainingReservations = { ...(state.budget_reservations || {}) };
5024
5026
  delete remainingReservations[currentTurn.turn_id];
5025
5027
  const costUsd = turnResult.cost?.usd || 0;
5028
+ const isIdleExpansionNewIntake = idleExpansionResultSummary?.kind === 'new_intake_intent';
5029
+ const suppressIdleExpansionNeedsHuman = isIdleExpansionNewIntake && turnResult.status === 'needs_human';
5026
5030
  let updatedState = {
5027
5031
  ...state,
5028
5032
  turn_sequence: acceptedSequence,
5029
5033
  last_completed_turn_id: currentTurn.turn_id,
5030
5034
  active_turns: remainingTurns,
5031
5035
  budget_reservations: remainingReservations,
5032
- blocked_on: turnResult.status === 'needs_human' ? `human:${turnResult.needs_human_reason || 'unspecified'}` : null,
5036
+ blocked_on: turnResult.status === 'needs_human' && !suppressIdleExpansionNeedsHuman ? `human:${turnResult.needs_human_reason || 'unspecified'}` : null,
5033
5037
  blocked_reason: null,
5034
5038
  escalation: null,
5035
5039
  accepted_integration_ref: derivedRef,
5036
- next_recommended_role: deriveNextRecommendedRole(turnResult, state, config),
5040
+ next_recommended_role: suppressIdleExpansionNeedsHuman
5041
+ ? currentTurn.assigned_role
5042
+ : deriveNextRecommendedRole(turnResult, state, config),
5037
5043
  budget_status: {
5038
5044
  ...(state.budget_status || {}),
5039
5045
  spent_usd: (state.budget_status?.spent_usd || 0) + costUsd,
@@ -5153,7 +5159,7 @@ function _acceptGovernedTurnLocked(root, config, opts) {
5153
5159
  updatedState.escalation = null;
5154
5160
  }
5155
5161
 
5156
- if (turnResult.status === 'needs_human') {
5162
+ if (turnResult.status === 'needs_human' && !suppressIdleExpansionNeedsHuman) {
5157
5163
  updatedState.status = 'blocked';
5158
5164
  updatedState.blocked_reason = buildBlockedReason({
5159
5165
  category: 'needs_human',
@@ -5223,11 +5229,11 @@ function _acceptGovernedTurnLocked(root, config, opts) {
5223
5229
  let completionResult = null;
5224
5230
  let timeoutResult = null;
5225
5231
 
5226
- // BUG-70: idle-expansion new_intake_intent is a proposal, not a chartered plan.
5227
- // Suppress phase_transition_request the new intake must be materialized into
5228
- // planning artifacts by a subsequent turn before implementation can proceed.
5229
- const isIdleExpansionNewIntake = idleExpansionResultSummary?.kind === 'new_intake_intent';
5230
- if (isIdleExpansionNewIntake && turnResult.phase_transition_request) {
5232
+ // BUG-70/71: idle-expansion new_intake_intent is a proposal, not a chartered plan.
5233
+ // Suppress phase_transition_request and human-only intake approval escalations
5234
+ // the new intake must be materialized into planning artifacts by a subsequent
5235
+ // planning turn before implementation can proceed.
5236
+ if (isIdleExpansionNewIntake && (turnResult.phase_transition_request || suppressIdleExpansionNeedsHuman)) {
5231
5237
  const rawIdleResult = turnResult.idle_expansion_result;
5232
5238
  updatedState.charter_materialization_pending = {
5233
5239
  charter: rawIdleResult?.new_intake_intent?.charter
@@ -5235,7 +5241,7 @@ function _acceptGovernedTurnLocked(root, config, opts) {
5235
5241
  || null,
5236
5242
  acceptance_contract: rawIdleResult?.new_intake_intent?.acceptance_contract
5237
5243
  || [],
5238
- suppressed_transition: turnResult.phase_transition_request,
5244
+ suppressed_transition: turnResult.phase_transition_request || 'implementation',
5239
5245
  source_turn_id: turnResult.turn_id,
5240
5246
  recorded_at: now,
5241
5247
  };
@@ -5245,9 +5251,10 @@ function _acceptGovernedTurnLocked(root, config, opts) {
5245
5251
  status: updatedState.status,
5246
5252
  turn: { turn_id: currentTurn.turn_id, role_id: currentTurn.assigned_role },
5247
5253
  payload: {
5248
- suppressed_transition: turnResult.phase_transition_request,
5254
+ suppressed_transition: turnResult.phase_transition_request || 'implementation',
5249
5255
  reason: 'New intake from idle expansion must be materialized into planning artifacts before implementation dispatch.',
5250
5256
  new_intake_charter: updatedState.charter_materialization_pending.charter,
5257
+ suppressed_needs_human: suppressIdleExpansionNeedsHuman,
5251
5258
  },
5252
5259
  });
5253
5260
  }
@@ -5259,7 +5266,7 @@ function _acceptGovernedTurnLocked(root, config, opts) {
5259
5266
  }
5260
5267
 
5261
5268
  const hasRemainingTurns = Object.keys(remainingTurns).length > 0;
5262
- if (turnResult.status !== 'needs_human') {
5269
+ if (turnResult.status !== 'needs_human' || suppressIdleExpansionNeedsHuman) {
5263
5270
  if (hasRemainingTurns) {
5264
5271
  if (turnResult.run_completion_request && !updatedState.queued_run_completion) {
5265
5272
  updatedState.queued_run_completion = {