@farmslot/agent-runtime 0.27.0 → 0.28.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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
- Active-development baseline; add user-facing changes here before release or package publication.
|
|
6
6
|
|
|
7
|
+
## 0.28.0 - 2026-10-16
|
|
8
|
+
|
|
9
|
+
- Accept qualified parent proof references during PR-follow-up closeout while preserving explicit fresh-proof requirements.
|
|
10
|
+
|
|
7
11
|
## 0.27.0 - 2026-10-16
|
|
8
12
|
|
|
9
13
|
- Capture validated native review results on the completed command without treating streamed text as proof.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farmslot/agent-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"test:branch-maintenance-live": "node --import tsx --test test/branch-maintenance-live.mts"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@farmslot/adapter-sdk": "0.17.
|
|
64
|
-
"@farmslot/protocol": "0.
|
|
63
|
+
"@farmslot/adapter-sdk": "0.17.1",
|
|
64
|
+
"@farmslot/protocol": "0.53.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"@types/node": "^22.0.0",
|
|
@@ -16,10 +16,13 @@ const { atomicWrite, readJson } = require('./mark-io.cjs');
|
|
|
16
16
|
const HANDOFF_INPUT = path.join('inputs', 'handoff.json');
|
|
17
17
|
const {
|
|
18
18
|
ACCEPTANCE_STATUS_ARTIFACT,
|
|
19
|
+
INHERITED_ACCEPTANCE_INPUT,
|
|
19
20
|
ACCEPTANCE_VERDICTS,
|
|
20
21
|
ACCEPTANCE_PROOF_MODES,
|
|
21
22
|
ACCEPTANCE_CRITERION_ID_PATTERN,
|
|
22
23
|
acceptanceCriterionId,
|
|
24
|
+
acceptanceCriteriaMatch,
|
|
25
|
+
registeredAcceptanceCriteria,
|
|
23
26
|
validateAcceptanceStatusLedger,
|
|
24
27
|
acceptanceCriteriaView,
|
|
25
28
|
summarizeAcceptanceStatus,
|
|
@@ -59,9 +62,7 @@ function handoffAcceptanceCriteria(taskDir) {
|
|
|
59
62
|
function criteriaFromHandoff(handoff) {
|
|
60
63
|
const task = isRecord(handoff.task) ? handoff.task : {};
|
|
61
64
|
const criteria = Array.isArray(task.acceptanceCriteria) ? task.acceptanceCriteria : [];
|
|
62
|
-
return criteria
|
|
63
|
-
.map((text, index) => ({ id: acceptanceCriterionId(index), text: String(text) }))
|
|
64
|
-
.filter((criterion) => criterion.text.trim().length > 0);
|
|
65
|
+
return registeredAcceptanceCriteria(criteria);
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
/**
|
|
@@ -198,6 +199,40 @@ function acceptanceContractIssues(taskDir, options = {}) {
|
|
|
198
199
|
return [err.message];
|
|
199
200
|
}
|
|
200
201
|
if (criteria.length === 0) return [];
|
|
202
|
+
// This is a cached qualification, not a new verdict or publication authority.
|
|
203
|
+
// The gateway independently checks the approved original parent at completion.
|
|
204
|
+
if (!options.requireFresh && fs.existsSync(path.join(taskDir, INHERITED_ACCEPTANCE_INPUT))) {
|
|
205
|
+
let reference;
|
|
206
|
+
let handoff;
|
|
207
|
+
try {
|
|
208
|
+
reference = readJson(path.join(taskDir, INHERITED_ACCEPTANCE_INPUT));
|
|
209
|
+
handoff = readJson(path.join(taskDir, HANDOFF_INPUT));
|
|
210
|
+
} catch (error) {
|
|
211
|
+
return [`Inherited acceptance reference cannot be read: ${error.message}`];
|
|
212
|
+
}
|
|
213
|
+
if (
|
|
214
|
+
!isRecord(reference) ||
|
|
215
|
+
reference.schemaVersion !== 1 ||
|
|
216
|
+
reference.source !== 'parent-run' ||
|
|
217
|
+
typeof reference.childRunId !== 'string' ||
|
|
218
|
+
!reference.childRunId ||
|
|
219
|
+
typeof reference.project !== 'string' ||
|
|
220
|
+
!reference.project ||
|
|
221
|
+
handoff.flow !== 'pr-complete' ||
|
|
222
|
+
reference.childRunId !== handoff.attemptId ||
|
|
223
|
+
reference.project !== handoff.project ||
|
|
224
|
+
typeof reference.parentRunId !== 'string' ||
|
|
225
|
+
!reference.parentRunId ||
|
|
226
|
+
reference.parentRunId === reference.childRunId ||
|
|
227
|
+
typeof reference.headSha !== 'string' ||
|
|
228
|
+
!/^[a-f0-9]{7,40}$/i.test(reference.headSha) ||
|
|
229
|
+
typeof reference.ledgerHash !== 'string' ||
|
|
230
|
+
!/^[a-f0-9]{64}$/i.test(reference.ledgerHash) ||
|
|
231
|
+
!acceptanceCriteriaMatch(criteria, reference.criteria)
|
|
232
|
+
)
|
|
233
|
+
return ['Inherited acceptance reference does not match this follow-up task.'];
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
201
236
|
let stored;
|
|
202
237
|
try {
|
|
203
238
|
stored = readAcceptanceLedger(taskDir);
|
|
@@ -758,6 +758,7 @@ if (
|
|
|
758
758
|
}
|
|
759
759
|
for (const issue of acceptanceContractIssues(taskDir, {
|
|
760
760
|
allowWeak: terminalContract?.acceptance?.allowWeak === true,
|
|
761
|
+
requireFresh: terminalContract?.acceptance?.requireFresh === true,
|
|
761
762
|
deferClaimVerdicts,
|
|
762
763
|
})) {
|
|
763
764
|
issues.push(issue);
|
|
@@ -33,6 +33,7 @@ const { atomicWrite } = require('./mark-io.cjs');
|
|
|
33
33
|
* @typedef {object} WorkerTerminalAcceptanceRules
|
|
34
34
|
* @property {boolean} [require]
|
|
35
35
|
* @property {boolean} [allowWeak]
|
|
36
|
+
* @property {boolean} [requireFresh]
|
|
36
37
|
*/
|
|
37
38
|
|
|
38
39
|
/**
|
|
@@ -265,6 +266,7 @@ function resolveWorkerTerminalContract(projectConfig, flowType, options = {}) {
|
|
|
265
266
|
? {
|
|
266
267
|
...(acceptanceRules.require ? { require: true } : {}),
|
|
267
268
|
...(acceptanceRules.allowWeak ? { allowWeak: true } : {}),
|
|
269
|
+
...(acceptanceRules.requireFresh ? { requireFresh: true } : {}),
|
|
268
270
|
}
|
|
269
271
|
: null;
|
|
270
272
|
|