agentxchain 2.92.0 → 2.94.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/report.js +7 -1
- package/src/commands/status.js +4 -0
- package/src/lib/dispatch-bundle.js +20 -1
- package/src/lib/export.js +20 -0
- package/src/lib/governed-state.js +66 -1
- package/src/lib/repo-decisions.js +100 -0
- package/src/lib/report.js +592 -2
- package/src/lib/schemas/turn-result.schema.json +20 -0
- package/src/lib/turn-result-validator.js +92 -1
|
@@ -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
|
}
|
|
@@ -258,6 +268,16 @@
|
|
|
258
268
|
"items": { "type": "string", "minLength": 1 },
|
|
259
269
|
"minItems": 1,
|
|
260
270
|
"description": "What the delegate must achieve for this delegation to be considered complete."
|
|
271
|
+
},
|
|
272
|
+
"required_decision_ids": {
|
|
273
|
+
"type": "array",
|
|
274
|
+
"items": {
|
|
275
|
+
"type": "string",
|
|
276
|
+
"pattern": "^DEC-\\d+$"
|
|
277
|
+
},
|
|
278
|
+
"minItems": 1,
|
|
279
|
+
"uniqueItems": true,
|
|
280
|
+
"description": "Optional named decisions the delegated child must emit before the parent review turn may advance phase/run lifecycle."
|
|
261
281
|
}
|
|
262
282
|
}
|
|
263
283
|
}
|
|
@@ -263,6 +263,16 @@ function validateSchema(tr) {
|
|
|
263
263
|
}
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
if ('delegations' in tr) {
|
|
267
|
+
if (!Array.isArray(tr.delegations)) {
|
|
268
|
+
errors.push('delegations must be an array.');
|
|
269
|
+
} else {
|
|
270
|
+
for (let i = 0; i < tr.delegations.length; i++) {
|
|
271
|
+
errors.push(...validateDelegation(tr.delegations[i], i));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
266
276
|
errors.push(...collectUnfilledTemplatePlaceholderErrors(tr));
|
|
267
277
|
|
|
268
278
|
return errors;
|
|
@@ -325,6 +335,8 @@ function checkPlaceholder(errors, fieldPath, value) {
|
|
|
325
335
|
}
|
|
326
336
|
}
|
|
327
337
|
|
|
338
|
+
const VALID_DURABILITIES = ['run', 'repo'];
|
|
339
|
+
|
|
328
340
|
function validateDecision(dec, index) {
|
|
329
341
|
const errors = [];
|
|
330
342
|
const prefix = `decisions[${index}]`;
|
|
@@ -344,6 +356,17 @@ function validateDecision(dec, index) {
|
|
|
344
356
|
if (typeof dec.rationale !== 'string' || !dec.rationale.trim()) {
|
|
345
357
|
errors.push(`${prefix}.rationale must be a non-empty string.`);
|
|
346
358
|
}
|
|
359
|
+
if (dec.durability !== undefined && !VALID_DURABILITIES.includes(dec.durability)) {
|
|
360
|
+
errors.push(`${prefix}.durability must be one of: ${VALID_DURABILITIES.join(', ')}.`);
|
|
361
|
+
}
|
|
362
|
+
if (dec.overrides !== undefined) {
|
|
363
|
+
if (typeof dec.overrides !== 'string' || !/^DEC-\d+$/.test(dec.overrides)) {
|
|
364
|
+
errors.push(`${prefix}.overrides must match pattern DEC-NNN.`);
|
|
365
|
+
}
|
|
366
|
+
if (dec.overrides === dec.id) {
|
|
367
|
+
errors.push(`${prefix}.overrides cannot reference itself.`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
347
370
|
return errors;
|
|
348
371
|
}
|
|
349
372
|
|
|
@@ -369,6 +392,54 @@ function validateObjection(obj, index) {
|
|
|
369
392
|
return errors;
|
|
370
393
|
}
|
|
371
394
|
|
|
395
|
+
function validateDelegation(del, index) {
|
|
396
|
+
const errors = [];
|
|
397
|
+
const prefix = `delegations[${index}]`;
|
|
398
|
+
|
|
399
|
+
if (del === null || typeof del !== 'object' || Array.isArray(del)) {
|
|
400
|
+
return [`${prefix} must be an object.`];
|
|
401
|
+
}
|
|
402
|
+
if (typeof del.id !== 'string' || !/^del-\d{3}$/.test(del.id)) {
|
|
403
|
+
errors.push(`${prefix}.id must match pattern del-NNN.`);
|
|
404
|
+
}
|
|
405
|
+
if (typeof del.to_role !== 'string' || !/^[a-z0-9_-]+$/.test(del.to_role)) {
|
|
406
|
+
errors.push(`${prefix}.to_role must match pattern ^[a-z0-9_-]+$.`);
|
|
407
|
+
}
|
|
408
|
+
if (typeof del.charter !== 'string' || !del.charter.trim()) {
|
|
409
|
+
errors.push(`${prefix}.charter must be a non-empty string.`);
|
|
410
|
+
}
|
|
411
|
+
if (!Array.isArray(del.acceptance_contract) || del.acceptance_contract.length === 0) {
|
|
412
|
+
errors.push(`${prefix}.acceptance_contract must be a non-empty array.`);
|
|
413
|
+
} else {
|
|
414
|
+
for (let i = 0; i < del.acceptance_contract.length; i++) {
|
|
415
|
+
if (typeof del.acceptance_contract[i] !== 'string' || !del.acceptance_contract[i].trim()) {
|
|
416
|
+
errors.push(`${prefix}.acceptance_contract[${i}] must be a non-empty string.`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (del.required_decision_ids !== undefined) {
|
|
421
|
+
if (!Array.isArray(del.required_decision_ids) || del.required_decision_ids.length === 0) {
|
|
422
|
+
errors.push(`${prefix}.required_decision_ids must be a non-empty array when provided.`);
|
|
423
|
+
} else {
|
|
424
|
+
const seen = new Set();
|
|
425
|
+
for (let i = 0; i < del.required_decision_ids.length; i++) {
|
|
426
|
+
const id = del.required_decision_ids[i];
|
|
427
|
+
if (typeof id !== 'string' || !/^DEC-\d+$/.test(id)) {
|
|
428
|
+
errors.push(`${prefix}.required_decision_ids[${i}] must match pattern DEC-NNN.`);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
if (seen.has(id)) {
|
|
432
|
+
errors.push(`${prefix}.required_decision_ids contains duplicate "${id}".`);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
seen.add(id);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return errors;
|
|
441
|
+
}
|
|
442
|
+
|
|
372
443
|
// ── Stage B: Assignment Validation ───────────────────────────────────────────
|
|
373
444
|
|
|
374
445
|
function validateAssignment(tr, state) {
|
|
@@ -550,6 +621,7 @@ function validateProtocol(tr, state, config) {
|
|
|
550
621
|
|
|
551
622
|
const role = config.roles?.[tr.role];
|
|
552
623
|
const writeAuthority = role?.write_authority;
|
|
624
|
+
const activeTurn = getActiveTurn(state) || state?.current_turn || null;
|
|
553
625
|
|
|
554
626
|
// Challenge requirement: review_only roles MUST raise at least one objection
|
|
555
627
|
if (config.rules?.challenge_required !== false) {
|
|
@@ -615,7 +687,6 @@ function validateProtocol(tr, state, config) {
|
|
|
615
687
|
}
|
|
616
688
|
|
|
617
689
|
// No recursive delegation: if this turn is a delegation review, it cannot delegate further
|
|
618
|
-
const activeTurn = state?.active_turns ? Object.values(state.active_turns)[0] : null;
|
|
619
690
|
if (activeTurn?.delegation_context) {
|
|
620
691
|
errors.push('Delegation review turns cannot contain further delegations.');
|
|
621
692
|
}
|
|
@@ -650,6 +721,26 @@ function validateProtocol(tr, state, config) {
|
|
|
650
721
|
}
|
|
651
722
|
}
|
|
652
723
|
|
|
724
|
+
if (activeTurn?.delegation_review) {
|
|
725
|
+
const unmetDecisionContracts = (activeTurn.delegation_review.results || [])
|
|
726
|
+
.filter((result) => Array.isArray(result?.missing_decision_ids) && result.missing_decision_ids.length > 0);
|
|
727
|
+
if (unmetDecisionContracts.length > 0) {
|
|
728
|
+
const detail = unmetDecisionContracts
|
|
729
|
+
.map((result) => `${result.delegation_id}: ${result.missing_decision_ids.join(', ')}`)
|
|
730
|
+
.join('; ');
|
|
731
|
+
if (tr.phase_transition_request) {
|
|
732
|
+
errors.push(
|
|
733
|
+
`Delegation review cannot request phase transition while required child decisions are missing: ${detail}.`
|
|
734
|
+
);
|
|
735
|
+
}
|
|
736
|
+
if (tr.run_completion_request) {
|
|
737
|
+
errors.push(
|
|
738
|
+
`Delegation review cannot request run completion while required child decisions are missing: ${detail}.`
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
653
744
|
return { errors, warnings };
|
|
654
745
|
}
|
|
655
746
|
|