agentxchain 2.155.57 → 2.155.59
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
|
@@ -506,6 +506,7 @@ function renderPrompt(role, roleId, turn, state, config, root) {
|
|
|
506
506
|
lines.push('- `verification.status`: **REQUIRED**. One of `pass`, `fail`, `skipped`. Always include this field in the `verification` object.');
|
|
507
507
|
lines.push('- `verification.status: "pass"` is valid only when every `verification.machine_evidence[].exit_code` is `0`, unless a negative-case command explicitly sets `expected_exit_code` to the same non-zero value.');
|
|
508
508
|
lines.push('- Expected-failure checks should be wrapped in a verifier that exits `0` when the failure occurs as expected. If you must record a raw non-zero negative-case command on a passing turn, set `verification.machine_evidence[].expected_exit_code` to the expected non-zero code and explain it in `evidence_summary`.');
|
|
509
|
+
lines.push('- `verification.machine_evidence[]` is only for executable command records with both `command` and `exit_code`. Put typed marker checks, file-grep observations, bucket summaries, and acceptance-contract summaries in `verification.evidence_summary`, not in `machine_evidence`.');
|
|
509
510
|
lines.push('- If verification commands produce side-effect files (e.g., `.tusq/plan.json`, `coverage/`, `.cache/`), declare each in `verification.produced_files` with `disposition: "ignore"` (temporary output to clean up) or `disposition: "artifact"` (output to checkpoint as a turn deliverable). Undeclared dirty files with declared verification will be auto-cleaned but declaring them is preferred.');
|
|
510
511
|
lines.push('- `artifact.type`: **REQUIRED**. One of `workspace`, `patch`, `commit`, `review`.');
|
|
511
512
|
lines.push('- If you make zero repo file edits, set `artifact.type` to `"review"` and `files_changed` to `[]`.');
|
|
@@ -7039,14 +7039,7 @@ function evaluateIntentCoverage(turnResult, intakeContext, { state = null, confi
|
|
|
7039
7039
|
}
|
|
7040
7040
|
|
|
7041
7041
|
// Build a searchable corpus from the turn result for semantic fallback
|
|
7042
|
-
const corpus =
|
|
7043
|
-
turnResult.summary || '',
|
|
7044
|
-
...(turnResult.decisions || []).map(d => `${d.statement || ''} ${d.rationale || ''}`),
|
|
7045
|
-
...(turnResult.objections || []).map(o => o.statement || ''),
|
|
7046
|
-
...(turnResult.files_changed || []),
|
|
7047
|
-
...(turnResult.artifacts_created || []),
|
|
7048
|
-
...(Array.isArray(turnResult.intent_response) ? turnResult.intent_response.map(r => `${r.item || ''} ${r.detail || ''}`) : []),
|
|
7049
|
-
].join('\n').toLowerCase();
|
|
7042
|
+
const corpus = buildIntentCoverageCorpus(turnResult);
|
|
7050
7043
|
|
|
7051
7044
|
for (const item of acceptanceItems) {
|
|
7052
7045
|
const normalizedItem = item.toLowerCase().trim();
|
|
@@ -7085,7 +7078,7 @@ function evaluateIntentCoverage(turnResult, intakeContext, { state = null, confi
|
|
|
7085
7078
|
}
|
|
7086
7079
|
|
|
7087
7080
|
// Check 2: Semantic fallback — significant keyword overlap
|
|
7088
|
-
const words = normalizedItem
|
|
7081
|
+
const words = tokenizeIntentCoverageText(normalizedItem).filter(w => w.length > 3);
|
|
7089
7082
|
if (words.length === 0) {
|
|
7090
7083
|
addressed.push(item);
|
|
7091
7084
|
continue;
|
|
@@ -7204,16 +7197,7 @@ function evaluateRoadmapDerivedConditionalCoverage(item, turnResult, intakeConte
|
|
|
7204
7197
|
const milestoneId = sectionMatch[1].toLowerCase();
|
|
7205
7198
|
|
|
7206
7199
|
// Build a searchable corpus from the turn result
|
|
7207
|
-
const corpus =
|
|
7208
|
-
turnResult.summary || '',
|
|
7209
|
-
...(turnResult.decisions || []).map(d => `${d.statement || ''} ${d.rationale || ''}`),
|
|
7210
|
-
...(turnResult.objections || []).map(o => o.statement || ''),
|
|
7211
|
-
...(turnResult.files_changed || []),
|
|
7212
|
-
...(turnResult.artifacts_created || []),
|
|
7213
|
-
...(Array.isArray(turnResult.intent_response)
|
|
7214
|
-
? turnResult.intent_response.map(r => `${r.item || ''} ${r.detail || ''}`)
|
|
7215
|
-
: []),
|
|
7216
|
-
].join('\n').toLowerCase();
|
|
7200
|
+
const corpus = buildIntentCoverageCorpus(turnResult);
|
|
7217
7201
|
|
|
7218
7202
|
// If the turn mentions the milestone section ID, the item is addressed
|
|
7219
7203
|
return corpus.includes(milestoneId);
|
|
@@ -7244,16 +7228,7 @@ function evaluateRoadmapReplenishmentConditionalCoverage(item, turnResult, intak
|
|
|
7244
7228
|
return null;
|
|
7245
7229
|
}
|
|
7246
7230
|
|
|
7247
|
-
const corpus =
|
|
7248
|
-
turnResult.summary || '',
|
|
7249
|
-
...(turnResult.decisions || []).map(d => `${d.statement || ''} ${d.rationale || ''}`),
|
|
7250
|
-
...(turnResult.objections || []).map(o => o.statement || ''),
|
|
7251
|
-
...(turnResult.files_changed || []),
|
|
7252
|
-
...(turnResult.artifacts_created || []),
|
|
7253
|
-
...(Array.isArray(turnResult.intent_response)
|
|
7254
|
-
? turnResult.intent_response.map(r => `${r.item || ''} ${r.detail || ''}`)
|
|
7255
|
-
: []),
|
|
7256
|
-
].join('\n').toLowerCase();
|
|
7231
|
+
const corpus = buildIntentCoverageCorpus(turnResult);
|
|
7257
7232
|
|
|
7258
7233
|
if (!corpus.includes('vision.md')) {
|
|
7259
7234
|
return false;
|
|
@@ -7275,6 +7250,40 @@ function evaluateRoadmapReplenishmentConditionalCoverage(item, turnResult, intak
|
|
|
7275
7250
|
return sectionNames.some((section) => corpus.includes(section));
|
|
7276
7251
|
}
|
|
7277
7252
|
|
|
7253
|
+
function buildIntentCoverageCorpus(turnResult) {
|
|
7254
|
+
const verification = turnResult?.verification && typeof turnResult.verification === 'object'
|
|
7255
|
+
? turnResult.verification
|
|
7256
|
+
: {};
|
|
7257
|
+
const machineEvidenceText = Array.isArray(verification.machine_evidence)
|
|
7258
|
+
? verification.machine_evidence.map((entry) => {
|
|
7259
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return '';
|
|
7260
|
+
return Object.values(entry).map((value) => {
|
|
7261
|
+
if (typeof value === 'string') return value;
|
|
7262
|
+
if (Array.isArray(value)) return value.join(' ');
|
|
7263
|
+
if (value && typeof value === 'object') return JSON.stringify(value);
|
|
7264
|
+
return '';
|
|
7265
|
+
}).join(' ');
|
|
7266
|
+
})
|
|
7267
|
+
: [];
|
|
7268
|
+
|
|
7269
|
+
return [
|
|
7270
|
+
turnResult.summary || '',
|
|
7271
|
+
...(turnResult.decisions || []).map(d => `${d.statement || ''} ${d.rationale || ''}`),
|
|
7272
|
+
...(turnResult.objections || []).map(o => o.statement || ''),
|
|
7273
|
+
...(turnResult.files_changed || []),
|
|
7274
|
+
...(turnResult.artifacts_created || []),
|
|
7275
|
+
verification.evidence_summary || '',
|
|
7276
|
+
...machineEvidenceText,
|
|
7277
|
+
...(Array.isArray(turnResult.intent_response) ? turnResult.intent_response.map(r => `${r.item || ''} ${r.detail || ''}`) : []),
|
|
7278
|
+
].join('\n').toLowerCase();
|
|
7279
|
+
}
|
|
7280
|
+
|
|
7281
|
+
function tokenizeIntentCoverageText(value) {
|
|
7282
|
+
return String(value || '')
|
|
7283
|
+
.toLowerCase()
|
|
7284
|
+
.match(/[a-z0-9]+/g) || [];
|
|
7285
|
+
}
|
|
7286
|
+
|
|
7278
7287
|
export {
|
|
7279
7288
|
STATE_PATH,
|
|
7280
7289
|
HISTORY_PATH,
|
|
@@ -1364,6 +1364,63 @@ export function normalizeTurnResult(tr, config, context = {}) {
|
|
|
1364
1364
|
normalized.verification = { ...normalized.verification, status: inferredStatus };
|
|
1365
1365
|
}
|
|
1366
1366
|
|
|
1367
|
+
// ── BUG-104: typed marker evidence belongs in evidence_summary ───────
|
|
1368
|
+
// machine_evidence is reserved for executable command records. Some model
|
|
1369
|
+
// turns emit useful structured observations in that array (for example
|
|
1370
|
+
// file_marker_grep objects) without command/exit_code fields. Preserve that
|
|
1371
|
+
// information as summary evidence instead of fabricating shell commands.
|
|
1372
|
+
if (
|
|
1373
|
+
normalized.verification
|
|
1374
|
+
&& typeof normalized.verification === 'object'
|
|
1375
|
+
&& !Array.isArray(normalized.verification)
|
|
1376
|
+
&& Array.isArray(normalized.verification.machine_evidence)
|
|
1377
|
+
) {
|
|
1378
|
+
const keptMachineEvidence = [];
|
|
1379
|
+
const structuredEvidenceSummaries = [];
|
|
1380
|
+
normalized.verification.machine_evidence.forEach((entry, index) => {
|
|
1381
|
+
if (
|
|
1382
|
+
entry
|
|
1383
|
+
&& typeof entry === 'object'
|
|
1384
|
+
&& !Array.isArray(entry)
|
|
1385
|
+
&& typeof entry.command === 'string'
|
|
1386
|
+
&& entry.command.trim()
|
|
1387
|
+
&& Number.isInteger(entry.exit_code)
|
|
1388
|
+
) {
|
|
1389
|
+
keptMachineEvidence.push(entry);
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
const summary = summarizeStructuredMachineEvidence(entry);
|
|
1394
|
+
if (!summary) {
|
|
1395
|
+
keptMachineEvidence.push(entry);
|
|
1396
|
+
return;
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
structuredEvidenceSummaries.push(summary);
|
|
1400
|
+
corrections.push(`verification.machine_evidence[${index}]: moved structured ${summary.type} evidence into evidence_summary`);
|
|
1401
|
+
normalizationEvents.push({
|
|
1402
|
+
field: `verification.machine_evidence[${index}]`,
|
|
1403
|
+
original_value: entry,
|
|
1404
|
+
normalized_value: summary.text,
|
|
1405
|
+
rationale: 'structured_machine_evidence_moved_to_evidence_summary',
|
|
1406
|
+
});
|
|
1407
|
+
});
|
|
1408
|
+
|
|
1409
|
+
if (structuredEvidenceSummaries.length > 0) {
|
|
1410
|
+
const existingSummary = typeof normalized.verification.evidence_summary === 'string'
|
|
1411
|
+
? normalized.verification.evidence_summary.trim()
|
|
1412
|
+
: '';
|
|
1413
|
+
const appendedSummary = structuredEvidenceSummaries.map((summary) => summary.text).join('; ');
|
|
1414
|
+
normalized.verification = {
|
|
1415
|
+
...normalized.verification,
|
|
1416
|
+
machine_evidence: keptMachineEvidence,
|
|
1417
|
+
evidence_summary: existingSummary
|
|
1418
|
+
? `${existingSummary}\nStructured evidence: ${appendedSummary}`
|
|
1419
|
+
: `Structured evidence: ${appendedSummary}`,
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1367
1424
|
// ── BUG-90: normalize missing artifact.type ─────────────────────────
|
|
1368
1425
|
if (
|
|
1369
1426
|
normalized.artifact
|
|
@@ -1742,6 +1799,42 @@ export function normalizeTurnResult(tr, config, context = {}) {
|
|
|
1742
1799
|
return { normalized, corrections, normalizationEvents };
|
|
1743
1800
|
}
|
|
1744
1801
|
|
|
1802
|
+
function summarizeStructuredMachineEvidence(entry) {
|
|
1803
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
1804
|
+
return null;
|
|
1805
|
+
}
|
|
1806
|
+
if (typeof entry.type !== 'string' || entry.type.trim().length === 0) {
|
|
1807
|
+
return null;
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
const type = entry.type.trim();
|
|
1811
|
+
const parts = [`type=${type}`];
|
|
1812
|
+
for (const key of ['path', 'marker', 'section', 'result']) {
|
|
1813
|
+
if (typeof entry[key] === 'string' && entry[key].trim()) {
|
|
1814
|
+
parts.push(`${key}=${truncateEvidenceValue(entry[key].trim())}`);
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
if (Array.isArray(entry.contract) && entry.contract.length > 0) {
|
|
1818
|
+
parts.push(`contract=${truncateEvidenceValue(entry.contract.join(' | '))}`);
|
|
1819
|
+
}
|
|
1820
|
+
if (
|
|
1821
|
+
entry.buckets_observed
|
|
1822
|
+
&& typeof entry.buckets_observed === 'object'
|
|
1823
|
+
&& !Array.isArray(entry.buckets_observed)
|
|
1824
|
+
) {
|
|
1825
|
+
parts.push(`buckets_observed=${truncateEvidenceValue(JSON.stringify(entry.buckets_observed))}`);
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
return {
|
|
1829
|
+
type,
|
|
1830
|
+
text: `[${parts.join(', ')}]`,
|
|
1831
|
+
};
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
function truncateEvidenceValue(value, max = 220) {
|
|
1835
|
+
return value.length > max ? `${value.slice(0, max - 3)}...` : value;
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1745
1838
|
function normalizeIdleExpansionMutualExclusionSentinel(result) {
|
|
1746
1839
|
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
1747
1840
|
return { changed: false, value: result, correction: '' };
|