agentxchain 2.91.0 → 2.93.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/bin/agentxchain.js +12 -2
- package/package.json +1 -1
- package/src/commands/audit.js +7 -1
- package/src/commands/decisions.js +94 -0
- package/src/commands/doctor.js +19 -1
- package/src/commands/report.js +7 -1
- package/src/commands/status.js +14 -0
- package/src/lib/adapters/local-cli-adapter.js +1 -1
- package/src/lib/dispatch-bundle.js +9 -0
- package/src/lib/export.js +60 -0
- package/src/lib/governed-state.js +135 -3
- package/src/lib/repo-decisions.js +100 -0
- package/src/lib/repo-observer.js +39 -5
- package/src/lib/report.js +618 -0
- package/src/lib/run-loop.js +16 -0
- package/src/lib/schemas/turn-result.schema.json +10 -0
- package/src/lib/turn-result-validator.js +13 -0
package/src/lib/run-loop.js
CHANGED
|
@@ -217,7 +217,16 @@ async function executeParallelTurns(root, config, state, maxConcurrent, callback
|
|
|
217
217
|
|
|
218
218
|
// If selectRole returns a role we already tried (or assigned), try
|
|
219
219
|
// other eligible roles from the routing before giving up.
|
|
220
|
+
// Exception: when delegation queue is driving resolution, do not fill
|
|
221
|
+
// extra slots with non-delegation roles via the fallback — those roles
|
|
222
|
+
// would execute without delegation context and corrupt the lifecycle.
|
|
220
223
|
if (triedRoles.has(roleId)) {
|
|
224
|
+
const hasPendingDelegations = Array.isArray(state?.delegation_queue) &&
|
|
225
|
+
state.delegation_queue.some(d => d.status === 'pending' || d.status === 'active');
|
|
226
|
+
const hasPendingReview = !!state?.pending_delegation_review;
|
|
227
|
+
if (hasPendingDelegations || hasPendingReview) {
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
221
230
|
const phase = state.phase;
|
|
222
231
|
const allowed = config?.routing?.[phase]?.allowed_next_roles || [];
|
|
223
232
|
const alternateFound = allowed.some((alt) => {
|
|
@@ -248,6 +257,13 @@ async function executeParallelTurns(root, config, state, maxConcurrent, callback
|
|
|
248
257
|
turnsToDispatch.push({ turn: assignResult.turn, state: assignResult.state });
|
|
249
258
|
emit({ type: 'turn_assigned', turn: assignResult.turn, role: roleId, state: assignResult.state });
|
|
250
259
|
|
|
260
|
+
// Delegation review is a coordination checkpoint — do not fill additional
|
|
261
|
+
// slots alongside it. The review must execute alone so it can assess all
|
|
262
|
+
// delegation results before the run continues.
|
|
263
|
+
if (assignResult.turn.delegation_review) {
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
|
|
251
267
|
// Reload state after assignment to get accurate active count
|
|
252
268
|
state = loadState(root, config);
|
|
253
269
|
activeCount = getActiveTurnCount(state);
|
|
@@ -76,6 +76,16 @@
|
|
|
76
76
|
"rationale": {
|
|
77
77
|
"type": "string",
|
|
78
78
|
"minLength": 1
|
|
79
|
+
},
|
|
80
|
+
"durability": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"enum": ["run", "repo"],
|
|
83
|
+
"description": "Decision persistence scope. 'run' (default) dies with the run; 'repo' persists across runs as a binding constraint."
|
|
84
|
+
},
|
|
85
|
+
"overrides": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"pattern": "^DEC-\\d+$",
|
|
88
|
+
"description": "ID of an active repo-durable decision this decision supersedes."
|
|
79
89
|
}
|
|
80
90
|
}
|
|
81
91
|
}
|
|
@@ -325,6 +325,8 @@ function checkPlaceholder(errors, fieldPath, value) {
|
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
327
|
|
|
328
|
+
const VALID_DURABILITIES = ['run', 'repo'];
|
|
329
|
+
|
|
328
330
|
function validateDecision(dec, index) {
|
|
329
331
|
const errors = [];
|
|
330
332
|
const prefix = `decisions[${index}]`;
|
|
@@ -344,6 +346,17 @@ function validateDecision(dec, index) {
|
|
|
344
346
|
if (typeof dec.rationale !== 'string' || !dec.rationale.trim()) {
|
|
345
347
|
errors.push(`${prefix}.rationale must be a non-empty string.`);
|
|
346
348
|
}
|
|
349
|
+
if (dec.durability !== undefined && !VALID_DURABILITIES.includes(dec.durability)) {
|
|
350
|
+
errors.push(`${prefix}.durability must be one of: ${VALID_DURABILITIES.join(', ')}.`);
|
|
351
|
+
}
|
|
352
|
+
if (dec.overrides !== undefined) {
|
|
353
|
+
if (typeof dec.overrides !== 'string' || !/^DEC-\d+$/.test(dec.overrides)) {
|
|
354
|
+
errors.push(`${prefix}.overrides must match pattern DEC-NNN.`);
|
|
355
|
+
}
|
|
356
|
+
if (dec.overrides === dec.id) {
|
|
357
|
+
errors.push(`${prefix}.overrides cannot reference itself.`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
347
360
|
return errors;
|
|
348
361
|
}
|
|
349
362
|
|