@farmslot/adapter-sdk 0.9.1 → 0.10.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,14 @@ All notable changes to `@farmslot/adapter-sdk` are tracked here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ - Active-development baseline; add user-facing changes here before release or package publication.
8
+
9
+ ## 0.10.0 - 2026-10-13
10
+
11
+ - Display rejected task-ledger package inputs without crashing or granting measured proof.
12
+ - Group retained evidence diagnostics into package status rows and open digest-verified reports independently of recipe proof errors.
13
+ - Share claim/step evidence selection, captions, source clips/stills and verified playback ranges across review clients (ADR-062).
14
+
7
15
  ## 0.9.1 - 2026-10-12
8
16
 
9
17
  - Update shared runtime dependencies for bounded recipe log observations.
package/README.md CHANGED
@@ -65,3 +65,26 @@ See [ADR-062](../../docs/adr/062-recorded-run-evidence.md) and its
65
65
  ```sh
66
66
  yarn workspace @farmslot/adapter-sdk quality
67
67
  ```
68
+
69
+ ### Evidence review
70
+
71
+ The experimental `@farmslot/adapter-sdk/evidence` entry exports
72
+ `createEvidenceReviewModel`, `loadRecordingEvidenceReview` and
73
+ `readEvidenceReviewReport`, with their request/result types. Web and native review
74
+ clients use this model for claims, recipe occurrences, captions, original-media
75
+ clips, stills and bounded playback effects. They implement only transport and
76
+ rendering. `selectClaim` and `selectOccurrence` preserve missing or untimed proof;
77
+ they never write a verdict. Original `videoPath` identifies playback independently
78
+ of its digest, so equal-byte segments retain their own clocks.
79
+
80
+ The existing Node entry exports `readRecordedEvidencePackage` and its read types.
81
+ Its optional `RecordedEvidencePackageReadIO` lets a trusted host supply contained
82
+ JSON reads, a file inventory and actual-byte digests for one retained root. The
83
+ default filesystem reader and its diagnostics remain the same. Always reject
84
+ failed read checks and run `validateRecordedEvidencePackage`; a metadata snapshot
85
+ alone is not approval or publication authority.
86
+
87
+ A report model takes the existing output manifest and `OutputReviewPayload`.
88
+ `readEvidenceReviewReport` verifies the selected report bytes against that manifest
89
+ before returning text. Reviewers can open its case/check claims through the same
90
+ model. No separate QA verdict reducer or player is needed.
@@ -0,0 +1,108 @@
1
+ import { type AcceptanceCriterionRef, type AcceptanceCriterionView, type AcceptanceEvidenceLink, type AcceptanceStatusLedger, type AcceptanceStatusSummary, type EvidenceMomentRef, type OutputReviewPayload, type RecipeClaimKind, type RecipeRecordingTimelineBinding, type RecipeRecordingTimelineDocument, type RecordedEvidencePackageInput, type RunOutput } from '@farmslot/protocol';
2
+ import { type EvidenceReviewPackageStatus } from './evidence-review-status.js';
3
+ export type EvidenceReviewContext = 'gate' | 'pr-preview' | 'run-detail' | 'artifact';
4
+ export type EvidenceReviewTiming = 'measured' | 'untimed' | 'outside-recording';
5
+ export type EvidenceReviewMediaType = 'image' | 'video' | 'document';
6
+ /** Standalone players supply the same retained trace and checked video identity. */
7
+ export interface EvidenceReviewRecordingInput extends RecipeRecordingTimelineBinding {
8
+ timeline: RecipeRecordingTimelineDocument;
9
+ gapBefore?: boolean;
10
+ }
11
+ export interface EvidenceReviewInput {
12
+ context?: EvidenceReviewContext;
13
+ readErrors?: readonly string[];
14
+ /** Transport namespace; contract references stay relative to their recipe package. */
15
+ artifactPrefix?: string;
16
+ /** Display path relative to the run's artifacts; never used to resolve media. */
17
+ packagePath?: string;
18
+ package?: RecordedEvidencePackageInput;
19
+ criteria?: readonly AcceptanceCriterionRef[];
20
+ ledger?: AcceptanceStatusLedger | null;
21
+ evidenceLinks?: readonly AcceptanceEvidenceLink[];
22
+ recordings?: readonly EvidenceReviewRecordingInput[];
23
+ report?: Pick<RunOutput, 'reportPath' | 'manifestDigest' | 'artifactManifest'>;
24
+ reportSnapshot?: OutputReviewPayload;
25
+ }
26
+ export interface EvidenceReviewArtifact {
27
+ path: string;
28
+ /** Resolved transport path. Legacy task-ledger refs already live in that namespace. */
29
+ artifactPath: string;
30
+ name: string;
31
+ mediaType: EvidenceReviewMediaType;
32
+ }
33
+ export interface EvidenceReviewClaim extends AcceptanceCriterionView {
34
+ kind: RecipeClaimKind;
35
+ parentId?: string;
36
+ caption: string;
37
+ timing?: EvidenceReviewTiming;
38
+ evidence: readonly EvidenceReviewArtifact[];
39
+ moments: readonly EvidenceMomentRef[];
40
+ occurrences: readonly EvidenceReviewOccurrence[];
41
+ }
42
+ export interface EvidenceReviewOccurrence {
43
+ traceIndex: number;
44
+ nodeId: string;
45
+ action: string;
46
+ intent: string;
47
+ ok: boolean;
48
+ proves: readonly string[];
49
+ /** Authored checked expectation from the retained input closure, not a fabricated result. */
50
+ expectation?: Readonly<Record<string, unknown>>;
51
+ artifacts: readonly EvidenceReviewArtifact[];
52
+ }
53
+ /** A virtual view of original media. Creating it performs no media I/O. */
54
+ export interface EvidenceReviewClip {
55
+ videoPath: string;
56
+ videoDigest: string;
57
+ traceIndex: number;
58
+ startMs: number;
59
+ endMs: number;
60
+ caption: string;
61
+ moment?: EvidenceMomentRef;
62
+ }
63
+ export interface EvidenceReviewSelection {
64
+ claimId?: string;
65
+ traceIndex?: number;
66
+ caption: string;
67
+ timing: EvidenceReviewTiming;
68
+ clips: readonly EvidenceReviewClip[];
69
+ stills: readonly EvidenceReviewArtifact[];
70
+ artifacts: readonly EvidenceReviewArtifact[];
71
+ message?: string;
72
+ }
73
+ /** Renderers apply these effects to their existing player; range decisions stay here. */
74
+ export interface EvidenceReviewPlaybackEffect {
75
+ clip: EvidenceReviewClip | null;
76
+ seekMs: number | null;
77
+ pause: boolean;
78
+ sourceChanged: boolean;
79
+ }
80
+ export interface EvidenceReviewModel {
81
+ readonly context: EvidenceReviewContext;
82
+ readonly summary: AcceptanceStatusSummary;
83
+ readonly claims: readonly EvidenceReviewClaim[];
84
+ readonly occurrences: readonly EvidenceReviewOccurrence[];
85
+ readonly recordings: readonly RecipeRecordingTimelineDocument[];
86
+ readonly errors: readonly string[];
87
+ readonly warnings: readonly string[];
88
+ readonly displayWarnings: readonly string[];
89
+ readonly selection: EvidenceReviewSelection | null;
90
+ readonly playback: EvidenceReviewPlaybackEffect;
91
+ readonly report: EvidenceReviewInput['report'];
92
+ readonly reportError?: string;
93
+ readonly packageStatus: EvidenceReviewPackageStatus | null;
94
+ selectClaim(id: string, artifactPath?: string): EvidenceReviewSelection | null;
95
+ selectOccurrence(traceIndex: number): EvidenceReviewSelection | null;
96
+ selectReport(): EvidenceReviewSelection | null;
97
+ clearSelection(): void;
98
+ artifactPath(path: string): string;
99
+ cueClip(index: number): EvidenceReviewPlaybackEffect;
100
+ seekClip(timeMs: number): EvidenceReviewPlaybackEffect;
101
+ playbackAt(videoPath: string, timeMs: number, mediaDurationMs?: number): EvidenceReviewPlaybackEffect;
102
+ markerSeekMs(videoPath: string, traceIndex: number, phase: 'start' | 'end', mediaDurationMs?: number): number | null;
103
+ adjacentFrameMs(videoPath: string, timeMs: number, direction: -1 | 1): number | null;
104
+ displayedFrameRangeMs(videoPath: string, timeMs: number, mediaDurationMs?: number): readonly [number, number] | null;
105
+ }
106
+ /** Experimental ADR-062 projection shared by web and native review contexts. */
107
+ export declare function createEvidenceReviewModel(input: EvidenceReviewInput): EvidenceReviewModel;
108
+ //# sourceMappingURL=evidence-review-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-review-model.d.ts","sourceRoot":"","sources":["../src/evidence-review-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,403 @@
1
+ import { acceptanceCriteriaView, EVIDENCE_PADDING_MS, isRecord, recipeTraceEntries, summarizeAcceptanceStatus, validateRecipeRecordingTimelineBinding, } from '@farmslot/protocol';
2
+ import { indexRecordingTimelines, occurrenceRecordingCoverage, planRecipeEvidence, proofDocument, validateRecordedEvidencePackage, } from '@farmslot/recipe-runner/evidence';
3
+ import { evidenceReviewPackageStatus, } from './evidence-review-status.js';
4
+ /** Experimental ADR-062 projection shared by web and native review contexts. */
5
+ export function createEvidenceReviewModel(input) {
6
+ // Gate refreshes cannot mutate the already-validated selection. Inputs are protocol JSON.
7
+ input = JSON.parse(JSON.stringify(input));
8
+ const pkg = input.package;
9
+ const findings = pkg ? validateRecordedEvidencePackage(pkg).findings : [];
10
+ // Invalid task-ledger input keeps its finding, without becoming recipe claims.
11
+ const packageClaims = pkg?.claims?.schemaVersion === 2 ? pkg.claims : undefined;
12
+ const errors = [
13
+ ...(input.readErrors ?? []),
14
+ ...findings.filter((finding) => finding.severity === 'error').map((finding) => finding.message),
15
+ ];
16
+ const warnings = findings
17
+ .filter((finding) => finding.severity === 'warning')
18
+ .map((finding) => finding.message);
19
+ const reportError = input.reportSnapshot &&
20
+ (input.report?.manifestDigest !== input.reportSnapshot.manifestDigest ||
21
+ input.report?.reportPath !== input.reportSnapshot.reportPath)
22
+ ? 'The output report no longer matches the reviewed snapshot.'
23
+ : undefined;
24
+ if (reportError)
25
+ errors.push(reportError);
26
+ if (packageClaims &&
27
+ ['incomplete', 'failed', 'explicit-off'].includes(packageClaims.recording.status))
28
+ warnings.push(`Recording ${packageClaims.recording.status}: ${packageClaims.recording.reason ?? 'see retained capture status'}`);
29
+ const ledger = packageClaims ?? input.ledger ?? null;
30
+ if (input.ledger?.schemaVersion === 2 && !pkg)
31
+ errors.push('Recorded claim evidence requires its retained execution package.');
32
+ if (packageClaims &&
33
+ input.ledger?.schemaVersion === 2 &&
34
+ packageClaims.recipeRunId !== input.ledger.recipeRunId)
35
+ errors.push('The task ledger belongs to another recipe execution.');
36
+ const trace = recipeTraceEntries(pkg?.trace ?? input.recordings?.[0]?.trace) ?? [];
37
+ const recordings = pkg
38
+ ? Object.values(pkg.timelines).map((timeline) => ({
39
+ timeline,
40
+ videoPath: timeline.videoPath,
41
+ videoDigest: pkg.artifactDigests[timeline.videoPath] ?? '',
42
+ trace: pkg.trace,
43
+ }))
44
+ : [...(input.recordings ?? [])];
45
+ for (const recording of recordings) {
46
+ if (pkg)
47
+ continue; // The canonical package validator already checks every binding.
48
+ errors.push(...validateRecipeRecordingTimelineBinding(recording.timeline, { ...recording, trace })
49
+ .findings.filter((finding) => finding.severity === 'error')
50
+ .map((finding) => finding.message));
51
+ }
52
+ const timelines = indexRecordingTimelines(recordings.map(({ timeline }) => timeline));
53
+ const segments = packageClaims?.recording.segments ??
54
+ recordings.map((recording, index) => ({
55
+ videoPath: recording.timeline.videoPath,
56
+ videoDigest: recording.timeline.videoDigest,
57
+ gapBefore: recording.gapBefore ?? index > 0,
58
+ }));
59
+ const recipeRunId = pkg && isRecord(pkg.summary) && typeof pkg.summary.recipeRunId === 'string'
60
+ ? pkg.summary.recipeRunId
61
+ : undefined;
62
+ const manifest = pkg && isRecord(pkg.manifest) && Array.isArray(pkg.manifest.artifacts)
63
+ ? pkg.manifest.artifacts.filter(isRecord)
64
+ : [];
65
+ const links = new Map((input.evidenceLinks ?? []).map((link) => [link.id, link.evidence]));
66
+ const claims = acceptanceCriteriaView(packageClaims?.criteria ?? input.criteria ?? ledger?.criteria ?? [], ledger).map((claim) => ({
67
+ ...claim,
68
+ kind: claim.status?.kind ?? 'acceptance',
69
+ ...(claim.status?.parentId ? { parentId: claim.status.parentId } : {}),
70
+ caption: claimCaption(claim),
71
+ timing: packageClaims?.criteria.find((status) => status.id === claim.id)?.timing,
72
+ evidence: artifacts(claim.status?.evidence ?? links.get(claim.id) ?? [], packageClaims ? input.artifactPrefix : undefined),
73
+ moments: claim.status?.moments ?? [],
74
+ occurrences: [],
75
+ }));
76
+ const proofNodes = pkg?.recipe && !errors.length
77
+ ? planRecipeEvidence(proofDocument(pkg.recipe), new Map(isRecord(pkg.recipeResolution) && Array.isArray(pkg.recipeResolution.dependencies)
78
+ ? pkg.recipeResolution.dependencies
79
+ .filter(isRecord)
80
+ .map((dependency) => [
81
+ String(dependency.ref),
82
+ proofDocument(pkg.resolvedRecipes?.[String(dependency.digest)]),
83
+ ])
84
+ : []), pkg.invocation && isRecord(pkg.invocation)
85
+ ? pkg.invocation.claims
86
+ : undefined).nodes
87
+ : new Map();
88
+ const nodeCounts = new Map();
89
+ for (const entry of trace) {
90
+ if (isRecord(entry) && typeof entry.nodeId === 'string')
91
+ nodeCounts.set(entry.nodeId, (nodeCounts.get(entry.nodeId) ?? 0) + 1);
92
+ }
93
+ const occurrences = trace.flatMap((entry, traceIndex) => {
94
+ if (!isRecord(entry) || typeof entry.nodeId !== 'string')
95
+ return [];
96
+ const nodeId = entry.nodeId;
97
+ const references = new Set(Array.isArray(entry.artifacts)
98
+ ? entry.artifacts.filter(isRecord).map((artifact) => artifact.path)
99
+ : []);
100
+ const files = manifest.filter((artifact) => {
101
+ const source = isRecord(artifact.metadata) ? artifact.metadata.recordedEvidence : undefined;
102
+ if (isRecord(source))
103
+ return source.traceIndex === traceIndex;
104
+ return (references.has(artifact.path) ||
105
+ (nodeCounts.get(nodeId) === 1 && artifact.nodeId === nodeId));
106
+ });
107
+ const node = proofNodes.get(nodeId);
108
+ const expectation = node
109
+ ? Object.fromEntries(['assert', 'contains', 'match', 'selector', 'test_id', 'testID', 'text', 'expected']
110
+ .filter((key) => node[key] !== undefined)
111
+ .map((key) => [key, node[key]]))
112
+ : {};
113
+ return [
114
+ {
115
+ traceIndex,
116
+ nodeId: entry.nodeId,
117
+ action: String(entry.action ?? ''),
118
+ intent: typeof entry.intent === 'string' ? entry.intent : entry.nodeId,
119
+ ok: entry.ok === true,
120
+ proves: Array.isArray(entry.proves)
121
+ ? entry.proves.filter((id) => typeof id === 'string')
122
+ : [],
123
+ ...(Object.keys(expectation).length ? { expectation } : {}),
124
+ artifacts: artifacts(files.map((artifact) => String(artifact.path)), input.artifactPrefix),
125
+ },
126
+ ];
127
+ });
128
+ const byClaim = new Map(claims.map((claim) => [claim.id, claim]));
129
+ const byOccurrence = new Map(occurrences.map((occurrence) => [occurrence.traceIndex, occurrence]));
130
+ for (const claim of claims) {
131
+ claim.occurrences = (claim.status?.assertionIndices ?? []).flatMap((index) => {
132
+ const occurrence = byOccurrence.get(index);
133
+ return occurrence ? [occurrence] : [];
134
+ });
135
+ }
136
+ let selection = null;
137
+ let clipIndex = 0;
138
+ const effect = (seekMs = null, pause = false, sourceChanged = false) => ({
139
+ clip: selection?.clips[clipIndex] ?? null,
140
+ seekMs,
141
+ pause,
142
+ sourceChanged,
143
+ });
144
+ const advanceClip = (availableEndMs) => {
145
+ const clip = selection?.clips[clipIndex];
146
+ const next = selection?.clips[clipIndex + 1];
147
+ if (!next)
148
+ return effect(availableEndMs ?? clip?.endMs ?? null, true);
149
+ clipIndex++;
150
+ return effect(next.startMs, false, true);
151
+ };
152
+ const clipsFor = (traceIndex) => {
153
+ if (errors.length)
154
+ return [];
155
+ const coverage = occurrenceRecordingCoverage(traceIndex, segments, timelines);
156
+ if (coverage.timing !== 'measured')
157
+ return [];
158
+ return coverage.segments.map((segment) => {
159
+ const timeline = timelines.get(segment.videoPath);
160
+ const marker = timeline.markers.find((marker) => marker.traceIndex === traceIndex);
161
+ return {
162
+ videoPath: segment.videoPath,
163
+ videoDigest: segment.videoDigest,
164
+ traceIndex,
165
+ startMs: Math.max(0, marker.startRangeMs[0] - EVIDENCE_PADDING_MS),
166
+ endMs: Math.min(timeline.durationMs, marker.endRangeMs[1] + EVIDENCE_PADDING_MS),
167
+ caption: byOccurrence.get(traceIndex)?.intent ?? marker.nodeId,
168
+ ...(recipeRunId
169
+ ? { moment: { recipeRunId, videoDigest: segment.videoDigest, traceIndex } }
170
+ : {}),
171
+ };
172
+ });
173
+ };
174
+ // Long recordings may list every original in the retained ledger. Present
175
+ // only this claim's measured originals; the full file inventory stays browsable.
176
+ for (const claim of claims) {
177
+ const measured = new Set(claim.moments.flatMap((moment) => clipsFor(moment.traceIndex)
178
+ .filter((clip) => clip.videoDigest === moment.videoDigest)
179
+ .map((clip) => clip.videoPath)));
180
+ if (measured.size)
181
+ claim.evidence = artifacts([
182
+ ...claim.evidence
183
+ .filter((file) => file.mediaType !== 'video' || measured.has(file.path))
184
+ .map((file) => file.path),
185
+ ...measured,
186
+ ], input.artifactPrefix);
187
+ }
188
+ const select = (caption, files, clips, traceIndex, claimId, retainedTiming) => {
189
+ const timing = errors.length
190
+ ? 'untimed'
191
+ : (retainedTiming ??
192
+ (clips.length
193
+ ? 'measured'
194
+ : traceIndex !== undefined
195
+ ? occurrenceRecordingCoverage(traceIndex, segments, timelines).timing
196
+ : 'untimed'));
197
+ const selectedFiles = [
198
+ ...new Map([
199
+ ...files,
200
+ ...artifacts(clips.map((clip) => clip.videoPath), input.artifactPrefix),
201
+ ].map((file) => [file.artifactPath, file])).values(),
202
+ ];
203
+ selection = {
204
+ caption,
205
+ timing,
206
+ clips,
207
+ artifacts: selectedFiles,
208
+ stills: selectedFiles.filter((artifact) => artifact.mediaType === 'image'),
209
+ ...(traceIndex !== undefined ? { traceIndex } : {}),
210
+ ...(claimId ? { claimId } : {}),
211
+ ...(errors.length
212
+ ? { message: errors.join('; ') }
213
+ : !clips.length
214
+ ? {
215
+ message: timing === 'outside-recording'
216
+ ? 'Outside recording.'
217
+ : 'Untimed evidence; no marker seek.',
218
+ }
219
+ : {}),
220
+ };
221
+ clipIndex = 0;
222
+ return selection;
223
+ };
224
+ const packageStatus = evidenceReviewPackageStatus(pkg, input.packagePath ?? input.artifactPrefix, errors);
225
+ return {
226
+ context: input.context ?? 'artifact',
227
+ summary: summarizeAcceptanceStatus({
228
+ schemaVersion: 1,
229
+ criteria: claims.flatMap((claim) => (claim.status ? [claim.status] : [])),
230
+ }, claims),
231
+ claims,
232
+ occurrences,
233
+ recordings: recordings.map((recording) => recording.timeline),
234
+ errors,
235
+ warnings,
236
+ displayWarnings: [...new Set(warnings)].filter((warning) => packageStatus?.status !== 'Legacy' || !warning.startsWith('Legacy package')),
237
+ report: input.report,
238
+ reportError,
239
+ packageStatus,
240
+ get selection() {
241
+ return selection;
242
+ },
243
+ get playback() {
244
+ return effect();
245
+ },
246
+ artifactPath(path) {
247
+ return `${input.artifactPrefix ?? ''}${path}`;
248
+ },
249
+ selectClaim(id, artifactPath) {
250
+ const claim = byClaim.get(id);
251
+ if (!claim ||
252
+ (artifactPath &&
253
+ !claim.evidence.some((file) => file.path === artifactPath || file.artifactPath === artifactPath)))
254
+ return null;
255
+ const indices = [
256
+ ...new Set(claim.moments.length
257
+ ? claim.moments.map((moment) => moment.traceIndex)
258
+ : (claim.status?.assertionIndices ?? [])),
259
+ ];
260
+ const clips = indices
261
+ .flatMap(clipsFor)
262
+ .filter((clip) => claim.moments.some((moment) => moment.traceIndex === clip.traceIndex && moment.videoDigest === clip.videoDigest));
263
+ const selected = select(claim.caption, claim.evidence, clips, indices[0], id, claim.timing);
264
+ if (artifactPath) {
265
+ const file = claim.evidence.find((file) => file.path === artifactPath || file.artifactPath === artifactPath);
266
+ if (file?.mediaType === 'video') {
267
+ const index = selected.clips.findIndex((clip) => clip.videoPath === file.path);
268
+ if (index >= 0)
269
+ clipIndex = index;
270
+ else {
271
+ selected.clips = [];
272
+ selected.timing = 'untimed';
273
+ selected.message = 'This original has no measured clip for the selected claim.';
274
+ }
275
+ }
276
+ }
277
+ return selected;
278
+ },
279
+ selectOccurrence(traceIndex) {
280
+ const occurrence = byOccurrence.get(traceIndex);
281
+ return occurrence
282
+ ? select(occurrence.intent, occurrence.artifacts, clipsFor(traceIndex), traceIndex)
283
+ : null;
284
+ },
285
+ clearSelection() {
286
+ selection = null;
287
+ clipIndex = 0;
288
+ },
289
+ selectReport() {
290
+ const path = input.report?.reportPath;
291
+ if (reportError ||
292
+ !path ||
293
+ !input.report?.artifactManifest.some((artifact) => artifact.path === path))
294
+ return null;
295
+ return select(`Report snapshot ${input.report.manifestDigest}`, artifacts([path]), []);
296
+ },
297
+ cueClip(index) {
298
+ if (!selection?.clips[index])
299
+ return effect(null, true);
300
+ clipIndex = index;
301
+ return effect(selection.clips[index].startMs, false, true);
302
+ },
303
+ seekClip(timeMs) {
304
+ const clip = selection?.clips[clipIndex];
305
+ return clip && Number.isFinite(timeMs)
306
+ ? effect(clamp(timeMs, clip.startMs, clip.endMs))
307
+ : effect(null, true);
308
+ },
309
+ playbackAt(videoPath, timeMs, mediaDurationMs) {
310
+ const clip = selection?.clips[clipIndex];
311
+ if (!clip || clip.videoPath !== videoPath || !Number.isFinite(timeMs))
312
+ return effect();
313
+ if (timeMs < clip.startMs)
314
+ return effect(clip.startMs);
315
+ const availableEnd = Number.isFinite(mediaDurationMs)
316
+ ? Math.min(clip.endMs, mediaDurationMs)
317
+ : clip.endMs;
318
+ if (timeMs < availableEnd)
319
+ return effect();
320
+ return advanceClip(availableEnd);
321
+ },
322
+ markerSeekMs(videoPath, traceIndex, phase, mediaDurationMs) {
323
+ if (errors.length ||
324
+ occurrenceRecordingCoverage(traceIndex, segments, timelines).timing !== 'measured')
325
+ return null;
326
+ const timeline = timelines.get(videoPath);
327
+ const marker = timeline?.markers.find((marker) => marker.traceIndex === traceIndex);
328
+ if (!timeline || !marker)
329
+ return null;
330
+ const bounds = phase === 'start' ? marker.startRangeMs : marker.endRangeMs;
331
+ const first = timeline.framesMs[0];
332
+ const last = timeline.framesMs.at(-1);
333
+ const duration = Math.min(timeline.durationMs, mediaDurationMs ?? timeline.durationMs);
334
+ if (first === undefined ||
335
+ last === undefined ||
336
+ bounds[1] < first ||
337
+ !Number.isFinite(duration) ||
338
+ bounds[0] >= duration)
339
+ return null;
340
+ return clamp((bounds[0] + bounds[1]) / 2, first, Math.min(last, duration));
341
+ },
342
+ adjacentFrameMs(videoPath, timeMs, direction) {
343
+ const timeline = errors.length ? undefined : timelines.get(videoPath);
344
+ if (!timeline?.framesMs.length || !Number.isFinite(timeMs))
345
+ return null;
346
+ const current = Math.max(0, upperFrame(timeline.framesMs, timeMs + 0.001) - 1);
347
+ return timeline.framesMs[clamp(current + direction, 0, timeline.framesMs.length - 1)];
348
+ },
349
+ displayedFrameRangeMs(videoPath, timeMs, mediaDurationMs) {
350
+ const timeline = errors.length ? undefined : timelines.get(videoPath);
351
+ const duration = Math.min(timeline?.durationMs ?? 0, mediaDurationMs ?? timeline?.durationMs ?? 0);
352
+ if (!timeline?.framesMs.length ||
353
+ timeMs < timeline.framesMs[0] ||
354
+ !Number.isFinite(timeMs) ||
355
+ timeMs >= duration)
356
+ return null;
357
+ const next = upperFrame(timeline.framesMs, timeMs);
358
+ return [
359
+ timeline.framesMs[next - 1],
360
+ Math.min(timeline.framesMs[next] ?? duration, duration),
361
+ ];
362
+ },
363
+ };
364
+ }
365
+ function upperFrame(frames, timeMs) {
366
+ let low = 0;
367
+ let high = frames.length;
368
+ while (low < high) {
369
+ const middle = Math.floor((low + high) / 2);
370
+ if (frames[middle] <= timeMs)
371
+ low = middle + 1;
372
+ else
373
+ high = middle;
374
+ }
375
+ return low;
376
+ }
377
+ function clamp(value, minimum, maximum) {
378
+ return Math.max(minimum, Math.min(maximum, value));
379
+ }
380
+ function artifacts(paths, prefix = '') {
381
+ return [...new Set(paths)].map((path) => ({
382
+ path,
383
+ artifactPath: `${prefix}${path}`,
384
+ name: path.split('/').at(-1) || path,
385
+ mediaType: /\.(?:png|jpe?g|webp|gif|svg)$/iu.test(path)
386
+ ? 'image'
387
+ : /\.(?:mp4|mov|webm|m4v)$/iu.test(path)
388
+ ? 'video'
389
+ : 'document',
390
+ }));
391
+ }
392
+ function claimCaption(claim) {
393
+ const status = claim.status;
394
+ return status
395
+ ? [
396
+ claim.id,
397
+ status.verdict,
398
+ status.proofMode ?? 'no proof mode',
399
+ status.recipeNodes.length ? `node ${status.recipeNodes.join(', ')}` : 'no recipe node',
400
+ ].join(' · ')
401
+ : `${claim.id} · not assessed`;
402
+ }
403
+ //# sourceMappingURL=evidence-review-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-review-model.js","sourceRoot":"","sources":["../src/evidence-review-model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type RecipeRecordingTimelineBinding } from '@farmslot/protocol';
2
+ import { type EvidenceReviewContext, type EvidenceReviewModel } from './evidence-review-model.js';
3
+ export interface RecordingEvidenceReadRequest extends Omit<RecipeRecordingTimelineBinding, 'trace'> {
4
+ context?: EvidenceReviewContext;
5
+ timelinePath: string;
6
+ readJson(path: string): Promise<unknown>;
7
+ }
8
+ /** Shared metadata loading for existing standalone video players; no media is downloaded. */
9
+ export declare function loadRecordingEvidenceReview(input: RecordingEvidenceReadRequest): Promise<EvidenceReviewModel>;
10
+ export interface EvidenceReviewReport {
11
+ path: string;
12
+ body: string;
13
+ caption: string;
14
+ }
15
+ /** Read only the selected report and refuse bytes outside the retained output snapshot. */
16
+ export declare function readEvidenceReviewReport(model: EvidenceReviewModel, readBytes: (path: string) => Promise<Uint8Array>): Promise<EvidenceReviewReport>;
17
+ //# sourceMappingURL=evidence-review-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-review-source.d.ts","sourceRoot":"","sources":["../src/evidence-review-source.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,8BAA8B,EAGpC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CACxD,8BAA8B,EAC9B,OAAO,CACR;IACC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1C;AAED,6FAA6F;AAC7F,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,mBAAmB,CAAC,CAc9B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,2FAA2F;AAC3F,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,GAC/C,OAAO,CAAC,oBAAoB,CAAC,CAU/B"}
@@ -0,0 +1,37 @@
1
+ import { sha256 } from '@noble/hashes/sha256';
2
+ import { bytesToHex } from '@noble/hashes/utils';
3
+ import { validateRecipeRecordingTimelineDocument, } from '@farmslot/protocol';
4
+ import { createEvidenceReviewModel, } from './evidence-review-model.js';
5
+ /** Shared metadata loading for existing standalone video players; no media is downloaded. */
6
+ export async function loadRecordingEvidenceReview(input) {
7
+ const value = await input.readJson(input.timelinePath);
8
+ const validation = validateRecipeRecordingTimelineDocument(value);
9
+ if (validation.status !== 'valid')
10
+ throw new Error('Recording timeline is invalid.');
11
+ const timeline = value;
12
+ const root = input.videoPath.slice(0, input.videoPath.length - timeline.videoPath.length);
13
+ const trace = await input.readJson(`${root}trace.json`);
14
+ const model = createEvidenceReviewModel({
15
+ context: input.context,
16
+ artifactPrefix: root,
17
+ recordings: [{ videoPath: input.videoPath, videoDigest: input.videoDigest, timeline, trace }],
18
+ });
19
+ if (model.errors.length)
20
+ throw new Error(model.errors.join('; '));
21
+ return model;
22
+ }
23
+ /** Read only the selected report and refuse bytes outside the retained output snapshot. */
24
+ export async function readEvidenceReviewReport(model, readBytes) {
25
+ const selected = model.selectReport();
26
+ const file = selected?.artifacts[0];
27
+ if (!file)
28
+ throw new Error(model.errors.join('; ') || 'The retained report is unavailable.');
29
+ const expected = model.report?.artifactManifest.find((entry) => entry.path === file.path)?.sha256;
30
+ if (!expected)
31
+ throw new Error('The retained report has no byte digest.');
32
+ const bytes = await readBytes(file.path);
33
+ if (bytesToHex(sha256(bytes)) !== expected.replace(/^sha256:/u, ''))
34
+ throw new Error('Report bytes no longer match the reviewed snapshot.');
35
+ return { path: file.path, body: new TextDecoder().decode(bytes), caption: selected.caption };
36
+ }
37
+ //# sourceMappingURL=evidence-review-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-review-source.js","sourceRoot":"","sources":["../src/evidence-review-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAGL,uCAAuC,GACxC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,yBAAyB,GAG1B,MAAM,4BAA4B,CAAC;AAWpC,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,KAAmC;IAEnC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,uCAAuC,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,UAAU,CAAC,MAAM,KAAK,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACrF,MAAM,QAAQ,GAAG,KAAwC,CAAC;IAC1D,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,yBAAyB,CAAC;QACtC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,IAAI;QACpB,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;KAC9F,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClE,OAAO,KAAK,CAAC;AACf,CAAC;AAQD,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,KAA0B,EAC1B,SAAgD;IAEhD,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,qCAAqC,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAClG,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAC/F,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type RecordedEvidencePackageInput } from '@farmslot/protocol';
2
+ export interface EvidenceReviewIssue {
3
+ message: string;
4
+ /** Number of reader/validator messages represented by this issue. */
5
+ count: number;
6
+ }
7
+ export interface EvidenceReviewPackageStatus {
8
+ status: 'Valid' | 'Legacy' | 'Invalid';
9
+ /** Red requires an identified current-contract package, never an unknown read. */
10
+ tone: 'success' | 'info' | 'error';
11
+ /** Relative to the run's artifacts, independent of media transport paths. */
12
+ path: string;
13
+ summary: string;
14
+ action?: string;
15
+ issues: readonly EvidenceReviewIssue[];
16
+ }
17
+ /** Presentation only. Raw reader/validator failures continue to refuse measured proof. */
18
+ export declare function evidenceReviewPackageStatus(pkg: RecordedEvidencePackageInput | undefined, packagePath: string | undefined, messages: readonly string[]): EvidenceReviewPackageStatus | null;
19
+ //# sourceMappingURL=evidence-review-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-review-status.d.ts","sourceRoot":"","sources":["../src/evidence-review-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAEjF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACvC,kFAAkF;IAClF,IAAI,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;IACnC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACxC;AAID,0FAA0F;AAC1F,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,4BAA4B,GAAG,SAAS,EAC7C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAC1B,2BAA2B,GAAG,IAAI,CA8CpC"}
@@ -0,0 +1,49 @@
1
+ import { isRecord } from '@farmslot/protocol';
2
+ const requiredFiles = ['summary.json', 'trace.json', 'artifact-manifest.json'];
3
+ /** Presentation only. Raw reader/validator failures continue to refuse measured proof. */
4
+ export function evidenceReviewPackageStatus(pkg, packagePath, messages) {
5
+ if (!pkg && !messages.length)
6
+ return null;
7
+ const missingCore = pkg ? requiredFiles.filter((file) => !pkg.artifactPaths?.includes(file)) : [];
8
+ const missing = [
9
+ ...missingCore,
10
+ ...(pkg?.recipe && !pkg.artifactPaths?.includes('recipe-resolution.json')
11
+ ? ['recipe-resolution.json']
12
+ : []),
13
+ ];
14
+ const grouped = new Map();
15
+ for (const message of messages) {
16
+ const file = missing.find((file) => message === `Missing required Recipe v1 artifact ${file}.` ||
17
+ message === `Recipe artifact package must include ${file}.` ||
18
+ message.startsWith(`${file} must be `));
19
+ const label = file ? `Missing ${file}` : message;
20
+ const issue = grouped.get(label);
21
+ if (issue)
22
+ issue.count++;
23
+ else
24
+ grouped.set(label, { message: label, count: 1 });
25
+ }
26
+ const current = Boolean((isRecord(pkg?.summary) && pkg.summary.version === 1) ||
27
+ (isRecord(pkg?.manifest) && pkg.manifest.version === 1) ||
28
+ (isRecord(pkg?.invocation) && pkg.invocation.version === 1) ||
29
+ pkg?.claims?.schemaVersion === 2 ||
30
+ (isRecord(pkg?.summary) && pkg.summary.recipeRunId) ||
31
+ pkg?.artifactPaths?.includes('recipe-invocation.json'));
32
+ const legacy = Boolean(pkg && !current);
33
+ const status = legacy ? 'Legacy' : messages.length ? 'Invalid' : 'Valid';
34
+ return {
35
+ status,
36
+ tone: status === 'Invalid' && current ? 'error' : status === 'Valid' ? 'success' : 'info',
37
+ path: (packagePath ?? '.').replace(/^artifacts\//u, '').replace(/\/$/u, '') || '.',
38
+ summary: legacy
39
+ ? `Recorded before Recipe v1: not machine-checkable${missing.length ? ` (missing ${missing.join(', ')})` : ''}; media untimed`
40
+ : status === 'Invalid'
41
+ ? `${grouped.size} evidence issue${grouped.size === 1 ? '' : 's'}; measured proof unavailable`
42
+ : 'Recipe evidence is machine-checkable',
43
+ ...(status === 'Invalid' && current
44
+ ? { action: 'Refresh the gate package or re-run the recipe.' }
45
+ : {}),
46
+ issues: [...grouped.values()],
47
+ };
48
+ }
49
+ //# sourceMappingURL=evidence-review-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence-review-status.js","sourceRoot":"","sources":["../src/evidence-review-status.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,9 @@
1
- /** The portable package validator shared by CLI, gateway and review clients. */
1
+ /** The shared package-validation surface used by CLI, gateway and both review clients. */
2
+ export type { EvidenceReviewArtifact, EvidenceReviewClaim, EvidenceReviewClip, EvidenceReviewContext, EvidenceReviewInput, EvidenceReviewMediaType, EvidenceReviewModel, EvidenceReviewOccurrence, EvidenceReviewPlaybackEffect, EvidenceReviewRecordingInput, EvidenceReviewSelection, EvidenceReviewTiming, } from './evidence-review-model.js';
3
+ export { createEvidenceReviewModel } from './evidence-review-model.js';
4
+ export type { EvidenceReviewReport, RecordingEvidenceReadRequest, } from './evidence-review-source.js';
5
+ export { loadRecordingEvidenceReview, readEvidenceReviewReport } from './evidence-review-source.js';
6
+ export type { EvidenceReviewIssue, EvidenceReviewPackageStatus } from './evidence-review-status.js';
2
7
  export type { RecipeValidationResult, RecordedEvidencePackageInput } from '@farmslot/protocol';
3
8
  export { validateRecordedEvidencePackage } from '@farmslot/recipe-runner/evidence';
4
9
  //# sourceMappingURL=evidence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,YAAY,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,EAC5B,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,YAAY,EACV,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACpG,YAAY,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AACpG,YAAY,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC"}
package/dist/evidence.js CHANGED
@@ -1,2 +1,4 @@
1
+ export { createEvidenceReviewModel } from './evidence-review-model.js';
2
+ export { loadRecordingEvidenceReview, readEvidenceReviewReport } from './evidence-review-source.js';
1
3
  export { validateRecordedEvidencePackage } from '@farmslot/recipe-runner/evidence';
2
4
  //# sourceMappingURL=evidence.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAKvE,OAAO,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAGpG,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -7,5 +7,5 @@ export { ADAPTER_SDK_VERSION, type AdapterActions, type AdapterBrowser, type Ada
7
7
  export type { ActiveVideoRecording, RecordingTarget, RecordingTargetContext, VideoRecorder, VideoRecorderStartRequest, VideoRecordingResult, } from '@farmslot/recipe-runner';
8
8
  export type { RecordingAdmission, RecordingAdmissionContext, RecordingAdmissionLease, } from '@farmslot/recipe-runner';
9
9
  /** Node-only retained package reader; portable validation lives at ./evidence. */
10
- export { readRecordedEvidencePackage, type RecordedEvidencePackageReadCheck, type RecordedEvidencePackageReadResult, } from '@farmslot/recipe-runner';
10
+ export { readRecordedEvidencePackage, type RecordedEvidencePackageReadCheck, type RecordedEvidencePackageReadIO, type RecordedEvidencePackageReadResult, } from '@farmslot/recipe-runner';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,8BAA8B,EAC9B,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,sBAAsB,EAC3B,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yCAAyC,EACzC,KAAK,2BAA2B,EAChC,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,eAAe,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EACL,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAEjC,kFAAkF;AAClF,OAAO,EACL,2BAA2B,EAC3B,KAAK,gCAAgC,EACrC,KAAK,iCAAiC,GACvC,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,8BAA8B,EAC9B,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,sBAAsB,EAC3B,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yCAAyC,EACzC,KAAK,2BAA2B,EAChC,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,eAAe,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EACL,mBAAmB,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAC1B,SAAS,EACT,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,aAAa,EACb,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAEjC,kFAAkF;AAClF,OAAO,EACL,2BAA2B,EAC3B,KAAK,gCAAgC,EACrC,KAAK,6BAA6B,EAClC,KAAK,iCAAiC,GACvC,MAAM,yBAAyB,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAA0B,MAAM,aAAa,CAAC;AAC5E,OAAO,EAOL,8BAA8B,GAE/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,yBAAyB,GAQ1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yCAAyC,EAEzC,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAwB,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EACL,mBAAmB,EA8CnB,SAAS,GAOV,MAAM,YAAY,CAAC;AAepB,kFAAkF;AAClF,OAAO,EACL,2BAA2B,GAG5B,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAA0B,MAAM,aAAa,CAAC;AAC5E,OAAO,EAOL,8BAA8B,GAE/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,yBAAyB,GAQ1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yCAAyC,EAEzC,uBAAuB,GACxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAwB,qBAAqB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EACL,mBAAmB,EA8CnB,SAAS,GAOV,MAAM,YAAY,CAAC;AAepB,kFAAkF;AAClF,OAAO,EACL,2BAA2B,GAI5B,MAAM,yBAAyB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farmslot/adapter-sdk",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,8 +29,9 @@
29
29
  "prepublishOnly": "node ../../scripts/quality/check-farmslot-package-readiness.mjs --publish --packages @farmslot/adapter-sdk"
30
30
  },
31
31
  "dependencies": {
32
- "@farmslot/protocol": "0.40.0",
33
- "@farmslot/recipe-runner": "0.31.0"
32
+ "@farmslot/protocol": "0.41.0",
33
+ "@farmslot/recipe-runner": "0.32.0",
34
+ "@noble/hashes": "^1.8.0"
34
35
  },
35
36
  "devDependencies": {
36
37
  "@types/node": "^22.0.0",