@martinloop/mcp 0.7.1 → 0.8.1
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/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/vendor/adapters/claude-cli.d.ts +16 -1
- package/dist/vendor/adapters/claude-cli.js +286 -71
- package/dist/vendor/adapters/cli-bridge.d.ts +12 -3
- package/dist/vendor/adapters/cli-bridge.js +129 -149
- package/dist/vendor/adapters/codex-capabilities.d.ts +4 -1
- package/dist/vendor/adapters/codex-capabilities.js +36 -4
- package/dist/vendor/adapters/codex-cli.d.ts +10 -3
- package/dist/vendor/adapters/codex-cli.js +21 -24
- package/dist/vendor/adapters/codex-host.js +150 -132
- package/dist/vendor/adapters/index.d.ts +3 -2
- package/dist/vendor/adapters/index.js +3 -2
- package/dist/vendor/adapters/openai-compatible.js +88 -6
- package/dist/vendor/adapters/process-supervisor.d.ts +60 -0
- package/dist/vendor/adapters/process-supervisor.js +541 -0
- package/dist/vendor/adapters/verifier-only.d.ts +10 -1
- package/dist/vendor/adapters/verifier-only.js +43 -1
- package/dist/vendor/contracts/external-outcome.d.ts +102 -0
- package/dist/vendor/contracts/external-outcome.js +226 -0
- package/dist/vendor/contracts/index.d.ts +12 -1
- package/dist/vendor/contracts/index.js +2 -0
- package/dist/vendor/contracts/swarm-hosted.d.ts +204 -0
- package/dist/vendor/contracts/swarm-hosted.js +629 -0
- package/dist/vendor/contracts/swarm.d.ts +449 -0
- package/dist/vendor/contracts/swarm.js +550 -0
- package/dist/vendor/core/external-outcome.d.ts +34 -0
- package/dist/vendor/core/external-outcome.js +515 -0
- package/dist/vendor/core/grounding.js +1 -1
- package/dist/vendor/core/index.d.ts +52 -1
- package/dist/vendor/core/index.js +55 -3
- package/dist/vendor/core/leash.d.ts +1 -0
- package/dist/vendor/core/leash.js +13 -0
- package/dist/vendor/core/persistence/integrity.d.ts +4 -0
- package/dist/vendor/core/persistence/integrity.js +19 -6
- package/dist/vendor/core/persistence/swarm-integrity.d.ts +63 -0
- package/dist/vendor/core/persistence/swarm-integrity.js +309 -0
- package/dist/vendor/core/policy.d.ts +3 -0
- package/dist/vendor/core/policy.js +13 -0
- package/dist/vendor/core/swarm/candidates.d.ts +78 -0
- package/dist/vendor/core/swarm/candidates.js +810 -0
- package/dist/vendor/core/swarm/evidence-projection.d.ts +87 -0
- package/dist/vendor/core/swarm/evidence-projection.js +128 -0
- package/dist/vendor/core/swarm/evidence.d.ts +40 -0
- package/dist/vendor/core/swarm/evidence.js +575 -0
- package/dist/vendor/core/swarm/hosted-export.d.ts +48 -0
- package/dist/vendor/core/swarm/hosted-export.js +362 -0
- package/dist/vendor/core/swarm/hosted-projection.d.ts +5 -0
- package/dist/vendor/core/swarm/hosted-projection.js +258 -0
- package/dist/vendor/core/swarm/index.d.ts +110 -0
- package/dist/vendor/core/swarm/index.js +1060 -0
- package/dist/vendor/core/swarm/integration.d.ts +76 -0
- package/dist/vendor/core/swarm/integration.js +615 -0
- package/dist/vendor/core/swarm/lifecycle.d.ts +72 -0
- package/dist/vendor/core/swarm/lifecycle.js +252 -0
- package/dist/vendor/core/swarm/live-runtime.d.ts +78 -0
- package/dist/vendor/core/swarm/live-runtime.js +1482 -0
- package/dist/vendor/core/swarm/live-store.d.ts +99 -0
- package/dist/vendor/core/swarm/live-store.js +860 -0
- package/dist/vendor/core/swarm/operational-reader.d.ts +17 -0
- package/dist/vendor/core/swarm/operational-reader.js +96 -0
- package/dist/vendor/core/swarm/operations.d.ts +29 -0
- package/dist/vendor/core/swarm/operations.js +128 -0
- package/dist/vendor/core/swarm/parent-receipt.d.ts +13 -0
- package/dist/vendor/core/swarm/parent-receipt.js +489 -0
- package/dist/vendor/core/swarm/receipt-projection.d.ts +26 -0
- package/dist/vendor/core/swarm/receipt-projection.js +120 -0
- package/dist/vendor/core/swarm/scheduler.d.ts +92 -0
- package/dist/vendor/core/swarm/scheduler.js +555 -0
- package/dist/vendor/core/swarm/verification.d.ts +70 -0
- package/dist/vendor/core/swarm/verification.js +295 -0
- package/dist/vendor/core/swarm/workspaces.d.ts +77 -0
- package/dist/vendor/core/swarm/workspaces.js +488 -0
- package/dist/vendor/core/verified-handoff.d.ts +4 -0
- package/dist/vendor/core/verified-handoff.js +4 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { normalizeSwarmPathPattern, swarmPathPatternContains, validateSwarmDeterministicDemoReceiptEvidence, validateSwarmRunRecord } from "../../contracts/index.js";
|
|
3
|
+
import { verifyPersistedSwarmCandidateArtifact } from "./candidates.js";
|
|
4
|
+
import { integrateSwarmCandidates } from "./integration.js";
|
|
5
|
+
import { verifyIntegratedSwarmResult } from "./verification.js";
|
|
6
|
+
import { SwarmWorkspaceCreationError } from "./workspaces.js";
|
|
7
|
+
import { validateSwarmTaskGraph } from "./scheduler.js";
|
|
8
|
+
export { createParentDependencyWaiverRegistry, createSwarmBudgetLedger, extendSwarmBudgetLease, issueParentDependencyWaiver, releaseSwarmBudgetLease, reserveSwarmBudgetLease, selectNextSwarmBatch, settleSwarmBudgetLease, tasksHaveScopeCollision, validateSwarmTaskGraph } from "./scheduler.js";
|
|
9
|
+
function assessSwarmOutcomeEvidence(evidence) {
|
|
10
|
+
const invariantKeys = [
|
|
11
|
+
"record",
|
|
12
|
+
"parentState",
|
|
13
|
+
"requiredTasks",
|
|
14
|
+
"admittedScope",
|
|
15
|
+
"integration",
|
|
16
|
+
"globalVerifier",
|
|
17
|
+
"receiptBinding",
|
|
18
|
+
"budget",
|
|
19
|
+
"cleanup"
|
|
20
|
+
];
|
|
21
|
+
const blockingInvariants = invariantKeys.filter((key) => evidence[key] !== "passed");
|
|
22
|
+
if (evidence.blockingFailures !== "none") {
|
|
23
|
+
blockingInvariants.push("blockingFailures");
|
|
24
|
+
}
|
|
25
|
+
if (blockingInvariants.length === 0) {
|
|
26
|
+
return {
|
|
27
|
+
disposition: "ready",
|
|
28
|
+
eligibleForParentVerification: true,
|
|
29
|
+
blockingInvariants: []
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const hasKnownFailure = invariantKeys.some((key) => evidence[key] === "failed")
|
|
33
|
+
|| evidence.blockingFailures === "present";
|
|
34
|
+
return {
|
|
35
|
+
disposition: hasKnownFailure ? "stopped" : "needs_review",
|
|
36
|
+
eligibleForParentVerification: false,
|
|
37
|
+
blockingInvariants
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function finalizeParentSwarmOutcome(input) {
|
|
41
|
+
const assessment = assessSwarmOutcomeEvidence(input.evidence);
|
|
42
|
+
if (!assessment.eligibleForParentVerification) {
|
|
43
|
+
return {
|
|
44
|
+
outcome: {
|
|
45
|
+
state: assessment.disposition === "stopped" ? "stopped" : "needs_review",
|
|
46
|
+
reason: assessment.disposition === "stopped"
|
|
47
|
+
? "One or more parent swarm verification invariants failed."
|
|
48
|
+
: "Parent swarm verification evidence is incomplete or unknown."
|
|
49
|
+
},
|
|
50
|
+
blockingInvariants: assessment.blockingInvariants
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
outcome: {
|
|
55
|
+
state: "verified",
|
|
56
|
+
reason: "All parent swarm verification invariants passed.",
|
|
57
|
+
verifiedAt: input.evaluatedAt
|
|
58
|
+
},
|
|
59
|
+
blockingInvariants: [],
|
|
60
|
+
event: {
|
|
61
|
+
type: "SWARM_VERIFIED",
|
|
62
|
+
swarmId: input.swarmId,
|
|
63
|
+
timestamp: input.evaluatedAt,
|
|
64
|
+
parentPolicyVersion: input.parentPolicyVersion,
|
|
65
|
+
payload: {}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const authorizedParentPipelineResults = new WeakSet();
|
|
70
|
+
function freezeParentPipelineResult(value, seen = new WeakSet()) {
|
|
71
|
+
if (value === null || typeof value !== "object")
|
|
72
|
+
return value;
|
|
73
|
+
const object = value;
|
|
74
|
+
if (seen.has(object))
|
|
75
|
+
return value;
|
|
76
|
+
seen.add(object);
|
|
77
|
+
for (const key of Reflect.ownKeys(object)) {
|
|
78
|
+
const descriptor = Object.getOwnPropertyDescriptor(object, key);
|
|
79
|
+
if (descriptor && "value" in descriptor) {
|
|
80
|
+
freezeParentPipelineResult(descriptor.value, seen);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return Object.freeze(value);
|
|
84
|
+
}
|
|
85
|
+
/** Internal authority check for operational persistence; not re-exported from Core root. */
|
|
86
|
+
export function isAuthorizedParentSwarmPipelineResult(result) {
|
|
87
|
+
return authorizedParentPipelineResults.has(result);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The only public live Phase 3 completion boundary. It derives integration,
|
|
91
|
+
* verifier, receipt, budget, conflict, and cleanup truth from concrete runtime
|
|
92
|
+
* evidence; callers cannot supply invariant booleans or a desired outcome.
|
|
93
|
+
*/
|
|
94
|
+
export async function runParentSwarmPipeline(input) {
|
|
95
|
+
const result = freezeParentPipelineResult(await runParentSwarmPipelineInternal(input));
|
|
96
|
+
authorizedParentPipelineResults.add(result);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
async function runParentSwarmPipelineInternal(input) {
|
|
100
|
+
const now = input.now ?? (() => new Date().toISOString());
|
|
101
|
+
const createId = input.createId ?? ((prefix) => `${prefix}-${Math.random().toString(36).slice(2, 10)}`);
|
|
102
|
+
const record = cloneSwarmRunRecord(input.record);
|
|
103
|
+
if (!validateSwarmRunRecord(record).ok || !validateSwarmTaskGraph(record.tasks).ok || record.outcome.state !== "running") {
|
|
104
|
+
return failedPipelineResult(record, "record", now());
|
|
105
|
+
}
|
|
106
|
+
if (record.events.some((event) => event.type === "SWARM_VERIFIED")) {
|
|
107
|
+
return failedPipelineResult(record, "parentState", now());
|
|
108
|
+
}
|
|
109
|
+
if (input.signal.aborted)
|
|
110
|
+
return failedPipelineResult(record, "parentState", now());
|
|
111
|
+
let integration;
|
|
112
|
+
let activeIntegrationWorkspace;
|
|
113
|
+
try {
|
|
114
|
+
integration = await integrateSwarmCandidates({
|
|
115
|
+
swarmRecord: record,
|
|
116
|
+
workspaceManager: input.workspaceManager,
|
|
117
|
+
integrationWorkspaceId: input.integrationWorkspaceId,
|
|
118
|
+
candidates: input.candidateIds.map((candidateId) => ({ candidateId })),
|
|
119
|
+
evidenceStore: input.evidenceStore,
|
|
120
|
+
conflictPolicy: "stop",
|
|
121
|
+
now,
|
|
122
|
+
createId,
|
|
123
|
+
onWorkspaceCreated: (workspace) => { activeIntegrationWorkspace = workspace; }
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
const cleanup = await retainOrCleanupExceptionalWorkspace(input, activeIntegrationWorkspace, error, "integration", now, createId, true);
|
|
128
|
+
return failedPipelineResult(record, "integration", now(), cleanup ? [cleanup] : []);
|
|
129
|
+
}
|
|
130
|
+
const recordWithIntegration = {
|
|
131
|
+
...record,
|
|
132
|
+
events: [...record.events, ...integration.events.map(cloneEvent)],
|
|
133
|
+
conflicts: [...record.conflicts, ...integration.conflicts.map((conflict) => ({ ...conflict, taskIds: [...conflict.taskIds], paths: [...conflict.paths] }))],
|
|
134
|
+
updatedAt: now()
|
|
135
|
+
};
|
|
136
|
+
let verificationResult;
|
|
137
|
+
const cleanup = [];
|
|
138
|
+
let cleanupPersisted = true;
|
|
139
|
+
if (integration.completed && integration.cleanupAuthorized && !input.signal.aborted) {
|
|
140
|
+
try {
|
|
141
|
+
verificationResult = await verifyIntegratedSwarmResult({
|
|
142
|
+
swarmRecord: recordWithIntegration,
|
|
143
|
+
workspaceManager: input.workspaceManager,
|
|
144
|
+
verifierWorkspaceId: input.verifierWorkspaceId,
|
|
145
|
+
admittedCandidateIds: integration.admittedCandidateIds,
|
|
146
|
+
integratedTreeHash: integration.finalTreeHash,
|
|
147
|
+
evidenceStore: input.evidenceStore,
|
|
148
|
+
executor: input.verifierExecutor,
|
|
149
|
+
signal: input.signal,
|
|
150
|
+
now,
|
|
151
|
+
createVerificationId: () => createId("global-verification")
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error instanceof SwarmWorkspaceCreationError) {
|
|
156
|
+
cleanup.push(error.cleanup);
|
|
157
|
+
try {
|
|
158
|
+
await input.evidenceStore.persistCleanupEvidence(error.cleanup);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
cleanupPersisted = false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (verificationResult?.cleanupAuthorized) {
|
|
167
|
+
const result = await removePipelineWorkspace(input, verificationResult.workspace, now, createId, verificationResult.processCloseState === "closed");
|
|
168
|
+
cleanup.push(result.cleanup);
|
|
169
|
+
cleanupPersisted &&= result.persisted;
|
|
170
|
+
}
|
|
171
|
+
if (integration.cleanupAuthorized) {
|
|
172
|
+
const result = await removePipelineWorkspace(input, integration.workspace, now, createId, true);
|
|
173
|
+
cleanup.push(result.cleanup);
|
|
174
|
+
cleanupPersisted &&= result.persisted;
|
|
175
|
+
}
|
|
176
|
+
const artifacts = [];
|
|
177
|
+
for (const candidateId of integration.admittedCandidateIds) {
|
|
178
|
+
const artifact = await input.evidenceStore.loadPersistedCandidate(candidateId);
|
|
179
|
+
if (artifact)
|
|
180
|
+
artifacts.push(artifact);
|
|
181
|
+
}
|
|
182
|
+
const receiptPassed = artifacts.length === integration.admittedCandidateIds.length
|
|
183
|
+
&& artifacts.every((artifact) => verifyPersistedSwarmCandidateArtifact(artifact) && artifact.receiptIntegrity.state === "verified");
|
|
184
|
+
const childCompletionPassed = await persistedChildCompletionPassed(record, artifacts, input.evidenceStore);
|
|
185
|
+
const candidateCoveragePassed = hasExactRequiredWriteTaskCoverage(record, artifacts);
|
|
186
|
+
const integrationPassed = integration.completed
|
|
187
|
+
&& integration.cleanupAuthorized
|
|
188
|
+
&& integration.conflicts.length === 0
|
|
189
|
+
&& integration.admittedCandidateIds.length === input.candidateIds.length
|
|
190
|
+
&& candidateCoveragePassed
|
|
191
|
+
&& integration.decisions.every((decision) => decision.state === "admitted");
|
|
192
|
+
const verifierPassed = verificationResult?.passed === true
|
|
193
|
+
&& verificationResult.evidence.commandState === "passed"
|
|
194
|
+
&& verificationResult.evidence.mutationState === "clean"
|
|
195
|
+
&& verificationResult.reconstructedTreeHash === integration.finalTreeHash;
|
|
196
|
+
const cleanupPassed = childCompletionPassed
|
|
197
|
+
&& cleanupPersisted
|
|
198
|
+
&& cleanup.length === (verificationResult?.cleanupAuthorized ? 2 : 1)
|
|
199
|
+
&& cleanup.every((entry) => entry.state === "completed");
|
|
200
|
+
const hasPipelineBlocker = recordWithIntegration.conflicts.some((conflict) => conflict.state === "blocking")
|
|
201
|
+
|| recordWithIntegration.events.some((event) => (event.type === "SWARM_STOPPED"
|
|
202
|
+
|| event.type === "SWARM_NEEDS_REVIEW"
|
|
203
|
+
|| event.type === "CHILD_NEEDS_REVIEW"))
|
|
204
|
+
|| recordWithIntegration.agents.some((agent) => agent.status === "needs_review")
|
|
205
|
+
|| recordWithIntegration.tasks.some((task) => task.status === "needs_review")
|
|
206
|
+
|| integration.conflicts.length > 0;
|
|
207
|
+
const evidence = {
|
|
208
|
+
record: "passed",
|
|
209
|
+
parentState: input.signal.aborted ? "failed" : "passed",
|
|
210
|
+
requiredTasks: record.tasks.filter((task) => task.required).every((task) => task.status === "accepted") ? "passed" : "failed",
|
|
211
|
+
admittedScope: integrationPassed ? "passed" : "failed",
|
|
212
|
+
integration: integrationPassed ? "passed" : "failed",
|
|
213
|
+
globalVerifier: verifierPassed ? "passed" : verificationResult ? "failed" : "unknown",
|
|
214
|
+
receiptBinding: receiptPassed ? "passed" : "failed",
|
|
215
|
+
budget: evaluateBudget(record),
|
|
216
|
+
cleanup: cleanupPassed && !input.signal.aborted ? "passed" : "failed",
|
|
217
|
+
blockingFailures: hasPipelineBlocker ? "present" : "none"
|
|
218
|
+
};
|
|
219
|
+
const evaluatedAt = now();
|
|
220
|
+
if (input.signal.aborted)
|
|
221
|
+
evidence.parentState = "failed";
|
|
222
|
+
const decision = finalizeParentSwarmOutcome({
|
|
223
|
+
swarmId: record.swarmId,
|
|
224
|
+
parentPolicyVersion: record.parentContract.policyVersion,
|
|
225
|
+
evaluatedAt,
|
|
226
|
+
evidence
|
|
227
|
+
});
|
|
228
|
+
const canonicalOutcome = verificationResult && !verifierPassed
|
|
229
|
+
? { state: "needs_review", reason: decision.outcome.reason }
|
|
230
|
+
: decision.outcome;
|
|
231
|
+
const canonicalDecisionEvent = verificationResult && !verifierPassed
|
|
232
|
+
? {
|
|
233
|
+
type: "SWARM_NEEDS_REVIEW",
|
|
234
|
+
swarmId: record.swarmId,
|
|
235
|
+
timestamp: evaluatedAt,
|
|
236
|
+
parentPolicyVersion: record.parentContract.policyVersion,
|
|
237
|
+
payload: { reason: canonicalOutcome.reason }
|
|
238
|
+
}
|
|
239
|
+
: decision.event;
|
|
240
|
+
const verifierEvent = verificationResult
|
|
241
|
+
? {
|
|
242
|
+
type: verifierPassed ? "GLOBAL_VERIFIER_PASSED" : "GLOBAL_VERIFIER_FAILED",
|
|
243
|
+
swarmId: record.swarmId,
|
|
244
|
+
timestamp: verificationResult.evidence.completedAt ?? evaluatedAt,
|
|
245
|
+
parentPolicyVersion: record.parentContract.policyVersion,
|
|
246
|
+
payload: {
|
|
247
|
+
verificationId: verificationResult.evidence.verificationId,
|
|
248
|
+
integratedTreeHash: integration.finalTreeHash
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
: undefined;
|
|
252
|
+
const finalRecord = cloneSwarmRunRecord({
|
|
253
|
+
...recordWithIntegration,
|
|
254
|
+
verification: verificationResult ? [...record.verification, {
|
|
255
|
+
verifierId: verificationResult.evidence.verificationId,
|
|
256
|
+
scope: "parent_global",
|
|
257
|
+
state: verifierPassed ? "passed" : "failed",
|
|
258
|
+
steps: record.parentContract.globalVerifierStack.map((step) => ({ ...step })),
|
|
259
|
+
boundAt: verificationResult.evidence.completedAt
|
|
260
|
+
}] : record.verification,
|
|
261
|
+
outcome: { ...canonicalOutcome },
|
|
262
|
+
events: [
|
|
263
|
+
...recordWithIntegration.events,
|
|
264
|
+
...(verifierEvent ? [verifierEvent] : []),
|
|
265
|
+
...(canonicalDecisionEvent ? [canonicalDecisionEvent] : [])
|
|
266
|
+
],
|
|
267
|
+
updatedAt: evaluatedAt
|
|
268
|
+
});
|
|
269
|
+
const assessment = assessSwarmOutcomeEvidence(evidence);
|
|
270
|
+
return Object.freeze({
|
|
271
|
+
record: finalRecord,
|
|
272
|
+
outcome: { ...canonicalOutcome },
|
|
273
|
+
disposition: verificationResult && !verifierPassed ? "needs_review" : assessment.disposition,
|
|
274
|
+
blockingInvariants: Object.freeze([...decision.blockingInvariants]),
|
|
275
|
+
integration: Object.freeze({
|
|
276
|
+
completed: integration.completed,
|
|
277
|
+
finalTreeHash: integration.finalTreeHash,
|
|
278
|
+
admittedCandidateIds: Object.freeze([...integration.admittedCandidateIds])
|
|
279
|
+
}),
|
|
280
|
+
...(verificationResult ? { verification: verificationResult.evidence } : {}),
|
|
281
|
+
cleanup: Object.freeze(cleanup)
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
function hasExactRequiredWriteTaskCoverage(record, artifacts) {
|
|
285
|
+
const requiredWriteTaskIds = record.tasks
|
|
286
|
+
.filter((task) => task.required && task.mutationMode === "write" && task.status === "accepted")
|
|
287
|
+
.map((task) => task.taskId);
|
|
288
|
+
const counts = new Map();
|
|
289
|
+
for (const artifact of artifacts) {
|
|
290
|
+
if (artifact.candidate.taskIds.length !== 1)
|
|
291
|
+
return false;
|
|
292
|
+
const taskId = artifact.candidate.taskIds[0];
|
|
293
|
+
const task = record.tasks.find((candidate) => candidate.taskId === taskId);
|
|
294
|
+
const agent = record.agents.find((candidate) => candidate.agentId === artifact.candidate.agentId);
|
|
295
|
+
if (!task
|
|
296
|
+
|| !agent
|
|
297
|
+
|| task.mutationMode !== "write"
|
|
298
|
+
|| task.status !== "accepted"
|
|
299
|
+
|| task.assignedAgentId !== artifact.candidate.agentId
|
|
300
|
+
|| agent.childRunId !== artifact.candidate.childRunId
|
|
301
|
+
|| !agent.contract.taskIds.includes(taskId))
|
|
302
|
+
return false;
|
|
303
|
+
counts.set(taskId, (counts.get(taskId) ?? 0) + 1);
|
|
304
|
+
}
|
|
305
|
+
return requiredWriteTaskIds.every((taskId) => counts.get(taskId) === 1)
|
|
306
|
+
&& [...counts.values()].every((count) => count === 1);
|
|
307
|
+
}
|
|
308
|
+
async function persistedChildCompletionPassed(record, artifacts, store) {
|
|
309
|
+
const artifactByTaskId = new Map();
|
|
310
|
+
for (const artifact of artifacts) {
|
|
311
|
+
if (artifact.candidate.taskIds.length !== 1)
|
|
312
|
+
return false;
|
|
313
|
+
const taskId = artifact.candidate.taskIds[0];
|
|
314
|
+
if (artifactByTaskId.has(taskId))
|
|
315
|
+
return false;
|
|
316
|
+
artifactByTaskId.set(taskId, artifact);
|
|
317
|
+
}
|
|
318
|
+
const taskIds = new Set(record.tasks.filter((task) => task.required).map((task) => task.taskId));
|
|
319
|
+
for (const taskId of artifactByTaskId.keys())
|
|
320
|
+
taskIds.add(taskId);
|
|
321
|
+
for (const taskId of taskIds) {
|
|
322
|
+
const task = record.tasks.find((candidate) => candidate.taskId === taskId);
|
|
323
|
+
const agent = task ? record.agents.find((candidate) => candidate.agentId === task.assignedAgentId) : undefined;
|
|
324
|
+
if (!task || !agent?.childRunId)
|
|
325
|
+
return false;
|
|
326
|
+
const completion = await store.loadPersistedChildCompletion(agent.childRunId);
|
|
327
|
+
if (!completion
|
|
328
|
+
|| completion.swarmId !== record.swarmId
|
|
329
|
+
|| completion.childRunId !== agent.childRunId
|
|
330
|
+
|| completion.agentId !== agent.agentId
|
|
331
|
+
|| !completion.taskIds.includes(taskId)
|
|
332
|
+
|| !sameStringSet(completion.taskIds, agent.contract.taskIds)
|
|
333
|
+
|| completion.evidencePersisted !== true
|
|
334
|
+
|| completion.processCloseState !== "closed"
|
|
335
|
+
|| (completion.leaseState !== "settled" && completion.leaseState !== "released")
|
|
336
|
+
|| !validChildReceiptBinding(completion))
|
|
337
|
+
return false;
|
|
338
|
+
const artifact = artifactByTaskId.get(taskId);
|
|
339
|
+
if (task.mutationMode === "write") {
|
|
340
|
+
if (!artifact
|
|
341
|
+
|| completion.workspaceCleanupState !== "completed"
|
|
342
|
+
|| completion.workspaceId !== artifact.candidate.workspaceId
|
|
343
|
+
|| !completion.cleanup
|
|
344
|
+
|| completion.cleanup.swarmId !== record.swarmId
|
|
345
|
+
|| completion.cleanup.workspaceId !== artifact.candidate.workspaceId
|
|
346
|
+
|| completion.cleanup.workspaceKind !== "child"
|
|
347
|
+
|| completion.cleanup.evidencePersisted !== true
|
|
348
|
+
|| completion.cleanup.state !== "completed"
|
|
349
|
+
|| completion.cleanup.removalState !== "removed")
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
else if (completion.workspaceCleanupState === "completed") {
|
|
353
|
+
if (!completion.cleanup
|
|
354
|
+
|| !completion.workspaceId
|
|
355
|
+
|| completion.cleanup.swarmId !== record.swarmId
|
|
356
|
+
|| completion.cleanup.workspaceId !== completion.workspaceId
|
|
357
|
+
|| completion.cleanup.workspaceKind !== "child"
|
|
358
|
+
|| completion.cleanup.evidencePersisted !== true
|
|
359
|
+
|| completion.cleanup.state !== "completed"
|
|
360
|
+
|| completion.cleanup.removalState !== "removed")
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
else if (completion.workspaceId !== undefined || completion.cleanup !== undefined)
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
function validChildReceiptBinding(completion) {
|
|
369
|
+
const receipt = completion.receipt;
|
|
370
|
+
if (receipt.receiptId.trim().length === 0
|
|
371
|
+
|| receipt.swarmId !== completion.swarmId
|
|
372
|
+
|| receipt.childRunId !== completion.childRunId
|
|
373
|
+
|| receipt.agentId !== completion.agentId
|
|
374
|
+
|| receipt.attemptId.trim().length === 0
|
|
375
|
+
|| receipt.attemptId !== completion.attemptId
|
|
376
|
+
|| !sameStringSet(receipt.taskIds, completion.taskIds)
|
|
377
|
+
|| receipt.integrity.state !== "verified"
|
|
378
|
+
|| !receipt.integrity.keyId
|
|
379
|
+
|| !isSha256(receipt.integrity.loopRecordSha256)
|
|
380
|
+
|| !isSha256(receipt.integrity.ledgerSha256)
|
|
381
|
+
|| !isSha256(receipt.integrity.ledgerHeadHash))
|
|
382
|
+
return false;
|
|
383
|
+
const canonical = JSON.stringify({
|
|
384
|
+
receiptId: receipt.receiptId,
|
|
385
|
+
swarmId: receipt.swarmId,
|
|
386
|
+
childRunId: receipt.childRunId,
|
|
387
|
+
agentId: receipt.agentId,
|
|
388
|
+
attemptId: receipt.attemptId,
|
|
389
|
+
taskIds: [...receipt.taskIds].sort(),
|
|
390
|
+
integrity: {
|
|
391
|
+
state: receipt.integrity.state,
|
|
392
|
+
keyId: receipt.integrity.keyId,
|
|
393
|
+
loopRecordSha256: receipt.integrity.loopRecordSha256,
|
|
394
|
+
ledgerSha256: receipt.integrity.ledgerSha256,
|
|
395
|
+
ledgerHeadHash: receipt.integrity.ledgerHeadHash
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
return createHash("sha256").update(canonical, "utf8").digest("hex") === receipt.bindingSha256;
|
|
399
|
+
}
|
|
400
|
+
function isSha256(value) {
|
|
401
|
+
return typeof value === "string" && /^[0-9a-f]{64}$/u.test(value);
|
|
402
|
+
}
|
|
403
|
+
async function retainOrCleanupExceptionalWorkspace(input, workspace, error, phase, now, createId, processTreeClosed) {
|
|
404
|
+
if (!workspace) {
|
|
405
|
+
if (error instanceof SwarmWorkspaceCreationError) {
|
|
406
|
+
await input.evidenceStore.persistCleanupEvidence(error.cleanup).catch(() => undefined);
|
|
407
|
+
return error.cleanup;
|
|
408
|
+
}
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
const errorCode = safePipelineErrorCode(error);
|
|
412
|
+
try {
|
|
413
|
+
await input.evidenceStore.persistWorkspaceFailureEvidence({
|
|
414
|
+
failureId: createId("workspace-failure"),
|
|
415
|
+
swarmId: input.record.swarmId,
|
|
416
|
+
workspaceId: workspace.record.workspaceId,
|
|
417
|
+
workspaceKind: workspace.record.kind === "verifier" ? "verifier" : "integration",
|
|
418
|
+
phase,
|
|
419
|
+
errorCode,
|
|
420
|
+
recordedAt: now()
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
catch {
|
|
424
|
+
return {
|
|
425
|
+
schemaVersion: "martin.swarm.v1",
|
|
426
|
+
cleanupId: createId("pipeline-cleanup-pending"),
|
|
427
|
+
swarmId: input.record.swarmId,
|
|
428
|
+
workspaceId: workspace.record.workspaceId,
|
|
429
|
+
workspaceKind: workspace.record.kind,
|
|
430
|
+
evidencePersisted: false,
|
|
431
|
+
processCloseState: processTreeClosed ? "closed" : "failed",
|
|
432
|
+
removalState: "failed",
|
|
433
|
+
state: "cleanup_pending",
|
|
434
|
+
attemptedAt: now(),
|
|
435
|
+
errorCode: "WORKSPACE_FAILURE_EVIDENCE_NOT_PERSISTED"
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
const result = await removePipelineWorkspace(input, workspace, now, createId, processTreeClosed);
|
|
439
|
+
return result.cleanup;
|
|
440
|
+
}
|
|
441
|
+
function safePipelineErrorCode(error) {
|
|
442
|
+
if (error instanceof Error && "code" in error) {
|
|
443
|
+
const code = String(error.code ?? "PIPELINE_WORKSPACE_FAILURE");
|
|
444
|
+
return code.slice(0, 96);
|
|
445
|
+
}
|
|
446
|
+
return "PIPELINE_WORKSPACE_FAILURE";
|
|
447
|
+
}
|
|
448
|
+
async function removePipelineWorkspace(input, workspace, now, createId, processTreeClosed) {
|
|
449
|
+
let cleanup;
|
|
450
|
+
try {
|
|
451
|
+
cleanup = await input.workspaceManager.removeWorkspace(workspace, {
|
|
452
|
+
evidencePersisted: true,
|
|
453
|
+
processTreeClosed,
|
|
454
|
+
force: true
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
const code = typeof error === "object" && error !== null && "code" in error
|
|
459
|
+
? String(error.code ?? "WORKSPACE_REMOVE_FAILED")
|
|
460
|
+
: "WORKSPACE_REMOVE_FAILED";
|
|
461
|
+
cleanup = {
|
|
462
|
+
schemaVersion: "martin.swarm.v1",
|
|
463
|
+
cleanupId: createId("pipeline-cleanup"),
|
|
464
|
+
swarmId: input.record.swarmId,
|
|
465
|
+
workspaceId: workspace.record.workspaceId,
|
|
466
|
+
workspaceKind: workspace.record.kind,
|
|
467
|
+
evidencePersisted: true,
|
|
468
|
+
processCloseState: processTreeClosed ? "closed" : "failed",
|
|
469
|
+
removalState: "failed",
|
|
470
|
+
state: code === "EPERM" || code === "EBUSY" ? "cleanup_pending" : "failed",
|
|
471
|
+
attemptedAt: now(),
|
|
472
|
+
errorCode: code
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
await input.evidenceStore.persistCleanupEvidence(cleanup);
|
|
477
|
+
return { cleanup, persisted: true };
|
|
478
|
+
}
|
|
479
|
+
catch {
|
|
480
|
+
return { cleanup, persisted: false };
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
function failedPipelineResult(record, invariant, evaluatedAt, cleanup = []) {
|
|
484
|
+
const evidence = failedEvidence(invariant);
|
|
485
|
+
const decision = finalizeParentSwarmOutcome({
|
|
486
|
+
swarmId: record.swarmId,
|
|
487
|
+
parentPolicyVersion: record.parentContract.policyVersion,
|
|
488
|
+
evaluatedAt,
|
|
489
|
+
evidence
|
|
490
|
+
});
|
|
491
|
+
const assessment = assessSwarmOutcomeEvidence(evidence);
|
|
492
|
+
return Object.freeze({
|
|
493
|
+
record: cloneSwarmRunRecord({ ...record, outcome: { ...decision.outcome }, updatedAt: evaluatedAt }),
|
|
494
|
+
outcome: { ...decision.outcome },
|
|
495
|
+
disposition: assessment.disposition,
|
|
496
|
+
blockingInvariants: Object.freeze([...decision.blockingInvariants]),
|
|
497
|
+
integration: Object.freeze({ completed: false, finalTreeHash: "", admittedCandidateIds: Object.freeze([]) }),
|
|
498
|
+
cleanup: Object.freeze([...cleanup])
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
export function completeDeterministicDemoSwarmRun(input) {
|
|
502
|
+
const recordSnapshot = cloneSwarmRunRecord(input.record);
|
|
503
|
+
const verifierSnapshot = {
|
|
504
|
+
...input.verifier,
|
|
505
|
+
commands: [...input.verifier.commands]
|
|
506
|
+
};
|
|
507
|
+
const receiptEvidence = input.receiptEvidence.map((evidence) => ({
|
|
508
|
+
...evidence,
|
|
509
|
+
taskIds: [...evidence.taskIds]
|
|
510
|
+
}));
|
|
511
|
+
const snapshot = {
|
|
512
|
+
record: recordSnapshot,
|
|
513
|
+
verifier: verifierSnapshot,
|
|
514
|
+
receiptEvidence
|
|
515
|
+
};
|
|
516
|
+
const evidence = deriveParentOutcomeEvidence(snapshot, receiptEvidence);
|
|
517
|
+
const decision = finalizeParentSwarmOutcome({
|
|
518
|
+
swarmId: recordSnapshot.swarmId,
|
|
519
|
+
parentPolicyVersion: recordSnapshot.parentContract.policyVersion,
|
|
520
|
+
evaluatedAt: verifierSnapshot.evaluatedAt,
|
|
521
|
+
evidence
|
|
522
|
+
});
|
|
523
|
+
const record = {
|
|
524
|
+
...recordSnapshot,
|
|
525
|
+
outcome: { ...decision.outcome },
|
|
526
|
+
events: decision.event
|
|
527
|
+
? [...recordSnapshot.events.map(cloneEvent), cloneEvent(decision.event)]
|
|
528
|
+
: recordSnapshot.events.map(cloneEvent),
|
|
529
|
+
updatedAt: verifierSnapshot.evaluatedAt
|
|
530
|
+
};
|
|
531
|
+
return {
|
|
532
|
+
...decision,
|
|
533
|
+
record,
|
|
534
|
+
receiptEvidence
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
function deriveParentOutcomeEvidence(input, receiptEvidence) {
|
|
538
|
+
const record = input.record;
|
|
539
|
+
const recordValid = validateSwarmRunRecord(record).ok
|
|
540
|
+
&& validateSwarmTaskGraph(record.tasks).ok
|
|
541
|
+
&& hasConsistentRecordBindings(record)
|
|
542
|
+
&& hasCanonicalDemoRoster(record);
|
|
543
|
+
if (!recordValid) {
|
|
544
|
+
return failedEvidence("record");
|
|
545
|
+
}
|
|
546
|
+
if (record.outcome.state !== "running") {
|
|
547
|
+
return failedEvidence("parentState");
|
|
548
|
+
}
|
|
549
|
+
return {
|
|
550
|
+
record: "passed",
|
|
551
|
+
parentState: "passed",
|
|
552
|
+
requiredTasks: record.tasks.filter((task) => task.required).every((task) => task.status === "accepted")
|
|
553
|
+
? "passed"
|
|
554
|
+
: "failed",
|
|
555
|
+
admittedScope: evaluateAdmittedScope(record),
|
|
556
|
+
integration: hasBoundEvent(record, "INTEGRATION_COMPLETED") ? "passed" : "unknown",
|
|
557
|
+
globalVerifier: evaluateGlobalVerifier(record, input.verifier),
|
|
558
|
+
receiptBinding: evaluateReceiptBinding(record, receiptEvidence),
|
|
559
|
+
budget: evaluateBudget(record),
|
|
560
|
+
cleanup: "passed",
|
|
561
|
+
blockingFailures: hasBlockingFailure(record) ? "present" : "none"
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
function failedEvidence(key) {
|
|
565
|
+
const evidence = {
|
|
566
|
+
record: "passed",
|
|
567
|
+
parentState: "passed",
|
|
568
|
+
requiredTasks: "passed",
|
|
569
|
+
admittedScope: "passed",
|
|
570
|
+
integration: "passed",
|
|
571
|
+
globalVerifier: "passed",
|
|
572
|
+
receiptBinding: "passed",
|
|
573
|
+
budget: "passed",
|
|
574
|
+
cleanup: "passed",
|
|
575
|
+
blockingFailures: "none"
|
|
576
|
+
};
|
|
577
|
+
evidence[key] = "failed";
|
|
578
|
+
return evidence;
|
|
579
|
+
}
|
|
580
|
+
function hasConsistentRecordBindings(record) {
|
|
581
|
+
if (record.budgetLedger.capUsd !== record.parentContract.budget.maxUsd)
|
|
582
|
+
return false;
|
|
583
|
+
if (record.budgetLedger.capTokens !== record.parentContract.budget.maxTokens)
|
|
584
|
+
return false;
|
|
585
|
+
if (record.events.some((event) => (event.swarmId !== record.swarmId
|
|
586
|
+
|| event.parentPolicyVersion !== record.parentContract.policyVersion)))
|
|
587
|
+
return false;
|
|
588
|
+
const tasks = new Map(record.tasks.map((task) => [task.taskId, task]));
|
|
589
|
+
const agents = new Map(record.agents.map((agent) => [agent.agentId, agent]));
|
|
590
|
+
for (const agent of record.agents) {
|
|
591
|
+
if (agent.contract.agentId !== agent.agentId)
|
|
592
|
+
return false;
|
|
593
|
+
if (agent.contract.taskIds.some((taskId) => !tasks.has(taskId)))
|
|
594
|
+
return false;
|
|
595
|
+
}
|
|
596
|
+
return record.tasks.every((task) => {
|
|
597
|
+
if (!task.assignedAgentId)
|
|
598
|
+
return task.status !== "accepted";
|
|
599
|
+
const agent = agents.get(task.assignedAgentId);
|
|
600
|
+
return agent !== undefined && agent.contract.taskIds.includes(task.taskId);
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
function evaluateAdmittedScope(record) {
|
|
604
|
+
const counts = new Map();
|
|
605
|
+
for (const admitted of record.events.filter((event) => event.type === "CHILD_PATCH_ADMITTED")) {
|
|
606
|
+
const task = admitted.taskId
|
|
607
|
+
? record.tasks.find((candidate) => candidate.taskId === admitted.taskId)
|
|
608
|
+
: undefined;
|
|
609
|
+
if (!task || task.status !== "accepted" || task.mutationMode !== "write" || !task.assignedAgentId) {
|
|
610
|
+
return "failed";
|
|
611
|
+
}
|
|
612
|
+
const agent = record.agents.find((candidate) => candidate.agentId === task.assignedAgentId);
|
|
613
|
+
if (!agent
|
|
614
|
+
|| admitted.agentId !== task.assignedAgentId
|
|
615
|
+
|| admitted.childRunId !== agent.childRunId
|
|
616
|
+
|| !hasBoundEventIdentity(record, admitted)
|
|
617
|
+
|| !isAuthorizedTaskScope(record, agent.agentId, task.writeScope))
|
|
618
|
+
return "failed";
|
|
619
|
+
const paths = admitted.payload.paths;
|
|
620
|
+
if (!Array.isArray(paths)
|
|
621
|
+
|| paths.length === 0
|
|
622
|
+
|| paths.some((path) => !isContainedAdmittedPath(record, agent.agentId, path, task.writeScope))) {
|
|
623
|
+
return "failed";
|
|
624
|
+
}
|
|
625
|
+
counts.set(task.taskId, (counts.get(task.taskId) ?? 0) + 1);
|
|
626
|
+
}
|
|
627
|
+
for (const task of record.tasks.filter((candidate) => candidate.status === "accepted" && candidate.mutationMode === "write")) {
|
|
628
|
+
const count = counts.get(task.taskId) ?? 0;
|
|
629
|
+
if (count === 0)
|
|
630
|
+
return "unknown";
|
|
631
|
+
if (count !== 1)
|
|
632
|
+
return "failed";
|
|
633
|
+
}
|
|
634
|
+
return "passed";
|
|
635
|
+
}
|
|
636
|
+
function evaluateGlobalVerifier(record, verifier) {
|
|
637
|
+
if (!hasText(record.workspaceId)
|
|
638
|
+
|| !hasText(record.projectId)
|
|
639
|
+
|| !hasText(verifier.verifierId)
|
|
640
|
+
|| !hasText(verifier.swarmId)
|
|
641
|
+
|| !hasText(verifier.workspaceId)
|
|
642
|
+
|| !hasText(verifier.parentPolicyVersion)
|
|
643
|
+
|| !isCanonicalIsoDate(verifier.evaluatedAt))
|
|
644
|
+
return "failed";
|
|
645
|
+
const expectedCommands = record.parentContract.globalVerifierStack.map((step) => step.command);
|
|
646
|
+
const parentVerifierRecords = record.verification.filter((candidate) => candidate.scope === "parent_global");
|
|
647
|
+
const boundRecord = parentVerifierRecords.length === 1
|
|
648
|
+
&& parentVerifierRecords[0]?.verifierId === verifier.verifierId
|
|
649
|
+
? parentVerifierRecords[0]
|
|
650
|
+
: undefined;
|
|
651
|
+
const passedEvent = record.events.find((event) => (event.type === "GLOBAL_VERIFIER_PASSED"
|
|
652
|
+
&& event.payload.verifierId === verifier.verifierId
|
|
653
|
+
&& event.timestamp === verifier.evaluatedAt
|
|
654
|
+
&& hasBoundEventIdentity(record, event)));
|
|
655
|
+
const identityMatches = verifier.swarmId === record.swarmId
|
|
656
|
+
&& verifier.workspaceId === record.workspaceId
|
|
657
|
+
&& verifier.parentPolicyVersion === record.parentContract.policyVersion
|
|
658
|
+
&& sameStrings(verifier.commands, expectedCommands)
|
|
659
|
+
&& boundRecord !== undefined
|
|
660
|
+
&& sameStrings(boundRecord.steps.map((step) => step.command), expectedCommands)
|
|
661
|
+
&& boundRecord.boundAt === verifier.evaluatedAt
|
|
662
|
+
&& passedEvent !== undefined;
|
|
663
|
+
if (!identityMatches || boundRecord?.state === "failed")
|
|
664
|
+
return "failed";
|
|
665
|
+
if (verifier.crashed || verifier.timedOut || (verifier.completed && verifier.exitCode !== 0))
|
|
666
|
+
return "failed";
|
|
667
|
+
const executionPassed = verifier.launched
|
|
668
|
+
&& verifier.completed
|
|
669
|
+
&& !verifier.crashed
|
|
670
|
+
&& !verifier.timedOut
|
|
671
|
+
&& verifier.exitCode === 0;
|
|
672
|
+
return executionPassed && boundRecord.state === "passed" ? "passed" : "unknown";
|
|
673
|
+
}
|
|
674
|
+
function evaluateReceiptBinding(record, receiptEvidence) {
|
|
675
|
+
if (record.agents.length !== 15 || receiptEvidence.length !== 15)
|
|
676
|
+
return "failed";
|
|
677
|
+
const expected = record.agents.map((agent) => ({
|
|
678
|
+
swarmId: record.swarmId,
|
|
679
|
+
agentId: agent.agentId,
|
|
680
|
+
taskIds: [...agent.contract.taskIds],
|
|
681
|
+
childRunId: agent.childRunId
|
|
682
|
+
}));
|
|
683
|
+
const seen = new Set();
|
|
684
|
+
let unknown = false;
|
|
685
|
+
for (const evidence of receiptEvidence) {
|
|
686
|
+
if (!validateSwarmDeterministicDemoReceiptEvidence(evidence).ok)
|
|
687
|
+
return "failed";
|
|
688
|
+
const key = `${evidence.swarmId}\u0000${evidence.agentId}\u0000${evidence.childRunId}`;
|
|
689
|
+
if (seen.has(key))
|
|
690
|
+
return "failed";
|
|
691
|
+
seen.add(key);
|
|
692
|
+
const binding = expected.find((candidate) => (candidate.swarmId === evidence.swarmId
|
|
693
|
+
&& candidate.agentId === evidence.agentId
|
|
694
|
+
&& candidate.childRunId === evidence.childRunId
|
|
695
|
+
&& sameStringSet(candidate.taskIds, evidence.taskIds)));
|
|
696
|
+
if (!binding || evidence.referentialBinding === "failed")
|
|
697
|
+
return "failed";
|
|
698
|
+
if (evidence.referentialBinding === "unknown")
|
|
699
|
+
unknown = true;
|
|
700
|
+
}
|
|
701
|
+
return unknown ? "unknown" : "passed";
|
|
702
|
+
}
|
|
703
|
+
function evaluateBudget(record) {
|
|
704
|
+
const ledger = record.budgetLedger;
|
|
705
|
+
if (!isValidTerminalBudgetLedger(record))
|
|
706
|
+
return "failed";
|
|
707
|
+
if (ledger.leases.some((lease) => lease.status === "overspent")
|
|
708
|
+
|| ledger.settledUsd > ledger.capUsd
|
|
709
|
+
|| (ledger.capTokens !== undefined && ledger.settledTokens > ledger.capTokens))
|
|
710
|
+
return "failed";
|
|
711
|
+
if (ledger.leases.some((lease) => lease.status === "reserved"))
|
|
712
|
+
return "unknown";
|
|
713
|
+
return "passed";
|
|
714
|
+
}
|
|
715
|
+
function hasBlockingFailure(record) {
|
|
716
|
+
return record.conflicts.some((conflict) => conflict.state === "blocking")
|
|
717
|
+
|| record.agents.some((agent) => (agent.agentId === "agent-06"
|
|
718
|
+
? agent.status !== "stopped" || !hasCanonicalDemoRecovery(record)
|
|
719
|
+
: agent.status !== "verified"))
|
|
720
|
+
|| record.events.some((event) => (event.type === "GLOBAL_VERIFIER_FAILED"
|
|
721
|
+
|| event.type === "SWARM_STOPPED"
|
|
722
|
+
|| event.type === "SWARM_NEEDS_REVIEW"));
|
|
723
|
+
}
|
|
724
|
+
function hasCanonicalDemoRecovery(record) {
|
|
725
|
+
const task = record.tasks.find((candidate) => candidate.taskId === "task-06");
|
|
726
|
+
const agent06 = record.agents.find((agent) => agent.agentId === "agent-06");
|
|
727
|
+
const agent10 = record.agents.find((agent) => agent.agentId === "agent-10");
|
|
728
|
+
if (!task
|
|
729
|
+
|| !agent06?.childRunId
|
|
730
|
+
|| !agent10?.childRunId
|
|
731
|
+
|| task.status !== "accepted"
|
|
732
|
+
|| task.assignedAgentId !== "agent-10"
|
|
733
|
+
|| !agent06.contract.taskIds.includes("task-06")
|
|
734
|
+
|| !agent10.contract.taskIds.includes("task-06"))
|
|
735
|
+
return false;
|
|
736
|
+
const recoveryTypes = [
|
|
737
|
+
"CHILD_PATCH_REJECTED",
|
|
738
|
+
"CHILD_STOPPED",
|
|
739
|
+
"TASK_REASSIGNED",
|
|
740
|
+
"CHILD_PATCH_ADMITTED"
|
|
741
|
+
];
|
|
742
|
+
if (recoveryTypes.some((type) => (record.events.filter((event) => event.type === type && event.taskId === "task-06").length !== 1)))
|
|
743
|
+
return false;
|
|
744
|
+
const rejected = matchingEvents(record, "CHILD_PATCH_REJECTED", "task-06", "agent-06", agent06.childRunId)
|
|
745
|
+
.filter((event) => event.payload.reason === "scope_creep");
|
|
746
|
+
const stopped = matchingEvents(record, "CHILD_STOPPED", "task-06", "agent-06", agent06.childRunId)
|
|
747
|
+
.filter((event) => event.payload.reason === "scope_creep");
|
|
748
|
+
const reassigned = matchingEvents(record, "TASK_REASSIGNED", "task-06", "agent-10", agent10.childRunId)
|
|
749
|
+
.filter((event) => event.payload.fromAgentId === "agent-06");
|
|
750
|
+
const admitted = matchingEvents(record, "CHILD_PATCH_ADMITTED", "task-06", "agent-10", agent10.childRunId);
|
|
751
|
+
const integrated = record.events.filter((event) => event.type === "INTEGRATION_COMPLETED" && hasBoundEventIdentity(record, event));
|
|
752
|
+
const verified = record.events.filter((event) => event.type === "GLOBAL_VERIFIER_PASSED" && hasBoundEventIdentity(record, event));
|
|
753
|
+
if (rejected.length !== 1
|
|
754
|
+
|| stopped.length !== 1
|
|
755
|
+
|| reassigned.length !== 1
|
|
756
|
+
|| admitted.length !== 1
|
|
757
|
+
|| integrated.length !== 1
|
|
758
|
+
|| verified.length !== 1)
|
|
759
|
+
return false;
|
|
760
|
+
const chain = [rejected[0], stopped[0], reassigned[0], admitted[0], integrated[0], verified[0]];
|
|
761
|
+
const positions = chain.map((event) => record.events.indexOf(event));
|
|
762
|
+
const timestamps = chain.map((event) => Date.parse(event.timestamp));
|
|
763
|
+
return positions.every((position, index) => index === 0 || position > positions[index - 1])
|
|
764
|
+
&& timestamps.every((timestamp, index) => (Number.isFinite(timestamp)
|
|
765
|
+
&& (index === 0 || timestamp > timestamps[index - 1])));
|
|
766
|
+
}
|
|
767
|
+
const DETERMINISTIC_DEMO_ROLES = [
|
|
768
|
+
"Planner",
|
|
769
|
+
"Data",
|
|
770
|
+
"API",
|
|
771
|
+
"Validation",
|
|
772
|
+
"UI",
|
|
773
|
+
"State",
|
|
774
|
+
"Unit Tests",
|
|
775
|
+
"Integration Tests",
|
|
776
|
+
"Accessibility",
|
|
777
|
+
"Error Handling",
|
|
778
|
+
"Docs",
|
|
779
|
+
"Scope Reviewer",
|
|
780
|
+
"Test Reviewer",
|
|
781
|
+
"Integrator",
|
|
782
|
+
"Final Verifier"
|
|
783
|
+
];
|
|
784
|
+
function hasCanonicalDemoRoster(record) {
|
|
785
|
+
if (record.agents.length !== DETERMINISTIC_DEMO_ROLES.length)
|
|
786
|
+
return false;
|
|
787
|
+
return DETERMINISTIC_DEMO_ROLES.every((role, index) => {
|
|
788
|
+
const expectedId = `agent-${String(index + 1).padStart(2, "0")}`;
|
|
789
|
+
const agent = record.agents[index];
|
|
790
|
+
return agent?.agentId === expectedId && agent.role === role;
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
function isAuthorizedTaskScope(record, agentId, writeScope) {
|
|
794
|
+
const agent = record.agents.find((candidate) => candidate.agentId === agentId);
|
|
795
|
+
if (!agent || writeScope.length === 0)
|
|
796
|
+
return false;
|
|
797
|
+
return writeScope.every((path) => {
|
|
798
|
+
const normalized = normalizeSwarmPathPattern(path);
|
|
799
|
+
if (!normalized.ok)
|
|
800
|
+
return false;
|
|
801
|
+
const value = normalized.value;
|
|
802
|
+
const allowedByParent = record.parentContract.scope.allowedPaths.some((allowed) => swarmPathPatternContains(allowed, value));
|
|
803
|
+
const allowedByChild = agent.contract.scope.allowedPaths.some((allowed) => swarmPathPatternContains(allowed, value));
|
|
804
|
+
return allowedByParent && allowedByChild;
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
function isContainedAdmittedPath(record, agentId, path, writeScope) {
|
|
808
|
+
if (typeof path !== "string")
|
|
809
|
+
return false;
|
|
810
|
+
const agent = record.agents.find((candidate) => candidate.agentId === agentId);
|
|
811
|
+
if (!agent)
|
|
812
|
+
return false;
|
|
813
|
+
const normalized = normalizeSwarmPathPattern(path);
|
|
814
|
+
if (!normalized.ok)
|
|
815
|
+
return false;
|
|
816
|
+
const value = normalized.value;
|
|
817
|
+
if (value.split("/").some((segment) => segment === "*" || segment === "**"))
|
|
818
|
+
return false;
|
|
819
|
+
const denied = [...record.parentContract.scope.deniedPaths, ...agent.contract.scope.deniedPaths];
|
|
820
|
+
return writeScope.some((scope) => swarmPathPatternContains(scope, value))
|
|
821
|
+
&& record.parentContract.scope.allowedPaths.some((allowed) => swarmPathPatternContains(allowed, value))
|
|
822
|
+
&& agent.contract.scope.allowedPaths.some((allowed) => swarmPathPatternContains(allowed, value))
|
|
823
|
+
&& denied.every((blocked) => !swarmPathPatternContains(blocked, value));
|
|
824
|
+
}
|
|
825
|
+
function hasBoundHistoricalReassignment(record, leaseId, taskId, priorAgentId) {
|
|
826
|
+
const task = record.tasks.find((candidate) => candidate.taskId === taskId);
|
|
827
|
+
const priorAgent = record.agents.find((candidate) => candidate.agentId === priorAgentId);
|
|
828
|
+
const currentAgent = record.agents.find((candidate) => candidate.agentId === task?.assignedAgentId);
|
|
829
|
+
if (!task
|
|
830
|
+
|| !priorAgent?.childRunId
|
|
831
|
+
|| !currentAgent?.childRunId
|
|
832
|
+
|| currentAgent.agentId === priorAgent.agentId
|
|
833
|
+
|| currentAgent.childRunId === priorAgent.childRunId
|
|
834
|
+
|| !priorAgent.contract.taskIds.includes(taskId)
|
|
835
|
+
|| !currentAgent.contract.taskIds.includes(taskId))
|
|
836
|
+
return false;
|
|
837
|
+
const priorStarted = matchingEvents(record, "CHILD_STARTED", taskId, priorAgentId, priorAgent.childRunId)
|
|
838
|
+
.filter((event) => event.payload.leaseId === leaseId);
|
|
839
|
+
const priorTerminal = matchingEvents(record, "CHILD_STOPPED", taskId, priorAgentId, priorAgent.childRunId);
|
|
840
|
+
const reassigned = record.events.filter((event) => (event.type === "TASK_REASSIGNED"
|
|
841
|
+
&& event.taskId === taskId
|
|
842
|
+
&& event.agentId === currentAgent.agentId
|
|
843
|
+
&& (event.childRunId === undefined || event.childRunId === currentAgent.childRunId)
|
|
844
|
+
&& event.payload.fromAgentId === priorAgentId
|
|
845
|
+
&& event.payload.toAgentId === currentAgent.agentId
|
|
846
|
+
&& hasText(event.payload.fromAttemptId)
|
|
847
|
+
&& hasText(event.payload.toAttemptId)
|
|
848
|
+
&& event.payload.fromAttemptId !== event.payload.toAttemptId
|
|
849
|
+
&& hasBoundEventIdentity(record, event)));
|
|
850
|
+
const currentStarted = matchingEvents(record, "CHILD_STARTED", taskId, currentAgent.agentId, currentAgent.childRunId);
|
|
851
|
+
if (priorStarted.length !== 1
|
|
852
|
+
|| priorTerminal.length !== 1
|
|
853
|
+
|| reassigned.length !== 1
|
|
854
|
+
|| currentStarted.length !== 1)
|
|
855
|
+
return false;
|
|
856
|
+
const fromAttemptId = reassigned[0].payload.fromAttemptId;
|
|
857
|
+
const toAttemptId = reassigned[0].payload.toAttemptId;
|
|
858
|
+
if (!hasText(fromAttemptId)
|
|
859
|
+
|| !hasText(toAttemptId)
|
|
860
|
+
|| priorStarted[0].payload.attemptId !== fromAttemptId
|
|
861
|
+
|| priorTerminal[0].payload.attemptId !== fromAttemptId
|
|
862
|
+
|| currentStarted[0].payload.attemptId !== toAttemptId)
|
|
863
|
+
return false;
|
|
864
|
+
const chain = [priorStarted[0], priorTerminal[0], reassigned[0], currentStarted[0]];
|
|
865
|
+
const positions = chain.map((event) => record.events.indexOf(event));
|
|
866
|
+
const timestamps = chain.map((event) => Date.parse(event.timestamp));
|
|
867
|
+
return positions.every((position, index) => index === 0 || position > positions[index - 1])
|
|
868
|
+
&& timestamps.every((timestamp, index) => (Number.isFinite(timestamp)
|
|
869
|
+
&& (index === 0 || timestamp > timestamps[index - 1])));
|
|
870
|
+
}
|
|
871
|
+
function isValidTerminalBudgetLedger(record) {
|
|
872
|
+
const ledger = record.budgetLedger;
|
|
873
|
+
if (!isNonnegativeFinite(ledger.capUsd)
|
|
874
|
+
|| (ledger.capTokens !== undefined && !isNonnegativeInteger(ledger.capTokens))
|
|
875
|
+
|| !isNonnegativeFinite(ledger.settledUsd)
|
|
876
|
+
|| !isNonnegativeInteger(ledger.settledTokens))
|
|
877
|
+
return false;
|
|
878
|
+
const leaseIds = new Set();
|
|
879
|
+
const agentIds = new Set(record.agents.map((agent) => agent.agentId));
|
|
880
|
+
const taskIds = new Set(record.tasks.map((task) => task.taskId));
|
|
881
|
+
let settledUsd = 0;
|
|
882
|
+
let settledTokens = 0;
|
|
883
|
+
let reservedUsd = 0;
|
|
884
|
+
let reservedTokens = 0;
|
|
885
|
+
let hasOverspentLease = false;
|
|
886
|
+
const childUsage = new Map();
|
|
887
|
+
for (const lease of ledger.leases) {
|
|
888
|
+
const agent = record.agents.find((candidate) => candidate.agentId === lease.agentId);
|
|
889
|
+
const task = record.tasks.find((candidate) => candidate.taskId === lease.taskId);
|
|
890
|
+
const currentAssignment = task?.assignedAgentId === lease.agentId;
|
|
891
|
+
const historicalAssignment = hasBoundHistoricalReassignment(record, lease.leaseId, lease.taskId, lease.agentId);
|
|
892
|
+
if (!hasText(lease.leaseId)
|
|
893
|
+
|| leaseIds.has(lease.leaseId)
|
|
894
|
+
|| !hasText(lease.agentId)
|
|
895
|
+
|| !agentIds.has(lease.agentId)
|
|
896
|
+
|| !agent
|
|
897
|
+
|| !hasText(lease.taskId)
|
|
898
|
+
|| !taskIds.has(lease.taskId)
|
|
899
|
+
|| !task
|
|
900
|
+
|| !agent.contract.taskIds.includes(lease.taskId)
|
|
901
|
+
|| (!currentAssignment && !historicalAssignment)
|
|
902
|
+
|| !(lease.status === "reserved" || lease.status === "settled" || lease.status === "overspent" || lease.status === "released")
|
|
903
|
+
|| !isNonnegativeFinite(lease.reservedUsd)
|
|
904
|
+
|| !isNonnegativeInteger(lease.reservedTokens))
|
|
905
|
+
return false;
|
|
906
|
+
leaseIds.add(lease.leaseId);
|
|
907
|
+
if (lease.status === "settled" || lease.status === "overspent") {
|
|
908
|
+
if (!lease.actualUsage
|
|
909
|
+
|| !isNonnegativeFinite(lease.actualUsage.usd)
|
|
910
|
+
|| !isNonnegativeInteger(lease.actualUsage.tokens))
|
|
911
|
+
return false;
|
|
912
|
+
const exceededReservation = lease.actualUsage.usd > lease.reservedUsd
|
|
913
|
+
|| lease.actualUsage.tokens > lease.reservedTokens;
|
|
914
|
+
if ((lease.status === "settled" && exceededReservation)
|
|
915
|
+
|| (lease.status === "overspent" && !exceededReservation))
|
|
916
|
+
return false;
|
|
917
|
+
if (lease.status === "overspent")
|
|
918
|
+
hasOverspentLease = true;
|
|
919
|
+
settledUsd += lease.actualUsage.usd;
|
|
920
|
+
settledTokens += lease.actualUsage.tokens;
|
|
921
|
+
const usage = childUsage.get(lease.agentId) ?? { usd: 0, tokens: 0 };
|
|
922
|
+
usage.usd += lease.actualUsage.usd;
|
|
923
|
+
usage.tokens += lease.actualUsage.tokens;
|
|
924
|
+
childUsage.set(lease.agentId, usage);
|
|
925
|
+
}
|
|
926
|
+
else if (lease.actualUsage !== undefined) {
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
if (lease.status === "reserved") {
|
|
930
|
+
reservedUsd += lease.reservedUsd;
|
|
931
|
+
reservedTokens += lease.reservedTokens;
|
|
932
|
+
const usage = childUsage.get(lease.agentId) ?? { usd: 0, tokens: 0 };
|
|
933
|
+
usage.usd += lease.reservedUsd;
|
|
934
|
+
usage.tokens += lease.reservedTokens;
|
|
935
|
+
childUsage.set(lease.agentId, usage);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
for (const agent of record.agents) {
|
|
939
|
+
const usage = childUsage.get(agent.agentId) ?? { usd: 0, tokens: 0 };
|
|
940
|
+
if (usage.usd > agent.contract.budget.maxUsd
|
|
941
|
+
|| (agent.contract.budget.maxTokens !== undefined && usage.tokens > agent.contract.budget.maxTokens))
|
|
942
|
+
return false;
|
|
943
|
+
}
|
|
944
|
+
return nearlyEqual(ledger.settledUsd, settledUsd)
|
|
945
|
+
&& ledger.settledTokens === settledTokens
|
|
946
|
+
&& (hasOverspentLease || settledUsd + reservedUsd <= ledger.capUsd)
|
|
947
|
+
&& (ledger.capTokens === undefined || hasOverspentLease || settledTokens + reservedTokens <= ledger.capTokens);
|
|
948
|
+
}
|
|
949
|
+
function matchingEvents(record, type, taskId, agentId, childRunId) {
|
|
950
|
+
return record.events.filter((event) => (event.type === type
|
|
951
|
+
&& event.taskId === taskId
|
|
952
|
+
&& event.agentId === agentId
|
|
953
|
+
&& event.childRunId === childRunId
|
|
954
|
+
&& hasBoundEventIdentity(record, event)));
|
|
955
|
+
}
|
|
956
|
+
function hasBoundEvent(record, type) {
|
|
957
|
+
return record.events.some((event) => event.type === type && hasBoundEventIdentity(record, event));
|
|
958
|
+
}
|
|
959
|
+
function hasBoundEventIdentity(record, event) {
|
|
960
|
+
return event.swarmId === record.swarmId
|
|
961
|
+
&& event.parentPolicyVersion === record.parentContract.policyVersion;
|
|
962
|
+
}
|
|
963
|
+
function sameStrings(left, right) {
|
|
964
|
+
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
965
|
+
}
|
|
966
|
+
function sameStringSet(left, right) {
|
|
967
|
+
return left.length === right.length && left.every((value) => right.includes(value));
|
|
968
|
+
}
|
|
969
|
+
function cloneEvent(event) {
|
|
970
|
+
return { ...event, payload: cloneValue(event.payload) };
|
|
971
|
+
}
|
|
972
|
+
function cloneSwarmRunRecord(record) {
|
|
973
|
+
return {
|
|
974
|
+
...record,
|
|
975
|
+
parentContract: {
|
|
976
|
+
...record.parentContract,
|
|
977
|
+
definitionOfDone: [...record.parentContract.definitionOfDone],
|
|
978
|
+
budget: { ...record.parentContract.budget },
|
|
979
|
+
scope: {
|
|
980
|
+
allowedPaths: [...record.parentContract.scope.allowedPaths],
|
|
981
|
+
deniedPaths: [...record.parentContract.scope.deniedPaths]
|
|
982
|
+
},
|
|
983
|
+
permissions: {
|
|
984
|
+
networkDomains: [...record.parentContract.permissions.networkDomains],
|
|
985
|
+
commands: [...record.parentContract.permissions.commands]
|
|
986
|
+
},
|
|
987
|
+
globalVerifierStack: record.parentContract.globalVerifierStack.map((step) => ({ ...step })),
|
|
988
|
+
stopPolicy: { ...record.parentContract.stopPolicy },
|
|
989
|
+
recoveryPolicy: { ...record.parentContract.recoveryPolicy },
|
|
990
|
+
approvalPolicy: { ...record.parentContract.approvalPolicy }
|
|
991
|
+
},
|
|
992
|
+
tasks: record.tasks.map((task) => ({
|
|
993
|
+
...task,
|
|
994
|
+
dependsOn: [...task.dependsOn],
|
|
995
|
+
writeScope: [...task.writeScope]
|
|
996
|
+
})),
|
|
997
|
+
agents: record.agents.map((agent) => ({
|
|
998
|
+
...agent,
|
|
999
|
+
contract: {
|
|
1000
|
+
...agent.contract,
|
|
1001
|
+
taskIds: [...agent.contract.taskIds],
|
|
1002
|
+
scope: {
|
|
1003
|
+
allowedPaths: [...agent.contract.scope.allowedPaths],
|
|
1004
|
+
deniedPaths: [...agent.contract.scope.deniedPaths]
|
|
1005
|
+
},
|
|
1006
|
+
budget: { ...agent.contract.budget },
|
|
1007
|
+
permissions: {
|
|
1008
|
+
networkDomains: [...agent.contract.permissions.networkDomains],
|
|
1009
|
+
commands: [...agent.contract.permissions.commands]
|
|
1010
|
+
},
|
|
1011
|
+
approvalPolicy: { ...agent.contract.approvalPolicy }
|
|
1012
|
+
}
|
|
1013
|
+
})),
|
|
1014
|
+
dependencyWaivers: record.dependencyWaivers.map((waiver) => ({ ...waiver })),
|
|
1015
|
+
budgetLedger: {
|
|
1016
|
+
...record.budgetLedger,
|
|
1017
|
+
leases: record.budgetLedger.leases.map((lease) => ({
|
|
1018
|
+
...lease,
|
|
1019
|
+
...(lease.actualUsage ? { actualUsage: { ...lease.actualUsage } } : {})
|
|
1020
|
+
}))
|
|
1021
|
+
},
|
|
1022
|
+
conflicts: record.conflicts.map((conflict) => ({
|
|
1023
|
+
...conflict,
|
|
1024
|
+
taskIds: [...conflict.taskIds],
|
|
1025
|
+
paths: [...conflict.paths]
|
|
1026
|
+
})),
|
|
1027
|
+
verification: record.verification.map((verification) => ({
|
|
1028
|
+
...verification,
|
|
1029
|
+
steps: verification.steps.map((step) => ({ ...step }))
|
|
1030
|
+
})),
|
|
1031
|
+
outcome: { ...record.outcome },
|
|
1032
|
+
events: record.events.map(cloneEvent)
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
function cloneValue(value) {
|
|
1036
|
+
if (Array.isArray(value))
|
|
1037
|
+
return value.map((item) => cloneValue(item));
|
|
1038
|
+
if (value !== null && typeof value === "object") {
|
|
1039
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, cloneValue(item)]));
|
|
1040
|
+
}
|
|
1041
|
+
return value;
|
|
1042
|
+
}
|
|
1043
|
+
function hasText(value) {
|
|
1044
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
1045
|
+
}
|
|
1046
|
+
function isNonnegativeFinite(value) {
|
|
1047
|
+
return Number.isFinite(value) && value >= 0;
|
|
1048
|
+
}
|
|
1049
|
+
function isNonnegativeInteger(value) {
|
|
1050
|
+
return Number.isInteger(value) && value >= 0;
|
|
1051
|
+
}
|
|
1052
|
+
function nearlyEqual(left, right) {
|
|
1053
|
+
return Math.abs(left - right) <= Number.EPSILON * Math.max(1, Math.abs(left), Math.abs(right));
|
|
1054
|
+
}
|
|
1055
|
+
function isCanonicalIsoDate(value) {
|
|
1056
|
+
if (!hasText(value))
|
|
1057
|
+
return false;
|
|
1058
|
+
const timestamp = Date.parse(value);
|
|
1059
|
+
return Number.isFinite(timestamp) && new Date(timestamp).toISOString() === value;
|
|
1060
|
+
}
|