agentxchain 2.42.0 → 2.43.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/package.json +1 -1
- package/src/lib/turn-result-validator.js +21 -11
package/package.json
CHANGED
|
@@ -660,29 +660,39 @@ export function normalizeTurnResult(tr, config, context = {}) {
|
|
|
660
660
|
}
|
|
661
661
|
}
|
|
662
662
|
|
|
663
|
-
// ── Rule 3: review_only
|
|
663
|
+
// ── Rule 3: review_only needs_human → lifecycle correction ──────────
|
|
664
|
+
// review_only roles cannot perform work that genuinely requires human
|
|
665
|
+
// intervention. If the model says "needs_human" with an affirmative,
|
|
666
|
+
// non-blocker reason, correct to the appropriate lifecycle signal:
|
|
667
|
+
// terminal phase → run_completion_request, non-terminal → phase_transition.
|
|
664
668
|
if (
|
|
665
669
|
context.writeAuthority === 'review_only' &&
|
|
666
670
|
context.phase &&
|
|
667
671
|
routing &&
|
|
668
672
|
normalized.status === 'needs_human' &&
|
|
669
|
-
normalized.run_completion_request !== false
|
|
673
|
+
normalized.run_completion_request !== false &&
|
|
674
|
+
typeof normalized.needs_human_reason === 'string'
|
|
670
675
|
) {
|
|
671
|
-
const
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
const isBlocker = blockerSignals.test(reason);
|
|
679
|
-
if (isAffirmative && !isBlocker) {
|
|
676
|
+
const reason = normalized.needs_human_reason.toLowerCase();
|
|
677
|
+
const affirmativeSignals = /\b(approv|ship|release|sign.?off|no.?block|ready|pass|good|accept|green.?light|proceed|move.?forward|complet|done|lgtm|satisf|recommend)\b/i;
|
|
678
|
+
const blockerSignals = /\b(critical|security|fail|block|cannot|must.?fix|regression|vulnerab|reject|unsafe|broken)\b/i;
|
|
679
|
+
const isAffirmative = affirmativeSignals.test(reason);
|
|
680
|
+
const isBlocker = blockerSignals.test(reason);
|
|
681
|
+
if (isAffirmative && !isBlocker) {
|
|
682
|
+
if (isTerminalPhase) {
|
|
680
683
|
corrections.push(
|
|
681
684
|
`status: corrected review_only terminal "needs_human" to run_completion_request — reason indicated ship readiness ("${normalized.needs_human_reason.slice(0, 80)}"), not a genuine blocker`
|
|
682
685
|
);
|
|
683
686
|
normalized.status = 'completed';
|
|
684
687
|
normalized.run_completion_request = true;
|
|
685
688
|
delete normalized.needs_human_reason;
|
|
689
|
+
} else if (nextPhase) {
|
|
690
|
+
corrections.push(
|
|
691
|
+
`status: corrected review_only "needs_human" to phase_transition_request "${nextPhase}" — reason indicated forward progress ("${normalized.needs_human_reason.slice(0, 80)}"), not a genuine blocker`
|
|
692
|
+
);
|
|
693
|
+
normalized.status = 'completed';
|
|
694
|
+
normalized.phase_transition_request = nextPhase;
|
|
695
|
+
delete normalized.needs_human_reason;
|
|
686
696
|
}
|
|
687
697
|
}
|
|
688
698
|
}
|