yam-flow 0.1.4 → 0.1.6
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 +28 -0
- package/COMMANDS.md +4 -2
- package/README.md +8 -3
- package/dist/bin/yam.js +133 -14
- package/dist/lib/trust-kernel.d.ts +56 -1
- package/dist/lib/trust-kernel.js +149 -2
- package/package.json +2 -2
- package/references/trust-kernel.md +3 -0
- package/references/ueye-proof.md +79 -2
- package/references/ueye.md +44 -4
- package/skills/ueye/SKILL.md +29 -8
- package/src/bin/yam.ts +134 -12
- package/src/lib/trust-kernel.ts +208 -3
- package/templates/ueye-comparison.md +71 -0
- package/templates/ueye-review.md +71 -0
- package/yam.manifest.json +2 -2
package/src/lib/trust-kernel.ts
CHANGED
|
@@ -56,6 +56,11 @@ export interface UeyeVisualProvenance {
|
|
|
56
56
|
source_hash: string;
|
|
57
57
|
reference_id: string;
|
|
58
58
|
screenshot_id: string;
|
|
59
|
+
provider_context: string;
|
|
60
|
+
provider_badge: string;
|
|
61
|
+
execution_surface: string;
|
|
62
|
+
app_surface: string;
|
|
63
|
+
browser_surface: string;
|
|
59
64
|
local_only: boolean;
|
|
60
65
|
redacted: boolean;
|
|
61
66
|
operator_provided: boolean;
|
|
@@ -63,6 +68,50 @@ export interface UeyeVisualProvenance {
|
|
|
63
68
|
truth_status: TruthStatus;
|
|
64
69
|
}
|
|
65
70
|
|
|
71
|
+
export interface UeyeSurfaceContext {
|
|
72
|
+
schema: 'yam.ueye-surface-context.v1';
|
|
73
|
+
provider_context: string;
|
|
74
|
+
provider_badge: string;
|
|
75
|
+
execution_surface: string;
|
|
76
|
+
app_surface: string;
|
|
77
|
+
browser_surface: string;
|
|
78
|
+
control_mode: string;
|
|
79
|
+
route: string;
|
|
80
|
+
mode: string;
|
|
81
|
+
url: string;
|
|
82
|
+
viewport: string;
|
|
83
|
+
screenshot_id: string;
|
|
84
|
+
evidence_id: string;
|
|
85
|
+
preserved_state: boolean;
|
|
86
|
+
preserved_url: string;
|
|
87
|
+
local_only: boolean;
|
|
88
|
+
truth_status: TruthStatus;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface UeyeDesignGateCheck {
|
|
92
|
+
id: string;
|
|
93
|
+
label: string;
|
|
94
|
+
status: 'pass' | 'fail' | 'warning' | 'not_checked';
|
|
95
|
+
required: boolean;
|
|
96
|
+
next_action: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface UeyeDesignCompletionGate {
|
|
100
|
+
schema: 'yam.ueye-design-completion-gate.v1';
|
|
101
|
+
mode: 'fast' | 'strict';
|
|
102
|
+
completion_claim: 'draft' | 'needs-polish' | 'done';
|
|
103
|
+
ready_to_claim_done: boolean;
|
|
104
|
+
design_score: number | null;
|
|
105
|
+
min_design_score: number;
|
|
106
|
+
checks: UeyeDesignGateCheck[];
|
|
107
|
+
p0: string[];
|
|
108
|
+
p1: string[];
|
|
109
|
+
warnings: string[];
|
|
110
|
+
blockers: string[];
|
|
111
|
+
next_action: string;
|
|
112
|
+
truth_status: TruthStatus;
|
|
113
|
+
}
|
|
114
|
+
|
|
66
115
|
export interface RollbackHint {
|
|
67
116
|
schema: 'yam.rollback-hint.v1';
|
|
68
117
|
touched_files: string[];
|
|
@@ -96,6 +145,8 @@ export interface UeyeRunReport {
|
|
|
96
145
|
schema: 'yam.ueye-run-report.v1';
|
|
97
146
|
reference_sources: UeyeVisualProvenance[];
|
|
98
147
|
implementation_sources: UeyeVisualProvenance[];
|
|
148
|
+
surface_context: UeyeSurfaceContext;
|
|
149
|
+
design_completion_gate: UeyeDesignCompletionGate;
|
|
99
150
|
comparison_result: string;
|
|
100
151
|
design_quality: string;
|
|
101
152
|
blocked_reason: string;
|
|
@@ -103,6 +154,10 @@ export interface UeyeRunReport {
|
|
|
103
154
|
truth_status: TruthStatus;
|
|
104
155
|
}
|
|
105
156
|
|
|
157
|
+
export interface UeyeRunReportInput extends Partial<Omit<UeyeRunReport, 'design_completion_gate'>> {
|
|
158
|
+
design_completion_gate?: Partial<UeyeDesignCompletionGate> & Record<string, unknown>;
|
|
159
|
+
}
|
|
160
|
+
|
|
106
161
|
export interface MediaGenerationProof {
|
|
107
162
|
schema: 'yam.media-generation-proof.v1';
|
|
108
163
|
tool_name: string;
|
|
@@ -145,6 +200,7 @@ export interface ProofSummary {
|
|
|
145
200
|
rollbackHint?: unknown;
|
|
146
201
|
runtimeBackendEvidence?: unknown;
|
|
147
202
|
mediaProof?: unknown;
|
|
203
|
+
designCompletion?: unknown;
|
|
148
204
|
}
|
|
149
205
|
|
|
150
206
|
export interface ProofOptions {
|
|
@@ -180,6 +236,7 @@ export interface YamCompletionProof {
|
|
|
180
236
|
rollbackHint: string[];
|
|
181
237
|
runtimeBackendEvidence: string[];
|
|
182
238
|
mediaProof: string[];
|
|
239
|
+
designCompletion: string[];
|
|
183
240
|
cleanup: unknown;
|
|
184
241
|
changed: string[];
|
|
185
242
|
skipped: string[];
|
|
@@ -201,6 +258,11 @@ export function buildUeyeVisualProvenance(input: Partial<UeyeVisualProvenance> =
|
|
|
201
258
|
source_hash: String(input.source_hash || 'unknown'),
|
|
202
259
|
reference_id: String(input.reference_id || ''),
|
|
203
260
|
screenshot_id: String(input.screenshot_id || ''),
|
|
261
|
+
provider_context: String(input.provider_context || 'not-recorded'),
|
|
262
|
+
provider_badge: String(input.provider_badge || 'not-recorded'),
|
|
263
|
+
execution_surface: String(input.execution_surface || 'not-recorded'),
|
|
264
|
+
app_surface: String(input.app_surface || 'not-recorded'),
|
|
265
|
+
browser_surface: String(input.browser_surface || 'not-recorded'),
|
|
204
266
|
local_only: Boolean(input.local_only),
|
|
205
267
|
redacted: Boolean(input.redacted),
|
|
206
268
|
operator_provided: Boolean(input.operator_provided),
|
|
@@ -209,6 +271,116 @@ export function buildUeyeVisualProvenance(input: Partial<UeyeVisualProvenance> =
|
|
|
209
271
|
};
|
|
210
272
|
}
|
|
211
273
|
|
|
274
|
+
export function buildUeyeSurfaceContext(input: Partial<UeyeSurfaceContext> = {}): UeyeSurfaceContext {
|
|
275
|
+
return {
|
|
276
|
+
schema: 'yam.ueye-surface-context.v1',
|
|
277
|
+
provider_context: String(input.provider_context || 'not-recorded'),
|
|
278
|
+
provider_badge: String(input.provider_badge || input.provider_context || 'not-recorded'),
|
|
279
|
+
execution_surface: String(input.execution_surface || 'not-recorded'),
|
|
280
|
+
app_surface: String(input.app_surface || 'not-recorded'),
|
|
281
|
+
browser_surface: String(input.browser_surface || 'not-recorded'),
|
|
282
|
+
control_mode: String(input.control_mode || 'not-recorded'),
|
|
283
|
+
route: String(input.route || 'ueye'),
|
|
284
|
+
mode: String(input.mode || 'report'),
|
|
285
|
+
url: String(input.url || ''),
|
|
286
|
+
viewport: String(input.viewport || ''),
|
|
287
|
+
screenshot_id: String(input.screenshot_id || ''),
|
|
288
|
+
evidence_id: String(input.evidence_id || ''),
|
|
289
|
+
preserved_state: Boolean(input.preserved_state),
|
|
290
|
+
preserved_url: String(input.preserved_url || ''),
|
|
291
|
+
local_only: input.local_only !== undefined ? Boolean(input.local_only) : true,
|
|
292
|
+
truth_status: isTruthStatus(input.truth_status) ? input.truth_status : 'partial'
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function buildUeyeDesignCompletionGate(input: Partial<UeyeDesignCompletionGate> & Record<string, unknown> = {}): UeyeDesignCompletionGate {
|
|
297
|
+
const completionClaim = normalizeUeyeCompletionClaim(input.completion_claim);
|
|
298
|
+
const mode = String(input.mode || '').toLowerCase() === 'strict' || completionClaim === 'done' ? 'strict' : 'fast';
|
|
299
|
+
const designScore = numberOrNull(input.design_score);
|
|
300
|
+
const minDesignScore = numberOrNull(input.min_design_score) ?? 8;
|
|
301
|
+
const p0 = asList(input.p0);
|
|
302
|
+
const p1 = asList(input.p1);
|
|
303
|
+
const hasReference = Boolean(input.has_reference);
|
|
304
|
+
const hasImplementation = Boolean(input.has_implementation_screenshot);
|
|
305
|
+
const comparisonResult = String(input.comparison_result || 'not-verified');
|
|
306
|
+
const designQuality = String(input.design_quality || 'not-checked');
|
|
307
|
+
const blockedReason = String(input.blocked_reason || '');
|
|
308
|
+
const strictOrDone = mode === 'strict' || completionClaim === 'done';
|
|
309
|
+
const checks: UeyeDesignGateCheck[] = [
|
|
310
|
+
designGateCheck('direction_lock', 'Design direction and target screen were locked before judging completion', Boolean(input.direction_locked) ? 'pass' : 'not_checked', strictOrDone, 'record the target screen and design direction before claiming done'),
|
|
311
|
+
designGateCheck('reference_read', 'Reference read proof exists when reference is used', !hasReference ? 'not_checked' : Boolean(input.reference_read) ? 'pass' : 'fail', hasReference && strictOrDone, 'record concrete reference observations before claiming reference-led work is done'),
|
|
312
|
+
designGateCheck('implementation_screenshot', 'Real implementation screenshot or screen evidence exists', hasImplementation ? 'pass' : 'fail', strictOrDone, 'capture or provide implementation screenshot before claiming done'),
|
|
313
|
+
designGateCheck('reference_comparison', 'Reference comparison is recorded when reference is used', !hasReference ? 'not_checked' : ['matched', 'similar', 'not-applicable'].includes(comparisonResult) ? 'pass' : 'fail', hasReference, 'compare against the reference or mark the difference as intentional before claiming done'),
|
|
314
|
+
designGateCheck('design_quality', 'Design quality result is pass', designQuality === 'pass' ? 'pass' : designQuality === 'needs-polish' ? 'warning' : 'fail', strictOrDone, 'resolve design quality issues or keep the result as needs-polish/partial'),
|
|
315
|
+
designGateCheck('p0_clear', 'No P0 visual blockers remain', p0.length ? 'fail' : 'pass', true, 'fix P0 blockers before any done claim'),
|
|
316
|
+
designGateCheck('p1_clear', 'No P1 major visual issues remain', p1.length ? 'fail' : 'pass', strictOrDone, 'fix or explicitly defer P1 issues before claiming done'),
|
|
317
|
+
designGateCheck('cta_affordance', 'Primary CTA and interaction affordances were checked', Boolean(input.cta_checked) ? 'pass' : 'not_checked', strictOrDone, 'check primary CTA clarity and interaction affordances before claiming done'),
|
|
318
|
+
designGateCheck('state_coverage', 'Primary UI states were checked', Boolean(input.states_checked) ? 'pass' : 'not_checked', strictOrDone, 'check default/loading/error/empty/disabled states or keep completion partial'),
|
|
319
|
+
designGateCheck('mobile_coverage', 'Mobile/responsive behavior was checked', Boolean(input.mobile_checked || input.responsive_checked) ? 'pass' : 'not_checked', strictOrDone, 'check mobile/responsive behavior before claiming done'),
|
|
320
|
+
designGateCheck('accessibility_visuals', 'Contrast/accessibility-relevant visuals were checked', Boolean(input.contrast_checked || input.accessibility_checked) ? 'pass' : 'not_checked', strictOrDone, 'check contrast/accessibility-relevant visuals before claiming done')
|
|
321
|
+
];
|
|
322
|
+
if (designScore !== null || strictOrDone) {
|
|
323
|
+
checks.push(designGateCheck('design_score', `Design score is at least ${minDesignScore}`, designScore !== null && designScore >= minDesignScore ? 'pass' : designScore === null ? 'not_checked' : 'fail', false, `record --design-score ${minDesignScore} or higher when using score-based completion`));
|
|
324
|
+
}
|
|
325
|
+
const blockers = [
|
|
326
|
+
...p0.map((item) => `P0: ${item}`),
|
|
327
|
+
...(blockedReason ? [blockedReason] : []),
|
|
328
|
+
...checks
|
|
329
|
+
.filter((check) => check.required && check.status !== 'pass')
|
|
330
|
+
.map((check) => `${check.id}: ${check.next_action}`)
|
|
331
|
+
];
|
|
332
|
+
const warnings = [
|
|
333
|
+
...p1.map((item) => `P1: ${item}`),
|
|
334
|
+
...checks
|
|
335
|
+
.filter((check) => !check.required && ['fail', 'warning', 'not_checked'].includes(check.status))
|
|
336
|
+
.map((check) => `${check.id}: ${check.next_action}`)
|
|
337
|
+
];
|
|
338
|
+
const ready = completionClaim === 'done' && blockers.length === 0;
|
|
339
|
+
const truth: TruthStatus = blockers.some((item) => item.startsWith('P0:')) || blockedReason ? 'blocked'
|
|
340
|
+
: ready ? 'verified'
|
|
341
|
+
: strictOrDone ? 'partial'
|
|
342
|
+
: hasImplementation ? 'partial'
|
|
343
|
+
: 'assumed';
|
|
344
|
+
return {
|
|
345
|
+
schema: 'yam.ueye-design-completion-gate.v1',
|
|
346
|
+
mode,
|
|
347
|
+
completion_claim: completionClaim,
|
|
348
|
+
ready_to_claim_done: ready,
|
|
349
|
+
design_score: designScore,
|
|
350
|
+
min_design_score: minDesignScore,
|
|
351
|
+
checks,
|
|
352
|
+
p0,
|
|
353
|
+
p1,
|
|
354
|
+
warnings,
|
|
355
|
+
blockers,
|
|
356
|
+
next_action: blockers[0] || (ready ? 'done claim is supported by the recorded design gate' : warnings[0] || 'keep the Ueye result as draft or needs-polish until a done claim is needed'),
|
|
357
|
+
truth_status: truth
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
function normalizeUeyeCompletionClaim(value: unknown = ''): UeyeDesignCompletionGate['completion_claim'] {
|
|
362
|
+
const text = String(value || '').toLowerCase();
|
|
363
|
+
if (text === 'done' || text === 'complete' || text === 'completed') return 'done';
|
|
364
|
+
if (text === 'needs-polish' || text === 'needs_polish' || text === 'polish') return 'needs-polish';
|
|
365
|
+
return 'draft';
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function designGateCheck(id: string, label: string, status: UeyeDesignGateCheck['status'], required: boolean, nextAction: string): UeyeDesignGateCheck {
|
|
369
|
+
return {
|
|
370
|
+
id,
|
|
371
|
+
label,
|
|
372
|
+
status,
|
|
373
|
+
required,
|
|
374
|
+
next_action: nextAction
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function numberOrNull(value: unknown = null): number | null {
|
|
379
|
+
if (value === undefined || value === null || value === '') return null;
|
|
380
|
+
const number = Number(value);
|
|
381
|
+
return Number.isFinite(number) ? number : null;
|
|
382
|
+
}
|
|
383
|
+
|
|
212
384
|
export function buildRollbackHint(input: Partial<RollbackHint> = {}): RollbackHint {
|
|
213
385
|
return {
|
|
214
386
|
schema: 'yam.rollback-hint.v1',
|
|
@@ -249,7 +421,7 @@ export function buildRuntimeBackendEvidence(input: Partial<RuntimeBackendEvidenc
|
|
|
249
421
|
};
|
|
250
422
|
}
|
|
251
423
|
|
|
252
|
-
export function buildUeyeRunReport(input:
|
|
424
|
+
export function buildUeyeRunReport(input: UeyeRunReportInput = {}): UeyeRunReport {
|
|
253
425
|
const references = Array.isArray(input.reference_sources)
|
|
254
426
|
? input.reference_sources.map((item) => buildUeyeVisualProvenance(item))
|
|
255
427
|
: [];
|
|
@@ -264,15 +436,30 @@ export function buildUeyeRunReport(input: Partial<UeyeRunReport> = {}): UeyeRunR
|
|
|
264
436
|
: comparisonResult === 'matched' && hasImplementation ? 'verified'
|
|
265
437
|
: hasImplementation ? 'partial'
|
|
266
438
|
: 'partial';
|
|
439
|
+
const gate = buildUeyeDesignCompletionGate({
|
|
440
|
+
...input.design_completion_gate,
|
|
441
|
+
has_reference: references.length > 0,
|
|
442
|
+
has_implementation_screenshot: hasImplementation,
|
|
443
|
+
comparison_result: comparisonResult,
|
|
444
|
+
design_quality: String(input.design_quality || 'not-checked'),
|
|
445
|
+
blocked_reason: blockedReason
|
|
446
|
+
});
|
|
447
|
+
const shouldApplyDesignGate = gate.mode === 'strict' || gate.completion_claim === 'done' || gate.blockers.length > 0;
|
|
448
|
+
const finalTruth = shouldApplyDesignGate ? weakestTruth(derivedTruth, gate.truth_status) : derivedTruth;
|
|
267
449
|
return {
|
|
268
450
|
schema: 'yam.ueye-run-report.v1',
|
|
269
451
|
reference_sources: references,
|
|
270
452
|
implementation_sources: implementations,
|
|
453
|
+
surface_context: buildUeyeSurfaceContext({
|
|
454
|
+
...input.surface_context,
|
|
455
|
+
truth_status: isTruthStatus(input.surface_context?.truth_status) ? input.surface_context?.truth_status : finalTruth
|
|
456
|
+
}),
|
|
457
|
+
design_completion_gate: gate,
|
|
271
458
|
comparison_result: comparisonResult,
|
|
272
459
|
design_quality: String(input.design_quality || 'not-checked'),
|
|
273
460
|
blocked_reason: blockedReason,
|
|
274
|
-
next_action: String(input.next_action || (
|
|
275
|
-
truth_status: isTruthStatus(input.truth_status) ? input.truth_status :
|
|
461
|
+
next_action: String(input.next_action || gate.blockers[0] || (finalTruth === 'verified' ? 'no action required' : 'capture or provide implementation screenshot before claiming verified visual status')),
|
|
462
|
+
truth_status: isTruthStatus(input.truth_status) ? input.truth_status : finalTruth
|
|
276
463
|
};
|
|
277
464
|
}
|
|
278
465
|
|
|
@@ -387,6 +574,9 @@ export function classifyEvidenceTruth(summary: ProofSummary = {}, options: Proof
|
|
|
387
574
|
for (const media of asList(summary.mediaProof)) {
|
|
388
575
|
rows.push(evidenceRow('evidence', media, readStructuredTruth(media, 'partial')));
|
|
389
576
|
}
|
|
577
|
+
for (const designCompletion of asList(summary.designCompletion)) {
|
|
578
|
+
rows.push(evidenceRow('visual', designCompletion, readStructuredTruth(designCompletion, 'partial')));
|
|
579
|
+
}
|
|
390
580
|
for (const runtime of asList(summary.runtime)) {
|
|
391
581
|
rows.push(evidenceRow('runtime', runtime, classifyRuntimeEvidence(runtime, options)));
|
|
392
582
|
}
|
|
@@ -416,6 +606,14 @@ export function applyProofTruthCaps(summary: ProofSummary = {}, options: ProofOp
|
|
|
416
606
|
cappedTruth = weakestTruth(cappedTruth, 'partial');
|
|
417
607
|
unverified.push('real_visual_evidence_missing');
|
|
418
608
|
}
|
|
609
|
+
const designCompletionTruth = designCompletionCap(summary.designCompletion);
|
|
610
|
+
if (designCompletionTruth) {
|
|
611
|
+
cappedTruth = weakestTruth(cappedTruth, designCompletionTruth);
|
|
612
|
+
if (designCompletionTruth === 'blocked') blockers.push('ueye_design_completion_blocked');
|
|
613
|
+
if (!['verified', 'proven'].includes(designCompletionTruth)) {
|
|
614
|
+
unverified.push('ueye_design_completion_not_verified');
|
|
615
|
+
}
|
|
616
|
+
}
|
|
419
617
|
if (requested !== cappedTruth) {
|
|
420
618
|
caps.push(`requested ${requested} capped to ${cappedTruth} by evidence`);
|
|
421
619
|
}
|
|
@@ -475,6 +673,7 @@ export function buildYamCompletionProof(summary: ProofSummary = {}, options: Pro
|
|
|
475
673
|
rollbackHint: asList(summary.rollbackHint),
|
|
476
674
|
runtimeBackendEvidence: asList(summary.runtimeBackendEvidence),
|
|
477
675
|
mediaProof: asList(summary.mediaProof),
|
|
676
|
+
designCompletion: asList(summary.designCompletion),
|
|
478
677
|
cleanup: summary.cleanup || '',
|
|
479
678
|
changed: asList(summary.changed),
|
|
480
679
|
skipped: asList(summary.skipped),
|
|
@@ -544,6 +743,12 @@ function readStructuredTruth(value: unknown = '', fallback: TruthStatus = 'parti
|
|
|
544
743
|
}
|
|
545
744
|
}
|
|
546
745
|
|
|
746
|
+
function designCompletionCap(value: unknown = ''): TruthStatus | null {
|
|
747
|
+
const items = asList(value);
|
|
748
|
+
if (!items.length) return null;
|
|
749
|
+
return items.reduce<TruthStatus>((weakest, item) => weakestTruth(weakest, readStructuredTruth(item, 'partial')), 'proven');
|
|
750
|
+
}
|
|
751
|
+
|
|
547
752
|
function strongestSupportedTruth(rows: EvidenceRow[] = []): TruthStatus {
|
|
548
753
|
if (rows.some((row) => row.truth === 'blocked')) return 'blocked';
|
|
549
754
|
if (rows.some((row) => row.truth === 'real_required_missing')) return 'real_required_missing';
|
|
@@ -31,6 +31,24 @@
|
|
|
31
31
|
| comparison_result | matched / similar / different / not-verified / not-applicable |
|
|
32
32
|
| truth_status | verified / partial / skipped / blocked / assumed |
|
|
33
33
|
|
|
34
|
+
## Surface Context
|
|
35
|
+
|
|
36
|
+
| Field | Value |
|
|
37
|
+
| --- | --- |
|
|
38
|
+
| provider_context | not-recorded |
|
|
39
|
+
| provider_badge | not-recorded |
|
|
40
|
+
| execution_surface | not-recorded |
|
|
41
|
+
| app_surface | not-recorded |
|
|
42
|
+
| browser_surface | not-recorded |
|
|
43
|
+
| control_mode | not-recorded |
|
|
44
|
+
| url | |
|
|
45
|
+
| viewport | |
|
|
46
|
+
| screenshot_id | |
|
|
47
|
+
| evidence_id | |
|
|
48
|
+
| preserved_state | true / false |
|
|
49
|
+
| preserved_url | |
|
|
50
|
+
| truth_status | verified / partial / skipped / blocked / assumed |
|
|
51
|
+
|
|
34
52
|
## Reference Read Proof
|
|
35
53
|
|
|
36
54
|
- Layout:
|
|
@@ -94,6 +112,36 @@ Use `pass`, `needs-polish`, or `fails` for each relevant design dimension before
|
|
|
94
112
|
| Accessibility | needs-polish | |
|
|
95
113
|
| Brand/mood fit | needs-polish | |
|
|
96
114
|
|
|
115
|
+
## Design Completion Gate
|
|
116
|
+
|
|
117
|
+
| Field | Value |
|
|
118
|
+
| --- | --- |
|
|
119
|
+
| completion_claim | draft / needs-polish / done |
|
|
120
|
+
| mode | fast / strict |
|
|
121
|
+
| ready_to_claim_done | true / false |
|
|
122
|
+
| design_score | |
|
|
123
|
+
| min_design_score | 8 |
|
|
124
|
+
| direction_locked | true / false |
|
|
125
|
+
| reference_read | true / false / not-applicable |
|
|
126
|
+
| implementation_screenshot | pass / fail / not_checked |
|
|
127
|
+
| reference_comparison | matched / similar / different / not-verified / not-applicable |
|
|
128
|
+
| design_quality | pass / needs-polish / fails / not-checked |
|
|
129
|
+
| p0_clear | pass / fail |
|
|
130
|
+
| p1_clear | pass / fail / deferred |
|
|
131
|
+
| cta_checked | true / false |
|
|
132
|
+
| states_checked | true / false |
|
|
133
|
+
| mobile_checked | true / false |
|
|
134
|
+
| contrast_accessibility_checked | true / false |
|
|
135
|
+
| truth_status | verified / partial / skipped / blocked / assumed |
|
|
136
|
+
|
|
137
|
+
### Design Gate Blockers
|
|
138
|
+
|
|
139
|
+
- None.
|
|
140
|
+
|
|
141
|
+
### Design Gate Warnings
|
|
142
|
+
|
|
143
|
+
- None.
|
|
144
|
+
|
|
97
145
|
### P0 Blockers
|
|
98
146
|
|
|
99
147
|
- None.
|
|
@@ -123,6 +171,29 @@ Use `pass`, `needs-polish`, or `fails` for each relevant design dimension before
|
|
|
123
171
|
"previous_screenshot_id": "",
|
|
124
172
|
"current_report_id": "",
|
|
125
173
|
"current_screenshot_id": "",
|
|
174
|
+
"surface_context": {
|
|
175
|
+
"provider_context": "not-recorded",
|
|
176
|
+
"provider_badge": "not-recorded",
|
|
177
|
+
"execution_surface": "not-recorded",
|
|
178
|
+
"app_surface": "not-recorded",
|
|
179
|
+
"browser_surface": "not-recorded",
|
|
180
|
+
"control_mode": "not-recorded",
|
|
181
|
+
"preserved_state": false,
|
|
182
|
+
"preserved_url": "",
|
|
183
|
+
"truth_status": "partial"
|
|
184
|
+
},
|
|
185
|
+
"design_completion_gate": {
|
|
186
|
+
"completion_claim": "needs-polish",
|
|
187
|
+
"mode": "fast",
|
|
188
|
+
"ready_to_claim_done": false,
|
|
189
|
+
"design_score": null,
|
|
190
|
+
"min_design_score": 8,
|
|
191
|
+
"p0": [],
|
|
192
|
+
"p1": [],
|
|
193
|
+
"blockers": [],
|
|
194
|
+
"warnings": [],
|
|
195
|
+
"truth_status": "partial"
|
|
196
|
+
},
|
|
126
197
|
"viewport": "",
|
|
127
198
|
"state": "",
|
|
128
199
|
"comparison_result": "not-verified",
|
package/templates/ueye-review.md
CHANGED
|
@@ -42,6 +42,24 @@
|
|
|
42
42
|
| comparison_result | matched / similar / different / not-verified / not-applicable |
|
|
43
43
|
| truth_status | verified / partial / skipped / blocked / assumed |
|
|
44
44
|
|
|
45
|
+
## Surface Context
|
|
46
|
+
|
|
47
|
+
| Field | Value |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| provider_context | not-recorded |
|
|
50
|
+
| provider_badge | not-recorded |
|
|
51
|
+
| execution_surface | not-recorded |
|
|
52
|
+
| app_surface | not-recorded |
|
|
53
|
+
| browser_surface | not-recorded |
|
|
54
|
+
| control_mode | not-recorded |
|
|
55
|
+
| url | |
|
|
56
|
+
| viewport | |
|
|
57
|
+
| screenshot_id | |
|
|
58
|
+
| evidence_id | |
|
|
59
|
+
| preserved_state | true / false |
|
|
60
|
+
| preserved_url | |
|
|
61
|
+
| truth_status | verified / partial / skipped / blocked / assumed |
|
|
62
|
+
|
|
45
63
|
## Reference Read Proof
|
|
46
64
|
|
|
47
65
|
- Layout:
|
|
@@ -105,6 +123,36 @@ Status values: matched / similar / different / not-verified / not-applicable.
|
|
|
105
123
|
|
|
106
124
|
Result values: pass / needs-polish / fails.
|
|
107
125
|
|
|
126
|
+
## Design Completion Gate
|
|
127
|
+
|
|
128
|
+
| Field | Value |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| completion_claim | draft / needs-polish / done |
|
|
131
|
+
| mode | fast / strict |
|
|
132
|
+
| ready_to_claim_done | true / false |
|
|
133
|
+
| design_score | |
|
|
134
|
+
| min_design_score | 8 |
|
|
135
|
+
| direction_locked | true / false |
|
|
136
|
+
| reference_read | true / false / not-applicable |
|
|
137
|
+
| implementation_screenshot | pass / fail / not_checked |
|
|
138
|
+
| reference_comparison | matched / similar / different / not-verified / not-applicable |
|
|
139
|
+
| design_quality | pass / needs-polish / fails / not-checked |
|
|
140
|
+
| p0_clear | pass / fail |
|
|
141
|
+
| p1_clear | pass / fail / deferred |
|
|
142
|
+
| cta_checked | true / false |
|
|
143
|
+
| states_checked | true / false |
|
|
144
|
+
| mobile_checked | true / false |
|
|
145
|
+
| contrast_accessibility_checked | true / false |
|
|
146
|
+
| truth_status | verified / partial / skipped / blocked / assumed |
|
|
147
|
+
|
|
148
|
+
### Design Gate Blockers
|
|
149
|
+
|
|
150
|
+
- None.
|
|
151
|
+
|
|
152
|
+
### Design Gate Warnings
|
|
153
|
+
|
|
154
|
+
- None.
|
|
155
|
+
|
|
108
156
|
## P0-P3 Issues
|
|
109
157
|
|
|
110
158
|
### P0 Blockers
|
|
@@ -155,6 +203,29 @@ Result values: pass / needs-polish / fails.
|
|
|
155
203
|
"previous_screenshot_id": "",
|
|
156
204
|
"current_report_id": "",
|
|
157
205
|
"current_screenshot_id": "",
|
|
206
|
+
"surface_context": {
|
|
207
|
+
"provider_context": "not-recorded",
|
|
208
|
+
"provider_badge": "not-recorded",
|
|
209
|
+
"execution_surface": "not-recorded",
|
|
210
|
+
"app_surface": "not-recorded",
|
|
211
|
+
"browser_surface": "not-recorded",
|
|
212
|
+
"control_mode": "not-recorded",
|
|
213
|
+
"preserved_state": false,
|
|
214
|
+
"preserved_url": "",
|
|
215
|
+
"truth_status": "partial"
|
|
216
|
+
},
|
|
217
|
+
"design_completion_gate": {
|
|
218
|
+
"completion_claim": "needs-polish",
|
|
219
|
+
"mode": "fast",
|
|
220
|
+
"ready_to_claim_done": false,
|
|
221
|
+
"design_score": null,
|
|
222
|
+
"min_design_score": 8,
|
|
223
|
+
"p0": [],
|
|
224
|
+
"p1": [],
|
|
225
|
+
"blockers": [],
|
|
226
|
+
"warnings": [],
|
|
227
|
+
"truth_status": "partial"
|
|
228
|
+
},
|
|
158
229
|
"viewport": "",
|
|
159
230
|
"state": "",
|
|
160
231
|
"comparison_result": "not-verified",
|
package/yam.manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yam",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"principles": [
|
|
5
5
|
"Direction before execution.",
|
|
6
6
|
"Start fast.",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
{
|
|
23
23
|
"id": "ueye",
|
|
24
24
|
"stage": "v0.3",
|
|
25
|
-
"purpose": "Tight UI/UX/design implementation and visual review with visual provenance, reference-read proof, visual comparison, design quality review, and P0-P3 issue tracking."
|
|
25
|
+
"purpose": "Tight UI/UX/design implementation and visual review with visual provenance, surface context, reference-read proof, visual comparison, design quality review, and P0-P3 issue tracking."
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"id": "question",
|