@farmslot/recipe-cli 0.3.0 → 0.4.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/CHANGELOG.md +18 -0
- package/README.md +12 -12
- package/dist/harness/adapters.d.ts +2 -0
- package/dist/harness/adapters.d.ts.map +1 -1
- package/dist/harness/adapters.js +4 -0
- package/dist/harness/adapters.js.map +1 -1
- package/dist/harness/execution-provenance.d.ts +56 -0
- package/dist/harness/execution-provenance.d.ts.map +1 -0
- package/dist/harness/execution-provenance.js +308 -0
- package/dist/harness/execution-provenance.js.map +1 -0
- package/dist/harness/host.d.ts +8 -0
- package/dist/harness/host.d.ts.map +1 -1
- package/dist/harness/host.js +9 -2
- package/dist/harness/host.js.map +1 -1
- package/dist/harness/index.d.ts +12 -2
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +12 -2
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/live-adapter-contract.d.ts +32 -0
- package/dist/harness/live-adapter-contract.d.ts.map +1 -0
- package/dist/harness/live-adapter-contract.js +425 -0
- package/dist/harness/live-adapter-contract.js.map +1 -0
- package/dist/harness/recording-target.d.ts +9 -0
- package/dist/harness/recording-target.d.ts.map +1 -0
- package/dist/harness/recording-target.js +39 -0
- package/dist/harness/recording-target.js.map +1 -0
- package/dist/harness/run-diagnostics.d.ts +139 -0
- package/dist/harness/run-diagnostics.d.ts.map +1 -0
- package/dist/harness/run-diagnostics.js +458 -0
- package/dist/harness/run-diagnostics.js.map +1 -0
- package/dist/harness/run-options.d.ts +4 -0
- package/dist/harness/run-options.d.ts.map +1 -0
- package/dist/harness/run-options.js +35 -0
- package/dist/harness/run-options.js.map +1 -0
- package/dist/harness/run-recording.d.ts +43 -0
- package/dist/harness/run-recording.d.ts.map +1 -0
- package/dist/harness/run-recording.js +517 -0
- package/dist/harness/run-recording.js.map +1 -0
- package/dist/harness/run-report.d.ts +19 -0
- package/dist/harness/run-report.d.ts.map +1 -0
- package/dist/harness/run-report.js +269 -0
- package/dist/harness/run-report.js.map +1 -0
- package/dist/harness/runtime-proof.d.ts +27 -0
- package/dist/harness/runtime-proof.d.ts.map +1 -0
- package/dist/harness/runtime-proof.js +144 -0
- package/dist/harness/runtime-proof.js.map +1 -0
- package/dist/harness/suggest.d.ts +3 -0
- package/dist/harness/suggest.d.ts.map +1 -0
- package/dist/harness/suggest.js +37 -0
- package/dist/harness/suggest.js.map +1 -0
- package/dist/harness/trust.d.ts +38 -0
- package/dist/harness/trust.d.ts.map +1 -0
- package/dist/harness/trust.js +89 -0
- package/dist/harness/trust.js.map +1 -0
- package/package.json +5 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-report.d.ts","sourceRoot":"","sources":["../../src/harness/run-report.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,GAAG,SAAS,CAmBZ;AAKD,wBAAgB,8BAA8B,CAC5C,oBAAoB,EAAE,MAAM,EAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAc,GAAG,IAAW,GACpC,IAAI,CAsEN;AA4BD,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,EAAE,CAqBX;AAKD,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,oBAAoB,EAAE,MAAM,EAC5B,KAAK,EAAE,MAAM,EAAE,GACd,cAAc,GAAG,IAAI,CAOvB"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// The human run report (report.md), the product checkout provenance and the
|
|
2
|
+
// browser a run drove, written next to a run's artifacts.
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { harnessAdapter } from './adapters.js';
|
|
7
|
+
import { harnessHost } from './host.js';
|
|
8
|
+
import { isRecord } from './parse-args.js';
|
|
9
|
+
export function writeRunReport(result) {
|
|
10
|
+
const summaryPath = String(result.summaryPath);
|
|
11
|
+
const tracePath = String(result.tracePath);
|
|
12
|
+
const artifactManifestPath = String(result.artifactManifestPath);
|
|
13
|
+
const artifactsDir = path.dirname(summaryPath);
|
|
14
|
+
const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf8'));
|
|
15
|
+
const trace = JSON.parse(fs.readFileSync(tracePath, 'utf8'));
|
|
16
|
+
const entries = Array.isArray(trace.entries) ? trace.entries : [];
|
|
17
|
+
const lines = renderRunReport(summary, entries);
|
|
18
|
+
const reportPath = path.join(artifactsDir, 'report.md');
|
|
19
|
+
fs.writeFileSync(reportPath, `${lines.join('\n')}\n`);
|
|
20
|
+
indexRunReportArtifact(artifactManifestPath);
|
|
21
|
+
return {
|
|
22
|
+
path: reportPath,
|
|
23
|
+
preview: lines
|
|
24
|
+
.filter((line) => line.startsWith('- '))
|
|
25
|
+
.slice(0, 6)
|
|
26
|
+
.map((line) => line.slice(2)),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// `browser` is the browser the run drove, bound by runRecipe while the run's
|
|
30
|
+
// ports were active (see executedBrowser); it is never re-derived here, after
|
|
31
|
+
// the run environment was restored.
|
|
32
|
+
export function indexProductProvenanceArtifact(artifactManifestPath, target, adapter, browser = null) {
|
|
33
|
+
const artifactsDir = path.dirname(artifactManifestPath);
|
|
34
|
+
let gitRef = 'unknown';
|
|
35
|
+
let branch = 'unknown';
|
|
36
|
+
let dirty = true;
|
|
37
|
+
try {
|
|
38
|
+
gitRef = execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
39
|
+
cwd: target,
|
|
40
|
+
encoding: 'utf8',
|
|
41
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
42
|
+
}).trim();
|
|
43
|
+
branch =
|
|
44
|
+
execFileSync('git', ['branch', '--show-current'], {
|
|
45
|
+
cwd: target,
|
|
46
|
+
encoding: 'utf8',
|
|
47
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
48
|
+
}).trim() || 'detached';
|
|
49
|
+
dirty =
|
|
50
|
+
execFileSync('git', ['status', '--porcelain', '--untracked-files=normal'], {
|
|
51
|
+
cwd: target,
|
|
52
|
+
encoding: 'utf8',
|
|
53
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
54
|
+
}).trim().length > 0;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Non-git targets keep explicit unknown provenance.
|
|
58
|
+
}
|
|
59
|
+
const provenance = {
|
|
60
|
+
schemaVersion: 1,
|
|
61
|
+
adapter,
|
|
62
|
+
repository: path.basename(path.resolve(target)),
|
|
63
|
+
git_ref: gitRef,
|
|
64
|
+
branch,
|
|
65
|
+
dirty,
|
|
66
|
+
...(browser ? { browser } : {}),
|
|
67
|
+
};
|
|
68
|
+
fs.writeFileSync(path.join(artifactsDir, 'product-provenance.json'), `${JSON.stringify(provenance, null, 2)}\n`);
|
|
69
|
+
let manifest;
|
|
70
|
+
try {
|
|
71
|
+
manifest = JSON.parse(fs.readFileSync(artifactManifestPath, 'utf8'));
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!isRecord(manifest))
|
|
77
|
+
return;
|
|
78
|
+
const artifacts = Array.isArray(manifest.artifacts) ? manifest.artifacts : [];
|
|
79
|
+
manifest.artifacts = [
|
|
80
|
+
...artifacts.filter((artifact) => !isRecord(artifact) || artifact.path !== 'product-provenance.json'),
|
|
81
|
+
{
|
|
82
|
+
path: 'product-provenance.json',
|
|
83
|
+
type: 'json',
|
|
84
|
+
label: 'Product checkout provenance',
|
|
85
|
+
category: 'system',
|
|
86
|
+
metadata: {
|
|
87
|
+
adapter,
|
|
88
|
+
git_ref: gitRef,
|
|
89
|
+
branch,
|
|
90
|
+
dirty,
|
|
91
|
+
...(browser?.boundTo && browser.boundTo !== 'none'
|
|
92
|
+
? (harnessAdapter(adapter).run?.browserProvenance?.(browser) ?? {})
|
|
93
|
+
: {}),
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
fs.writeFileSync(artifactManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
98
|
+
}
|
|
99
|
+
// A node's cdp_port, literal or "{{params.name}}" resolved from the run's
|
|
100
|
+
// params, then the recipe's paramsSchema default; null when it stays unknown.
|
|
101
|
+
function resolveTemplatedPort(value, params, recipe) {
|
|
102
|
+
let resolved = value;
|
|
103
|
+
const template = /^\{\{\s*params\.([\w-]+)\s*\}\}$/u.exec(String(value).trim());
|
|
104
|
+
if (template) {
|
|
105
|
+
const name = template[1];
|
|
106
|
+
const schema = isRecord(recipe) && isRecord(recipe.paramsSchema) && isRecord(recipe.paramsSchema.properties)
|
|
107
|
+
? recipe.paramsSchema.properties[name]
|
|
108
|
+
: undefined;
|
|
109
|
+
resolved =
|
|
110
|
+
isRecord(params) && params[name] !== undefined
|
|
111
|
+
? params[name]
|
|
112
|
+
: isRecord(schema)
|
|
113
|
+
? schema.default
|
|
114
|
+
: undefined;
|
|
115
|
+
}
|
|
116
|
+
const text = String(resolved ?? '').trim();
|
|
117
|
+
return /^\d+$/u.test(text) ? text : null;
|
|
118
|
+
}
|
|
119
|
+
// The CDP ports a run's actions were given: the run environment's port (same
|
|
120
|
+
// precedence as the adapters: CDP_PORT, then RECIPE_CDP_PORT) and any
|
|
121
|
+
// `cdp_port` a node of the run's own recipe sets for itself. Nodes inside
|
|
122
|
+
// called library recipes are not walked; no shipped recipe sets cdp_port.
|
|
123
|
+
export function recipeCdpPorts(request) {
|
|
124
|
+
const ports = new Set();
|
|
125
|
+
const envPort = request.env?.CDP_PORT || request.env?.RECIPE_CDP_PORT;
|
|
126
|
+
if (envPort)
|
|
127
|
+
ports.add(String(envPort));
|
|
128
|
+
let recipe = request.recipeDocument;
|
|
129
|
+
if (recipe === undefined && request.recipePath) {
|
|
130
|
+
try {
|
|
131
|
+
recipe = JSON.parse(fs.readFileSync(request.recipePath, 'utf8'));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
recipe = undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const workflow = isRecord(recipe) && isRecord(recipe.workflow) ? recipe.workflow : null;
|
|
138
|
+
const nodes = workflow && isRecord(workflow.nodes) ? Object.values(workflow.nodes) : [];
|
|
139
|
+
for (const node of nodes) {
|
|
140
|
+
if (!isRecord(node) || node.cdp_port === undefined || node.cdp_port === null)
|
|
141
|
+
continue;
|
|
142
|
+
const port = resolveTemplatedPort(node.cdp_port, request.params, recipe);
|
|
143
|
+
// An unresolvable template could name any port, so it blocks binding.
|
|
144
|
+
ports.add(port ?? `unresolved ${String(node.cdp_port)}`);
|
|
145
|
+
}
|
|
146
|
+
return [...ports];
|
|
147
|
+
}
|
|
148
|
+
// The browser a run drove, bound by the engine while the run is active,
|
|
149
|
+
// against the port(s) its actions were given. Binding needs exactly one known
|
|
150
|
+
// port; the caller's environment is never consulted.
|
|
151
|
+
export function executedBrowser(adapter, target, artifactManifestPath, ports) {
|
|
152
|
+
const run = harnessAdapter(adapter).run;
|
|
153
|
+
if (!run?.launchedBrowser)
|
|
154
|
+
return null;
|
|
155
|
+
if (ports.length === 0)
|
|
156
|
+
return { boundTo: 'none', reason: 'the run had no known CDP port' };
|
|
157
|
+
if (ports.length > 1)
|
|
158
|
+
return { boundTo: 'none', reason: `the run drove several CDP ports (${ports.join(', ')})` };
|
|
159
|
+
return run.launchedBrowser(target, path.dirname(artifactManifestPath), ports[0]);
|
|
160
|
+
}
|
|
161
|
+
function renderRunReport(summary, entries) {
|
|
162
|
+
const lines = [
|
|
163
|
+
`# ${harnessHost().product} Recipe Run`,
|
|
164
|
+
'',
|
|
165
|
+
`Status: ${String(summary.status ?? 'unknown')}`,
|
|
166
|
+
`Duration: ${formatDuration(Number(summary.durationMs ?? 0))}`,
|
|
167
|
+
`Nodes: ${Number(summary.passed ?? 0)}/${Number(summary.total ?? entries.length)} passed`,
|
|
168
|
+
];
|
|
169
|
+
const sideFindings = isRecord(summary.sideFindings) ? summary.sideFindings : undefined;
|
|
170
|
+
const sideFindingCounts = sideFindings && isRecord(sideFindings.counts) ? sideFindings.counts : undefined;
|
|
171
|
+
const sideFindingTotal = Number(sideFindingCounts?.total ?? 0);
|
|
172
|
+
if (sideFindingTotal > 0) {
|
|
173
|
+
lines.push('', '## Side findings', `- REVIEW ${sideFindingTotal} distinct application warning/error event(s) (non-blocking; expanded below and stored in diagnostics.json)`);
|
|
174
|
+
}
|
|
175
|
+
lines.push('', '## Steps');
|
|
176
|
+
for (const entry of entries) {
|
|
177
|
+
if (!isRecord(entry))
|
|
178
|
+
continue;
|
|
179
|
+
const mark = entry.ok === false ? 'FAIL' : 'PASS';
|
|
180
|
+
const nodeId = String(entry.nodeId ?? '(node)');
|
|
181
|
+
const action = String(entry.action ?? '(action)');
|
|
182
|
+
const duration = formatDuration(Number(entry.durationMs ?? 0));
|
|
183
|
+
const detail = summarizeNodeOutput(entry.output);
|
|
184
|
+
lines.push(`- ${mark} ${nodeId} (${action}, ${duration})${detail ? `: ${detail}` : ''}`);
|
|
185
|
+
}
|
|
186
|
+
return lines;
|
|
187
|
+
}
|
|
188
|
+
function summarizeNodeOutput(output) {
|
|
189
|
+
if (!isRecord(output))
|
|
190
|
+
return '';
|
|
191
|
+
const parts = [];
|
|
192
|
+
const preferredKeys = [
|
|
193
|
+
'platform',
|
|
194
|
+
'screen',
|
|
195
|
+
'route',
|
|
196
|
+
'page',
|
|
197
|
+
'network',
|
|
198
|
+
'account',
|
|
199
|
+
'count',
|
|
200
|
+
'matchingCount',
|
|
201
|
+
'proofPath',
|
|
202
|
+
'screenshot',
|
|
203
|
+
'path',
|
|
204
|
+
];
|
|
205
|
+
for (const key of preferredKeys)
|
|
206
|
+
addPart(parts, labelFor(key), summarizeValue(output[key]));
|
|
207
|
+
const accountState = isRecord(output.accountState) ? output.accountState : undefined;
|
|
208
|
+
if (accountState) {
|
|
209
|
+
addPart(parts, 'totalBalance', accountState.totalBalance);
|
|
210
|
+
addPart(parts, 'spendable', accountState.spendableBalance);
|
|
211
|
+
addPart(parts, 'marginUsed', accountState.marginUsed);
|
|
212
|
+
addPart(parts, 'unrealizedPnl', accountState.unrealizedPnl);
|
|
213
|
+
}
|
|
214
|
+
if (parts.length === 0) {
|
|
215
|
+
for (const [key, value] of Object.entries(output)) {
|
|
216
|
+
if (parts.length >= 5)
|
|
217
|
+
break;
|
|
218
|
+
if (key === 'liveAdapter' || key === 'artifacts')
|
|
219
|
+
continue;
|
|
220
|
+
addPart(parts, key, summarizeValue(value));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return parts.join(', ');
|
|
224
|
+
}
|
|
225
|
+
function labelFor(key) {
|
|
226
|
+
return key === 'matchingCount' ? 'matching' : key === 'proofPath' ? 'proof' : key;
|
|
227
|
+
}
|
|
228
|
+
function summarizeValue(value) {
|
|
229
|
+
if (typeof value === 'string')
|
|
230
|
+
return shortenAddress(value);
|
|
231
|
+
if (typeof value === 'number' || typeof value === 'boolean')
|
|
232
|
+
return value;
|
|
233
|
+
if (Array.isArray(value))
|
|
234
|
+
return `${value.length} item${value.length === 1 ? '' : 's'}`;
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
function addPart(parts, label, value) {
|
|
238
|
+
if (value === undefined || value === null || value === '')
|
|
239
|
+
return;
|
|
240
|
+
parts.push(`${label}=${String(value)}`);
|
|
241
|
+
}
|
|
242
|
+
function shortenAddress(value) {
|
|
243
|
+
return /^0x[a-fA-F0-9]{40}$/u.test(value) ? `${value.slice(0, 6)}...${value.slice(-4)}` : value;
|
|
244
|
+
}
|
|
245
|
+
function formatDuration(ms) {
|
|
246
|
+
if (!Number.isFinite(ms) || ms <= 0)
|
|
247
|
+
return '0ms';
|
|
248
|
+
if (ms < 1000)
|
|
249
|
+
return `${Math.round(ms)}ms`;
|
|
250
|
+
return `${(ms / 1000).toFixed(ms < 10000 ? 1 : 0)}s`;
|
|
251
|
+
}
|
|
252
|
+
function indexRunReportArtifact(artifactManifestPath) {
|
|
253
|
+
let manifest;
|
|
254
|
+
try {
|
|
255
|
+
manifest = JSON.parse(fs.readFileSync(artifactManifestPath, 'utf8'));
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (!isRecord(manifest))
|
|
261
|
+
return;
|
|
262
|
+
const artifacts = Array.isArray(manifest.artifacts) ? manifest.artifacts : [];
|
|
263
|
+
manifest.artifacts = [
|
|
264
|
+
...artifacts.filter((artifact) => !isRecord(artifact) || artifact.path !== 'report.md'),
|
|
265
|
+
{ path: 'report.md', type: 'report', label: 'Human run report', category: 'system' },
|
|
266
|
+
];
|
|
267
|
+
fs.writeFileSync(artifactManifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=run-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-report.js","sourceRoot":"","sources":["../../src/harness/run-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type RecipeValidationFinding, validateRecipeArtifactPackage } from '@farmslot/protocol';
|
|
2
|
+
/** Validate executed behavioral proof, independently of any task host or control plane. */
|
|
3
|
+
export declare function validateRuntimeProof(bundle: Parameters<typeof validateRecipeArtifactPackage>[0], smokeTarget?: string): void;
|
|
4
|
+
/**
|
|
5
|
+
* Check possible proof bindings after protocol/dependency validation, without executing a graph.
|
|
6
|
+
* A clean result is conditional: order, branches, successful observations and indexed artifacts
|
|
7
|
+
* still require validateRuntimeProof on the executed package.
|
|
8
|
+
*/
|
|
9
|
+
export declare function validateRuntimeProofPlan(recipe: ProofDocument, documents?: ReadonlyMap<string, ProofDocument>): RecipeValidationFinding[];
|
|
10
|
+
/** The recipe shape proof checks read: its proof targets and workflow nodes. */
|
|
11
|
+
export interface ProofDocument {
|
|
12
|
+
proofTargets?: {
|
|
13
|
+
id: string;
|
|
14
|
+
}[];
|
|
15
|
+
workflow: {
|
|
16
|
+
nodes: Record<string, ProofNode>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface ProofNode {
|
|
20
|
+
action: string;
|
|
21
|
+
ref?: string;
|
|
22
|
+
proves?: string[];
|
|
23
|
+
source?: string;
|
|
24
|
+
node?: string;
|
|
25
|
+
path?: string;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=runtime-proof.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-proof.d.ts","sourceRoot":"","sources":["../../src/harness/runtime-proof.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,uBAAuB,EAC5B,6BAA6B,EAC9B,MAAM,oBAAoB,CAAC;AAE5B,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,CAAC,OAAO,6BAA6B,CAAC,CAAC,CAAC,CAAC,EAC3D,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAmFN;AAwDD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,aAAa,EACrB,SAAS,GAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAa,GACxD,uBAAuB,EAAE,CA0C3B;AAED,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;KAAE,CAAC;CAChD;AACD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Behavioral proof checks on a recipe: the plan before it runs, and the
|
|
2
|
+
// executed artifact package after, independently of any task host.
|
|
3
|
+
import assert from 'node:assert/strict';
|
|
4
|
+
import { normalizeRecipeRef, validateRecipeArtifactPackage, } from '@farmslot/protocol';
|
|
5
|
+
/** Validate executed behavioral proof, independently of any task host or control plane. */
|
|
6
|
+
export function validateRuntimeProof(bundle, smokeTarget) {
|
|
7
|
+
const checked = validateRecipeArtifactPackage(bundle);
|
|
8
|
+
assert.equal(checked.status, 'valid', JSON.stringify(checked.findings));
|
|
9
|
+
const { recipe, summary, trace, manifest, recipeResolution, resolvedRecipes } = bundle;
|
|
10
|
+
assert.equal(summary.status, 'pass', 'Runtime recipe did not pass');
|
|
11
|
+
const entries = Array.isArray(trace) ? trace : trace.entries;
|
|
12
|
+
assert(entries.length && entries.every((entry) => entry.ok === true), 'Runtime trace contains failed or unknown actions');
|
|
13
|
+
assert(entries.some((entry) => entry.action === 'end' &&
|
|
14
|
+
entry.status === 'pass' &&
|
|
15
|
+
!String(entry.nodeId ?? entry.id).includes('/')), 'Runtime recipe did not reach its passing end');
|
|
16
|
+
const documents = new Map(recipeResolution.dependencies.map((dependency) => [
|
|
17
|
+
normalizeRecipeRef(dependency.ref),
|
|
18
|
+
resolvedRecipes[dependency.digest],
|
|
19
|
+
]));
|
|
20
|
+
const nodes = collectProofNodes(recipe, documents);
|
|
21
|
+
const executed = new Map(entries.map((entry, index) => [entry.nodeId ?? entry.id, { entry, index }]));
|
|
22
|
+
function proves(id) {
|
|
23
|
+
const node = nodes.get(id);
|
|
24
|
+
const current = executed.get(id);
|
|
25
|
+
if (!current || current.entry.action !== node.action)
|
|
26
|
+
return false;
|
|
27
|
+
if (node.action === 'call')
|
|
28
|
+
return [...nodes.keys()].some((child) => child.startsWith(`${id}/`) && proves(child));
|
|
29
|
+
if (!assertions.has(node.action) ||
|
|
30
|
+
!current.entry.output ||
|
|
31
|
+
typeof current.entry.output !== 'object')
|
|
32
|
+
return false;
|
|
33
|
+
if (node.action === 'assert_output') {
|
|
34
|
+
const source = assertionSource(id, node);
|
|
35
|
+
const prior = executed.get(source);
|
|
36
|
+
const action = nodes.get(source)?.action;
|
|
37
|
+
return Boolean(prior &&
|
|
38
|
+
prior.index < current.index &&
|
|
39
|
+
action &&
|
|
40
|
+
action === prior.entry.action &&
|
|
41
|
+
isObservation(action));
|
|
42
|
+
}
|
|
43
|
+
if (node.action === 'ui.wait_for')
|
|
44
|
+
return entries.slice(0, current.index).some((entry) => inputs.has(entry.action));
|
|
45
|
+
return (typeof node.path === 'string' &&
|
|
46
|
+
manifest.artifacts.some((artifact) => artifact.path === node.path && artifact.category === 'proof'));
|
|
47
|
+
}
|
|
48
|
+
assert(recipe.proofTargets?.length, 'Runtime recipe has no behavioral proof targets');
|
|
49
|
+
for (const target of recipe.proofTargets) {
|
|
50
|
+
const linked = [...nodes].filter(([, node]) => node.proves?.includes(target.id));
|
|
51
|
+
assert(linked.some(([id]) => proves(id)), `Proof target ${target.id} has no executed runtime assertion`);
|
|
52
|
+
}
|
|
53
|
+
if (smokeTarget)
|
|
54
|
+
assert(recipe.proofTargets.some((target) => target.id === smokeTarget), 'Smoke target is absent from recipe');
|
|
55
|
+
}
|
|
56
|
+
const assertions = new Set(['assert_output', 'assert_json', 'ui.wait_for']);
|
|
57
|
+
const controls = new Set([
|
|
58
|
+
'end',
|
|
59
|
+
'wait',
|
|
60
|
+
'manual',
|
|
61
|
+
'switch',
|
|
62
|
+
'call',
|
|
63
|
+
'index_artifacts',
|
|
64
|
+
'assert_exit_code',
|
|
65
|
+
'assert_file',
|
|
66
|
+
'branch',
|
|
67
|
+
'repeat',
|
|
68
|
+
'set',
|
|
69
|
+
'log',
|
|
70
|
+
]);
|
|
71
|
+
const inputs = new Set([
|
|
72
|
+
'ui.press',
|
|
73
|
+
'ui.key_press',
|
|
74
|
+
'ui.set_input',
|
|
75
|
+
'ui.swipe',
|
|
76
|
+
'ui.drag',
|
|
77
|
+
'ui.long_press',
|
|
78
|
+
]);
|
|
79
|
+
function isObservation(action) {
|
|
80
|
+
return !controls.has(action) && !assertions.has(action);
|
|
81
|
+
}
|
|
82
|
+
function assertionSource(id, node) {
|
|
83
|
+
const prefix = id.includes('/') ? id.slice(0, id.lastIndexOf('/') + 1) : '';
|
|
84
|
+
return prefix + String(node.source ?? node.node ?? '');
|
|
85
|
+
}
|
|
86
|
+
function collectProofNodes(recipe, documents) {
|
|
87
|
+
const nodes = new Map();
|
|
88
|
+
function collect(document, prefix = '', stack = new Set()) {
|
|
89
|
+
for (const [id, node] of Object.entries(document.workflow.nodes)) {
|
|
90
|
+
nodes.set(prefix + id, node);
|
|
91
|
+
if (node.action === 'call' && typeof node.ref === 'string') {
|
|
92
|
+
const ref = normalizeRecipeRef(node.ref);
|
|
93
|
+
assert(!stack.has(ref), 'Recursive recipe proof');
|
|
94
|
+
const nested = documents.get(ref);
|
|
95
|
+
assert(nested, `Missing resolved recipe ${ref}`);
|
|
96
|
+
collect(nested, `${prefix}${id}/`, new Set(stack).add(ref));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
collect(recipe);
|
|
101
|
+
return nodes;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check possible proof bindings after protocol/dependency validation, without executing a graph.
|
|
105
|
+
* A clean result is conditional: order, branches, successful observations and indexed artifacts
|
|
106
|
+
* still require validateRuntimeProof on the executed package.
|
|
107
|
+
*/
|
|
108
|
+
export function validateRuntimeProofPlan(recipe, documents = new Map()) {
|
|
109
|
+
const finding = (code, path, message) => ({
|
|
110
|
+
severity: 'error',
|
|
111
|
+
code,
|
|
112
|
+
path,
|
|
113
|
+
message,
|
|
114
|
+
});
|
|
115
|
+
if (!recipe.proofTargets?.length)
|
|
116
|
+
return [
|
|
117
|
+
finding('proof.targets_missing', 'proofTargets', 'Behavioral proof requires at least one proof target.'),
|
|
118
|
+
];
|
|
119
|
+
const nodes = collectProofNodes(recipe, documents);
|
|
120
|
+
const hasInput = [...nodes.values()].some((node) => inputs.has(node.action));
|
|
121
|
+
function eligible(id) {
|
|
122
|
+
const node = nodes.get(id);
|
|
123
|
+
if (node.action === 'call')
|
|
124
|
+
return [...nodes.keys()].some((child) => child.startsWith(`${id}/`) && eligible(child));
|
|
125
|
+
if (node.action === 'assert_output') {
|
|
126
|
+
const source = nodes.get(assertionSource(id, node));
|
|
127
|
+
return Boolean(source && isObservation(source.action));
|
|
128
|
+
}
|
|
129
|
+
// Inputs may live in a caller or a sibling call. Do not infer execution order here.
|
|
130
|
+
if (node.action === 'ui.wait_for')
|
|
131
|
+
return hasInput;
|
|
132
|
+
// The manifest is created at execution; a path alone cannot prove it will be indexed.
|
|
133
|
+
return node.action === 'assert_json' && typeof node.path === 'string';
|
|
134
|
+
}
|
|
135
|
+
return recipe.proofTargets.flatMap((target, index) => {
|
|
136
|
+
const linked = [...nodes].filter(([, node]) => node.proves?.includes(target.id));
|
|
137
|
+
return linked.some(([id]) => eligible(id))
|
|
138
|
+
? []
|
|
139
|
+
: [
|
|
140
|
+
finding('proof.no_runtime_assertion', `proofTargets[${index}]`, `Proof target ${target.id} has no potentially eligible runtime assertion. Bind proves to assert_output over an observation, ui.wait_for with an input action, assert_json over a proof artifact, or a call containing one. Runtime order, outcomes and artifact indexing remain unverified.`),
|
|
141
|
+
];
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=runtime-proof.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-proof.js","sourceRoot":"","sources":["../../src/harness/runtime-proof.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest.d.ts","sourceRoot":"","sources":["../../src/harness/suggest.ts"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAYxF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// "Did you mean" suggestions for a mistyped command, option, value or action.
|
|
2
|
+
/** The candidate nearest `input` by edit distance, or undefined when none is close. */
|
|
3
|
+
export function closest(input, candidates) {
|
|
4
|
+
if (candidates.length === 0)
|
|
5
|
+
return undefined;
|
|
6
|
+
const ranked = candidates
|
|
7
|
+
.map((candidate) => ({ candidate, distance: levenshtein(input, candidate) }))
|
|
8
|
+
.sort((left, right) => left.distance - right.distance || left.candidate.localeCompare(right.candidate));
|
|
9
|
+
const best = ranked[0];
|
|
10
|
+
if (!best)
|
|
11
|
+
return undefined;
|
|
12
|
+
const threshold = Math.max(2, Math.floor(Math.max(input.length, best.candidate.length) / 3));
|
|
13
|
+
return best.distance <= threshold ? best.candidate : undefined;
|
|
14
|
+
}
|
|
15
|
+
// Optimal string alignment distance: an adjacent transposition costs one edit.
|
|
16
|
+
function levenshtein(left, right) {
|
|
17
|
+
let twoBack;
|
|
18
|
+
let prior = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
19
|
+
for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) {
|
|
20
|
+
const current = [leftIndex];
|
|
21
|
+
for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) {
|
|
22
|
+
const substitution = prior[rightIndex - 1] + (left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1);
|
|
23
|
+
current[rightIndex] = Math.min((current[rightIndex - 1] ?? 0) + 1, (prior[rightIndex] ?? 0) + 1, substitution);
|
|
24
|
+
if (twoBack &&
|
|
25
|
+
leftIndex > 1 &&
|
|
26
|
+
rightIndex > 1 &&
|
|
27
|
+
left[leftIndex - 1] === right[rightIndex - 2] &&
|
|
28
|
+
left[leftIndex - 2] === right[rightIndex - 1]) {
|
|
29
|
+
current[rightIndex] = Math.min(current[rightIndex] ?? 0, (twoBack[rightIndex - 2] ?? 0) + 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
twoBack = prior;
|
|
33
|
+
prior = current;
|
|
34
|
+
}
|
|
35
|
+
return prior[right.length] ?? right.length;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=suggest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest.js","sourceRoot":"","sources":["../../src/harness/suggest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RecipeExecutionApproval, RecipeSourceProvenance } from '@farmslot/protocol';
|
|
2
|
+
/** Source provenance and plan approval from explicit flags; absent flags add nothing. */
|
|
3
|
+
export declare function explicitRecipeTrustOptions(values: {
|
|
4
|
+
sourceTrust?: string;
|
|
5
|
+
sourceKind?: string;
|
|
6
|
+
sourceName?: string;
|
|
7
|
+
sourceDigest?: string;
|
|
8
|
+
approvalDigest?: string;
|
|
9
|
+
}): {
|
|
10
|
+
source?: RecipeSourceProvenance;
|
|
11
|
+
approval?: RecipeExecutionApproval;
|
|
12
|
+
};
|
|
13
|
+
export type RecipeTrustFailure = {
|
|
14
|
+
code: string;
|
|
15
|
+
message: string;
|
|
16
|
+
userAction: string;
|
|
17
|
+
details?: {
|
|
18
|
+
recipeDigest?: string;
|
|
19
|
+
trust?: string;
|
|
20
|
+
blocked?: Array<{
|
|
21
|
+
nodeId: string;
|
|
22
|
+
action: string;
|
|
23
|
+
capabilities: string[];
|
|
24
|
+
source: string;
|
|
25
|
+
implementation?: {
|
|
26
|
+
kind?: string;
|
|
27
|
+
trust?: string;
|
|
28
|
+
digest?: string;
|
|
29
|
+
};
|
|
30
|
+
}>;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* A `RECIPE_*` trust error as a command envelope, without the blocked nodes'
|
|
35
|
+
* payloads; undefined for any other error.
|
|
36
|
+
*/
|
|
37
|
+
export declare function recipeTrustFailure(error: unknown): RecipeTrustFailure | undefined;
|
|
38
|
+
//# sourceMappingURL=trust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust.d.ts","sourceRoot":"","sources":["../../src/harness/trust.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EAEvB,sBAAsB,EAEvB,MAAM,oBAAoB,CAAC;AAE5B,yFAAyF;AACzF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG;IAAE,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAe1E;AAGD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE;QACR,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,KAAK,CAAC;YACd,MAAM,EAAE,MAAM,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,YAAY,EAAE,MAAM,EAAE,CAAC;YACvB,MAAM,EAAE,MAAM,CAAC;YACf,cAAc,CAAC,EAAE;gBACf,IAAI,CAAC,EAAE,MAAM,CAAC;gBACd,KAAK,CAAC,EAAE,MAAM,CAAC;gBACf,MAAM,CAAC,EAAE,MAAM,CAAC;aACjB,CAAC;SACH,CAAC,CAAC;KACJ,CAAC;CACH,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,GAAG,SAAS,CA2EjF"}
|