agentxchain 2.155.71 → 2.155.73
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/README.md +4 -8
- package/package.json +5 -6
- package/scripts/migrate-node-test-to-vitest.mjs +98 -0
- package/scripts/release-postflight.sh +1 -1
- package/scripts/release-preflight.sh +5 -5
- package/scripts/verify-post-publish.sh +1 -1
- package/src/commands/run.js +3 -0
- package/src/commands/step.js +47 -1
- package/src/lib/adapters/local-cli-adapter.js +179 -2
- package/src/lib/claude-local-auth.js +14 -0
- package/src/lib/continuous-run.js +42 -3
- package/src/lib/dispatch-bundle.js +7 -3
- package/src/lib/dispatch-progress.js +9 -0
- package/src/lib/governed-state.js +4 -3
- package/src/lib/normalized-config.js +2 -0
- package/src/lib/recovery-classification.js +158 -0
- package/src/lib/report.js +91 -0
- package/src/lib/run-events.js +7 -1
- package/src/lib/schemas/agentxchain-config.schema.json +10 -0
- package/src/lib/turn-checkpoint.js +12 -3
- package/src/lib/turn-result-validator.js +42 -6
- package/src/lib/vision-reader.js +11 -1
|
@@ -138,7 +138,7 @@ export function validateStagedTurnResult(root, state, config, opts = {}) {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
// ── Stage C: Artifact Validation ───────────────────────────────────────
|
|
141
|
-
const artifactResult = validateArtifact(turnResult, config);
|
|
141
|
+
const artifactResult = validateArtifact(turnResult, config, state);
|
|
142
142
|
if (artifactResult.errors.length > 0) {
|
|
143
143
|
return result('artifact', 'artifact_error', artifactResult.errors, artifactResult.warnings);
|
|
144
144
|
}
|
|
@@ -670,7 +670,7 @@ function validateAssignment(tr, state) {
|
|
|
670
670
|
|
|
671
671
|
// ── Stage C: Artifact Validation ─────────────────────────────────────────────
|
|
672
672
|
|
|
673
|
-
function validateArtifact(tr, config) {
|
|
673
|
+
function validateArtifact(tr, config, state = null) {
|
|
674
674
|
const errors = [];
|
|
675
675
|
const warnings = [];
|
|
676
676
|
|
|
@@ -699,6 +699,11 @@ function validateArtifact(tr, config) {
|
|
|
699
699
|
`Artifact type "workspace" requires authoritative write authority, but role "${tr.role}" has "${writeAuthority}".`
|
|
700
700
|
);
|
|
701
701
|
}
|
|
702
|
+
if ((tr.files_changed || []).length === 0 && !hasCheckpointableProducedFiles(tr)) {
|
|
703
|
+
errors.push(
|
|
704
|
+
'artifact.type: "workspace" but files_changed is empty. Use artifact type "review" for no-edit turns, or declare checkpointable verification.produced_files entries with disposition "artifact".'
|
|
705
|
+
);
|
|
706
|
+
}
|
|
702
707
|
}
|
|
703
708
|
|
|
704
709
|
// Check for reserved path modifications
|
|
@@ -722,9 +727,17 @@ function validateArtifact(tr, config) {
|
|
|
722
727
|
}
|
|
723
728
|
}
|
|
724
729
|
|
|
725
|
-
//
|
|
726
|
-
|
|
727
|
-
|
|
730
|
+
// Implementation-phase completion must be backed by actual product code
|
|
731
|
+
// changes. Planning/review artifacts are supplementary and should not satisfy
|
|
732
|
+
// the implementation_complete gate by themselves.
|
|
733
|
+
if (writeAuthority === 'authoritative' && state?.phase === 'implementation' && tr.status === 'completed') {
|
|
734
|
+
const productFiles = (tr.files_changed || []).filter(f => isProductChangePath(f));
|
|
735
|
+
if (productFiles.length === 0) {
|
|
736
|
+
errors.push(
|
|
737
|
+
`Role "${tr.role}" completed an implementation turn without product code changes in files_changed. ` +
|
|
738
|
+
'Implementation-phase completion requires at least one non-planning, non-review repo path; planning artifacts alone are not sufficient.'
|
|
739
|
+
);
|
|
740
|
+
}
|
|
728
741
|
}
|
|
729
742
|
|
|
730
743
|
// Validate proposed_changes for proposed runtimes that cannot write repo files directly.
|
|
@@ -772,6 +785,24 @@ function isAllowedReviewPath(filePath) {
|
|
|
772
785
|
return filePath.startsWith('.planning/') || filePath.startsWith('.agentxchain/reviews/');
|
|
773
786
|
}
|
|
774
787
|
|
|
788
|
+
function isProductChangePath(filePath) {
|
|
789
|
+
return typeof filePath === 'string'
|
|
790
|
+
&& filePath.trim().length > 0
|
|
791
|
+
&& !isAllowedReviewPath(filePath)
|
|
792
|
+
&& !filePath.startsWith('.agentxchain/staging/');
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
function hasCheckpointableProducedFiles(tr) {
|
|
796
|
+
return Array.isArray(tr.verification?.produced_files)
|
|
797
|
+
&& tr.verification.produced_files.some((entry) => (
|
|
798
|
+
entry
|
|
799
|
+
&& typeof entry === 'object'
|
|
800
|
+
&& typeof entry.path === 'string'
|
|
801
|
+
&& entry.path.trim()
|
|
802
|
+
&& (entry.disposition == null || entry.disposition === 'artifact')
|
|
803
|
+
));
|
|
804
|
+
}
|
|
805
|
+
|
|
775
806
|
// ── Stage D: Verification Validation ─────────────────────────────────────────
|
|
776
807
|
|
|
777
808
|
function validateVerification(tr) {
|
|
@@ -1488,7 +1519,12 @@ export function normalizeTurnResult(tr, config, context = {}) {
|
|
|
1488
1519
|
&& !Array.isArray(normalized.artifact)
|
|
1489
1520
|
&& normalized.artifact.type === 'workspace'
|
|
1490
1521
|
&& filesChangedIsEmpty
|
|
1491
|
-
&& (
|
|
1522
|
+
&& !hasCheckpointableProducedFiles(normalized)
|
|
1523
|
+
&& (
|
|
1524
|
+
context.forceReviewArtifact
|
|
1525
|
+
|| hasExplicitNoEditLifecycleSignal
|
|
1526
|
+
|| (normalized.status === 'needs_human' && normalized.proposed_next_role === 'human')
|
|
1527
|
+
)
|
|
1492
1528
|
) {
|
|
1493
1529
|
normalized.artifact = {
|
|
1494
1530
|
...normalized.artifact,
|
package/src/lib/vision-reader.js
CHANGED
|
@@ -15,6 +15,13 @@ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
|
15
15
|
import { join, resolve as pathResolve, isAbsolute } from 'node:path';
|
|
16
16
|
import { createHash } from 'node:crypto';
|
|
17
17
|
|
|
18
|
+
const ROADMAP_TRACKING_ANNOTATION_PATTERN = /<!--\s*tracking\s*:[\s\S]*?-->/i;
|
|
19
|
+
|
|
20
|
+
export function stripRoadmapTrackingAnnotations(text) {
|
|
21
|
+
if (typeof text !== 'string') return '';
|
|
22
|
+
return text.replace(ROADMAP_TRACKING_ANNOTATION_PATTERN, '').replace(/\s+/g, ' ').trim();
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
// ---------------------------------------------------------------------------
|
|
19
26
|
// Parsing
|
|
20
27
|
// ---------------------------------------------------------------------------
|
|
@@ -259,8 +266,10 @@ export function deriveRoadmapCandidates(root, roadmapPath = '.planning/ROADMAP.m
|
|
|
259
266
|
|
|
260
267
|
const uncheckedMatch = line.match(/^\s*[-*]\s+\[\s\]\s+(.+?)\s*$/);
|
|
261
268
|
if (!uncheckedMatch || !currentMilestone) continue;
|
|
269
|
+
if (ROADMAP_TRACKING_ANNOTATION_PATTERN.test(line)) continue;
|
|
262
270
|
|
|
263
|
-
const goal = uncheckedMatch[1]
|
|
271
|
+
const goal = stripRoadmapTrackingAnnotations(uncheckedMatch[1]);
|
|
272
|
+
if (!goal) continue;
|
|
264
273
|
const combinedGoal = `${currentMilestone}: ${goal}`;
|
|
265
274
|
if (isGoalAddressed(combinedGoal, allSignals) || isGoalAddressed(goal, allSignals)) {
|
|
266
275
|
continue;
|
|
@@ -484,6 +493,7 @@ export function detectRoadmapExhaustedVisionOpen(root, visionPath, roadmapPath =
|
|
|
484
493
|
continue;
|
|
485
494
|
}
|
|
486
495
|
if (currentMilestone && /^\s*[-*]\s+\[\s\]/.test(line)) {
|
|
496
|
+
if (ROADMAP_TRACKING_ANNOTATION_PATTERN.test(line)) continue;
|
|
487
497
|
hasUnchecked = true;
|
|
488
498
|
}
|
|
489
499
|
}
|