yam-flow 0.1.2 → 0.1.3

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.
@@ -15,6 +15,8 @@ export type TruthStatus = (typeof TRUTH_STATUSES)[number];
15
15
  export type SafetyLevel = 'danger' | 'warning';
16
16
  export type EvidenceKind = 'command' | 'evidence' | 'visual' | 'runtime' | 'skipped' | 'blocked' | 'assumption' | 'cleanup' | 'none';
17
17
  export type RuntimeSubsystem = 'real_runtime' | 'tmux_physical' | 'process_cleanup' | 'browser_visual' | 'db_safety';
18
+ export type RuntimeBackend = 'none' | 'in_app_browser' | 'playwright' | 'terminal' | 'tmux' | 'zellij' | 'unknown';
19
+ export type RuntimeClaim = 'not_started' | 'started' | 'observed' | 'stopped' | 'cleanup_verified' | 'blocked' | 'unknown';
18
20
 
19
21
  export interface SafetyHit {
20
22
  level: SafetyLevel;
@@ -79,6 +81,41 @@ export interface MissionPatchEnvelope {
79
81
  truth_status: TruthStatus;
80
82
  }
81
83
 
84
+ export interface RuntimeBackendEvidence {
85
+ schema: 'yam.runtime-backend-evidence.v1';
86
+ backend: RuntimeBackend;
87
+ claim: RuntimeClaim;
88
+ evidence_id: string;
89
+ command: string;
90
+ cleanup_checked: boolean;
91
+ note: string;
92
+ truth_status: TruthStatus;
93
+ }
94
+
95
+ export interface UeyeRunReport {
96
+ schema: 'yam.ueye-run-report.v1';
97
+ reference_sources: UeyeVisualProvenance[];
98
+ implementation_sources: UeyeVisualProvenance[];
99
+ comparison_result: string;
100
+ design_quality: string;
101
+ blocked_reason: string;
102
+ next_action: string;
103
+ truth_status: TruthStatus;
104
+ }
105
+
106
+ export interface MediaGenerationProof {
107
+ schema: 'yam.media-generation-proof.v1';
108
+ tool_name: string;
109
+ generation_requested: boolean;
110
+ generation_attempted: boolean;
111
+ output_path: string;
112
+ output_hash: string;
113
+ wait_loop_checked: boolean;
114
+ blocked_reason: string;
115
+ next_action: string;
116
+ truth_status: TruthStatus;
117
+ }
118
+
82
119
  export interface FakeRealPolicyResult {
83
120
  schema: 'yam.fake-real-policy.v1';
84
121
  ok: boolean;
@@ -106,6 +143,8 @@ export interface ProofSummary {
106
143
  visualProvenance?: unknown;
107
144
  missionEnvelope?: unknown;
108
145
  rollbackHint?: unknown;
146
+ runtimeBackendEvidence?: unknown;
147
+ mediaProof?: unknown;
109
148
  }
110
149
 
111
150
  export interface ProofOptions {
@@ -139,6 +178,8 @@ export interface YamCompletionProof {
139
178
  visualProvenance: string[];
140
179
  missionEnvelope: string[];
141
180
  rollbackHint: string[];
181
+ runtimeBackendEvidence: string[];
182
+ mediaProof: string[];
142
183
  cleanup: unknown;
143
184
  changed: string[];
144
185
  skipped: string[];
@@ -193,6 +234,73 @@ export function buildMissionPatchEnvelope(input: Partial<MissionPatchEnvelope> =
193
234
  };
194
235
  }
195
236
 
237
+ export function buildRuntimeBackendEvidence(input: Partial<RuntimeBackendEvidence> = {}): RuntimeBackendEvidence {
238
+ const backend = normalizeRuntimeBackend(input.backend);
239
+ const claim = normalizeRuntimeClaim(input.claim);
240
+ return {
241
+ schema: 'yam.runtime-backend-evidence.v1',
242
+ backend,
243
+ claim,
244
+ evidence_id: String(input.evidence_id || ''),
245
+ command: String(input.command || ''),
246
+ cleanup_checked: Boolean(input.cleanup_checked),
247
+ note: String(input.note || ''),
248
+ truth_status: isTruthStatus(input.truth_status) ? input.truth_status : runtimeBackendTruth(backend, claim, Boolean(input.cleanup_checked))
249
+ };
250
+ }
251
+
252
+ export function buildUeyeRunReport(input: Partial<UeyeRunReport> = {}): UeyeRunReport {
253
+ const references = Array.isArray(input.reference_sources)
254
+ ? input.reference_sources.map((item) => buildUeyeVisualProvenance(item))
255
+ : [];
256
+ const implementations = Array.isArray(input.implementation_sources)
257
+ ? input.implementation_sources.map((item) => buildUeyeVisualProvenance(item))
258
+ : [];
259
+ const blockedReason = String(input.blocked_reason || '');
260
+ const comparisonResult = String(input.comparison_result || 'not-verified');
261
+ const hasImplementation = implementations.length > 0;
262
+ const derivedTruth: TruthStatus = blockedReason ? 'blocked'
263
+ : !references.length && !hasImplementation ? 'assumed'
264
+ : comparisonResult === 'matched' && hasImplementation ? 'verified'
265
+ : hasImplementation ? 'partial'
266
+ : 'partial';
267
+ return {
268
+ schema: 'yam.ueye-run-report.v1',
269
+ reference_sources: references,
270
+ implementation_sources: implementations,
271
+ comparison_result: comparisonResult,
272
+ design_quality: String(input.design_quality || 'not-checked'),
273
+ blocked_reason: blockedReason,
274
+ next_action: String(input.next_action || (derivedTruth === 'verified' ? 'no action required' : 'capture or provide implementation screenshot before claiming verified visual status')),
275
+ truth_status: isTruthStatus(input.truth_status) ? input.truth_status : derivedTruth
276
+ };
277
+ }
278
+
279
+ export function buildMediaGenerationProof(input: Partial<MediaGenerationProof> = {}): MediaGenerationProof {
280
+ const requested = Boolean(input.generation_requested);
281
+ const attempted = Boolean(input.generation_attempted);
282
+ const outputHash = String(input.output_hash || 'unknown');
283
+ const blockedReason = String(input.blocked_reason || '');
284
+ const derivedTruth: TruthStatus = blockedReason ? 'blocked'
285
+ : requested && !attempted ? 'blocked'
286
+ : attempted && outputHash !== 'unknown' ? 'verified'
287
+ : attempted ? 'partial'
288
+ : requested ? 'assumed'
289
+ : 'skipped';
290
+ return {
291
+ schema: 'yam.media-generation-proof.v1',
292
+ tool_name: String(input.tool_name || ''),
293
+ generation_requested: requested,
294
+ generation_attempted: attempted,
295
+ output_path: String(input.output_path || ''),
296
+ output_hash: outputHash,
297
+ wait_loop_checked: Boolean(input.wait_loop_checked),
298
+ blocked_reason: blockedReason,
299
+ next_action: String(input.next_action || (derivedTruth === 'blocked' ? 'provide a usable media tool or mark generation as skipped' : 'record output evidence before using generated media as implementation proof')),
300
+ truth_status: isTruthStatus(input.truth_status) ? input.truth_status : derivedTruth
301
+ };
302
+ }
303
+
196
304
  const TRUTH_RANK: Readonly<Record<TruthStatus, number>> = Object.freeze({
197
305
  blocked: 0,
198
306
  real_required_missing: 0,
@@ -273,6 +381,12 @@ export function classifyEvidenceTruth(summary: ProofSummary = {}, options: Proof
273
381
  for (const rollback of asList(summary.rollbackHint)) {
274
382
  rows.push(evidenceRow('evidence', rollback, metadataTruth(rollback, 'partial')));
275
383
  }
384
+ for (const backend of asList(summary.runtimeBackendEvidence)) {
385
+ rows.push(evidenceRow('runtime', backend, readStructuredTruth(backend, 'partial')));
386
+ }
387
+ for (const media of asList(summary.mediaProof)) {
388
+ rows.push(evidenceRow('evidence', media, readStructuredTruth(media, 'partial')));
389
+ }
276
390
  for (const runtime of asList(summary.runtime)) {
277
391
  rows.push(evidenceRow('runtime', runtime, classifyRuntimeEvidence(runtime, options)));
278
392
  }
@@ -359,6 +473,8 @@ export function buildYamCompletionProof(summary: ProofSummary = {}, options: Pro
359
473
  visualProvenance: asList(summary.visualProvenance),
360
474
  missionEnvelope: asList(summary.missionEnvelope),
361
475
  rollbackHint: asList(summary.rollbackHint),
476
+ runtimeBackendEvidence: asList(summary.runtimeBackendEvidence),
477
+ mediaProof: asList(summary.mediaProof),
362
478
  cleanup: summary.cleanup || '',
363
479
  changed: asList(summary.changed),
364
480
  skipped: asList(summary.skipped),
@@ -491,6 +607,37 @@ function runtimeRow(subsystem: RuntimeSubsystem, proofLevel: TruthStatus, requir
491
607
  };
492
608
  }
493
609
 
610
+ function normalizeRuntimeBackend(value: unknown = ''): RuntimeBackend {
611
+ const text = String(value || '').toLowerCase().replace(/[-\s]/g, '_');
612
+ if (text === 'in_app_browser' || text === 'browser') return 'in_app_browser';
613
+ if (text === 'playwright') return 'playwright';
614
+ if (text === 'terminal' || text === 'shell') return 'terminal';
615
+ if (text === 'tmux') return 'tmux';
616
+ if (text === 'zellij') return 'zellij';
617
+ if (text === 'none' || text === 'not_started') return 'none';
618
+ return 'unknown';
619
+ }
620
+
621
+ function normalizeRuntimeClaim(value: unknown = ''): RuntimeClaim {
622
+ const text = String(value || '').toLowerCase().replace(/[-\s]/g, '_');
623
+ if (text === 'not_started' || text === 'none') return 'not_started';
624
+ if (text === 'started') return 'started';
625
+ if (text === 'observed' || text === 'checked') return 'observed';
626
+ if (text === 'stopped') return 'stopped';
627
+ if (text === 'cleanup_verified' || text === 'cleanup_checked') return 'cleanup_verified';
628
+ if (text === 'blocked') return 'blocked';
629
+ return 'unknown';
630
+ }
631
+
632
+ function runtimeBackendTruth(backend: RuntimeBackend, claim: RuntimeClaim, cleanupChecked = false): TruthStatus {
633
+ if (claim === 'blocked') return 'blocked';
634
+ if (backend === 'none' || claim === 'not_started') return 'skipped';
635
+ if (backend === 'unknown' || claim === 'unknown') return 'partial';
636
+ if (claim === 'cleanup_verified' || cleanupChecked) return 'proven';
637
+ if (claim === 'observed' || claim === 'stopped' || claim === 'started') return 'verified';
638
+ return 'partial';
639
+ }
640
+
494
641
  function evidenceRow(kind: EvidenceKind, value: unknown, truth: TruthStatus): EvidenceRow {
495
642
  return { kind, value: String(value || ''), truth };
496
643
  }