yam-flow 0.1.5 → 0.1.7
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/AGENTS.md +7 -4
- package/CHANGELOG.md +45 -0
- package/COMMANDS.md +12 -3
- package/DECISIONS.md +28 -5
- package/README.md +29 -5
- package/ROADMAP.md +2 -2
- package/dist/bin/yam.js +607 -20
- package/dist/lib/trust-kernel.d.ts +38 -1
- package/dist/lib/trust-kernel.js +153 -7
- package/package.json +2 -2
- package/references/cleanup-scan.md +33 -0
- package/references/final-report.md +6 -1
- package/references/risk-escalation.md +4 -0
- package/references/runtime-orchestration.md +7 -0
- package/references/scout.md +9 -3
- package/references/tool-trust-layer.md +14 -2
- package/references/trust-kernel.md +3 -0
- package/references/truth-matrix.md +4 -0
- package/references/ueye-proof.md +51 -1
- package/references/ueye.md +27 -3
- package/skills/scout/SKILL.md +19 -9
- package/skills/ueye/SKILL.md +20 -3
- package/src/bin/yam.ts +603 -17
- package/src/lib/trust-kernel.ts +199 -7
- package/templates/ueye-comparison.md +42 -0
- package/templates/ueye-review.md +42 -0
- package/templates/yam.project.md +14 -0
package/src/lib/trust-kernel.ts
CHANGED
|
@@ -88,6 +88,30 @@ export interface UeyeSurfaceContext {
|
|
|
88
88
|
truth_status: TruthStatus;
|
|
89
89
|
}
|
|
90
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
|
+
|
|
91
115
|
export interface RollbackHint {
|
|
92
116
|
schema: 'yam.rollback-hint.v1';
|
|
93
117
|
touched_files: string[];
|
|
@@ -113,6 +137,14 @@ export interface RuntimeBackendEvidence {
|
|
|
113
137
|
evidence_id: string;
|
|
114
138
|
command: string;
|
|
115
139
|
cleanup_checked: boolean;
|
|
140
|
+
started_at: string;
|
|
141
|
+
stopped_at: string;
|
|
142
|
+
exit_code: number | null;
|
|
143
|
+
pid: number | null;
|
|
144
|
+
port: number | null;
|
|
145
|
+
cleanup_method: string;
|
|
146
|
+
cleanup_observed: boolean;
|
|
147
|
+
left_running_intentionally: boolean;
|
|
116
148
|
note: string;
|
|
117
149
|
truth_status: TruthStatus;
|
|
118
150
|
}
|
|
@@ -122,6 +154,7 @@ export interface UeyeRunReport {
|
|
|
122
154
|
reference_sources: UeyeVisualProvenance[];
|
|
123
155
|
implementation_sources: UeyeVisualProvenance[];
|
|
124
156
|
surface_context: UeyeSurfaceContext;
|
|
157
|
+
design_completion_gate: UeyeDesignCompletionGate;
|
|
125
158
|
comparison_result: string;
|
|
126
159
|
design_quality: string;
|
|
127
160
|
blocked_reason: string;
|
|
@@ -129,6 +162,10 @@ export interface UeyeRunReport {
|
|
|
129
162
|
truth_status: TruthStatus;
|
|
130
163
|
}
|
|
131
164
|
|
|
165
|
+
export interface UeyeRunReportInput extends Partial<Omit<UeyeRunReport, 'design_completion_gate'>> {
|
|
166
|
+
design_completion_gate?: Partial<UeyeDesignCompletionGate> & Record<string, unknown>;
|
|
167
|
+
}
|
|
168
|
+
|
|
132
169
|
export interface MediaGenerationProof {
|
|
133
170
|
schema: 'yam.media-generation-proof.v1';
|
|
134
171
|
tool_name: string;
|
|
@@ -171,6 +208,7 @@ export interface ProofSummary {
|
|
|
171
208
|
rollbackHint?: unknown;
|
|
172
209
|
runtimeBackendEvidence?: unknown;
|
|
173
210
|
mediaProof?: unknown;
|
|
211
|
+
designCompletion?: unknown;
|
|
174
212
|
}
|
|
175
213
|
|
|
176
214
|
export interface ProofOptions {
|
|
@@ -206,6 +244,7 @@ export interface YamCompletionProof {
|
|
|
206
244
|
rollbackHint: string[];
|
|
207
245
|
runtimeBackendEvidence: string[];
|
|
208
246
|
mediaProof: string[];
|
|
247
|
+
designCompletion: string[];
|
|
209
248
|
cleanup: unknown;
|
|
210
249
|
changed: string[];
|
|
211
250
|
skipped: string[];
|
|
@@ -262,6 +301,94 @@ export function buildUeyeSurfaceContext(input: Partial<UeyeSurfaceContext> = {})
|
|
|
262
301
|
};
|
|
263
302
|
}
|
|
264
303
|
|
|
304
|
+
export function buildUeyeDesignCompletionGate(input: Partial<UeyeDesignCompletionGate> & Record<string, unknown> = {}): UeyeDesignCompletionGate {
|
|
305
|
+
const completionClaim = normalizeUeyeCompletionClaim(input.completion_claim);
|
|
306
|
+
const mode = String(input.mode || '').toLowerCase() === 'strict' || completionClaim === 'done' ? 'strict' : 'fast';
|
|
307
|
+
const designScore = numberOrNull(input.design_score);
|
|
308
|
+
const minDesignScore = numberOrNull(input.min_design_score) ?? 8;
|
|
309
|
+
const p0 = asList(input.p0);
|
|
310
|
+
const p1 = asList(input.p1);
|
|
311
|
+
const hasReference = Boolean(input.has_reference);
|
|
312
|
+
const hasImplementation = Boolean(input.has_implementation_screenshot);
|
|
313
|
+
const comparisonResult = String(input.comparison_result || 'not-verified');
|
|
314
|
+
const designQuality = String(input.design_quality || 'not-checked');
|
|
315
|
+
const blockedReason = String(input.blocked_reason || '');
|
|
316
|
+
const strictOrDone = mode === 'strict' || completionClaim === 'done';
|
|
317
|
+
const checks: UeyeDesignGateCheck[] = [
|
|
318
|
+
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'),
|
|
319
|
+
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'),
|
|
320
|
+
designGateCheck('implementation_screenshot', 'Real implementation screenshot or screen evidence exists', hasImplementation ? 'pass' : 'fail', strictOrDone, 'capture or provide implementation screenshot before claiming done'),
|
|
321
|
+
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'),
|
|
322
|
+
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'),
|
|
323
|
+
designGateCheck('p0_clear', 'No P0 visual blockers remain', p0.length ? 'fail' : 'pass', true, 'fix P0 blockers before any done claim'),
|
|
324
|
+
designGateCheck('p1_clear', 'No P1 major visual issues remain', p1.length ? 'fail' : 'pass', strictOrDone, 'fix or explicitly defer P1 issues before claiming done'),
|
|
325
|
+
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'),
|
|
326
|
+
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'),
|
|
327
|
+
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'),
|
|
328
|
+
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')
|
|
329
|
+
];
|
|
330
|
+
if (designScore !== null || strictOrDone) {
|
|
331
|
+
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`));
|
|
332
|
+
}
|
|
333
|
+
const blockers = [
|
|
334
|
+
...p0.map((item) => `P0: ${item}`),
|
|
335
|
+
...(blockedReason ? [blockedReason] : []),
|
|
336
|
+
...checks
|
|
337
|
+
.filter((check) => check.required && check.status !== 'pass')
|
|
338
|
+
.map((check) => `${check.id}: ${check.next_action}`)
|
|
339
|
+
];
|
|
340
|
+
const warnings = [
|
|
341
|
+
...p1.map((item) => `P1: ${item}`),
|
|
342
|
+
...checks
|
|
343
|
+
.filter((check) => !check.required && ['fail', 'warning', 'not_checked'].includes(check.status))
|
|
344
|
+
.map((check) => `${check.id}: ${check.next_action}`)
|
|
345
|
+
];
|
|
346
|
+
const ready = completionClaim === 'done' && blockers.length === 0;
|
|
347
|
+
const truth: TruthStatus = blockers.some((item) => item.startsWith('P0:')) || blockedReason ? 'blocked'
|
|
348
|
+
: ready ? 'verified'
|
|
349
|
+
: strictOrDone ? 'partial'
|
|
350
|
+
: hasImplementation ? 'partial'
|
|
351
|
+
: 'assumed';
|
|
352
|
+
return {
|
|
353
|
+
schema: 'yam.ueye-design-completion-gate.v1',
|
|
354
|
+
mode,
|
|
355
|
+
completion_claim: completionClaim,
|
|
356
|
+
ready_to_claim_done: ready,
|
|
357
|
+
design_score: designScore,
|
|
358
|
+
min_design_score: minDesignScore,
|
|
359
|
+
checks,
|
|
360
|
+
p0,
|
|
361
|
+
p1,
|
|
362
|
+
warnings,
|
|
363
|
+
blockers,
|
|
364
|
+
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'),
|
|
365
|
+
truth_status: truth
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function normalizeUeyeCompletionClaim(value: unknown = ''): UeyeDesignCompletionGate['completion_claim'] {
|
|
370
|
+
const text = String(value || '').toLowerCase();
|
|
371
|
+
if (text === 'done' || text === 'complete' || text === 'completed') return 'done';
|
|
372
|
+
if (text === 'needs-polish' || text === 'needs_polish' || text === 'polish') return 'needs-polish';
|
|
373
|
+
return 'draft';
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function designGateCheck(id: string, label: string, status: UeyeDesignGateCheck['status'], required: boolean, nextAction: string): UeyeDesignGateCheck {
|
|
377
|
+
return {
|
|
378
|
+
id,
|
|
379
|
+
label,
|
|
380
|
+
status,
|
|
381
|
+
required,
|
|
382
|
+
next_action: nextAction
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function numberOrNull(value: unknown = null): number | null {
|
|
387
|
+
if (value === undefined || value === null || value === '') return null;
|
|
388
|
+
const number = Number(value);
|
|
389
|
+
return Number.isFinite(number) ? number : null;
|
|
390
|
+
}
|
|
391
|
+
|
|
265
392
|
export function buildRollbackHint(input: Partial<RollbackHint> = {}): RollbackHint {
|
|
266
393
|
return {
|
|
267
394
|
schema: 'yam.rollback-hint.v1',
|
|
@@ -290,6 +417,13 @@ export function buildMissionPatchEnvelope(input: Partial<MissionPatchEnvelope> =
|
|
|
290
417
|
export function buildRuntimeBackendEvidence(input: Partial<RuntimeBackendEvidence> = {}): RuntimeBackendEvidence {
|
|
291
418
|
const backend = normalizeRuntimeBackend(input.backend);
|
|
292
419
|
const claim = normalizeRuntimeClaim(input.claim);
|
|
420
|
+
const cleanupObserved = Boolean(input.cleanup_observed);
|
|
421
|
+
const leftRunningIntentionally = Boolean(input.left_running_intentionally);
|
|
422
|
+
const exitCode = numberOrNull(input.exit_code);
|
|
423
|
+
const pid = numberOrNull(input.pid);
|
|
424
|
+
const port = numberOrNull(input.port);
|
|
425
|
+
const stoppedAt = String(input.stopped_at || '');
|
|
426
|
+
const cleanupMethod = String(input.cleanup_method || '');
|
|
293
427
|
return {
|
|
294
428
|
schema: 'yam.runtime-backend-evidence.v1',
|
|
295
429
|
backend,
|
|
@@ -297,12 +431,28 @@ export function buildRuntimeBackendEvidence(input: Partial<RuntimeBackendEvidenc
|
|
|
297
431
|
evidence_id: String(input.evidence_id || ''),
|
|
298
432
|
command: String(input.command || ''),
|
|
299
433
|
cleanup_checked: Boolean(input.cleanup_checked),
|
|
434
|
+
started_at: String(input.started_at || ''),
|
|
435
|
+
stopped_at: stoppedAt,
|
|
436
|
+
exit_code: exitCode,
|
|
437
|
+
pid,
|
|
438
|
+
port,
|
|
439
|
+
cleanup_method: cleanupMethod,
|
|
440
|
+
cleanup_observed: cleanupObserved,
|
|
441
|
+
left_running_intentionally: leftRunningIntentionally,
|
|
300
442
|
note: String(input.note || ''),
|
|
301
|
-
truth_status: isTruthStatus(input.truth_status) ? input.truth_status : runtimeBackendTruth(backend, claim,
|
|
443
|
+
truth_status: isTruthStatus(input.truth_status) ? input.truth_status : runtimeBackendTruth(backend, claim, {
|
|
444
|
+
cleanupChecked: Boolean(input.cleanup_checked),
|
|
445
|
+
cleanupObserved,
|
|
446
|
+
leftRunningIntentionally,
|
|
447
|
+
stoppedAt,
|
|
448
|
+
exitCode,
|
|
449
|
+
pid,
|
|
450
|
+
cleanupMethod
|
|
451
|
+
})
|
|
302
452
|
};
|
|
303
453
|
}
|
|
304
454
|
|
|
305
|
-
export function buildUeyeRunReport(input:
|
|
455
|
+
export function buildUeyeRunReport(input: UeyeRunReportInput = {}): UeyeRunReport {
|
|
306
456
|
const references = Array.isArray(input.reference_sources)
|
|
307
457
|
? input.reference_sources.map((item) => buildUeyeVisualProvenance(item))
|
|
308
458
|
: [];
|
|
@@ -317,19 +467,30 @@ export function buildUeyeRunReport(input: Partial<UeyeRunReport> = {}): UeyeRunR
|
|
|
317
467
|
: comparisonResult === 'matched' && hasImplementation ? 'verified'
|
|
318
468
|
: hasImplementation ? 'partial'
|
|
319
469
|
: 'partial';
|
|
470
|
+
const gate = buildUeyeDesignCompletionGate({
|
|
471
|
+
...input.design_completion_gate,
|
|
472
|
+
has_reference: references.length > 0,
|
|
473
|
+
has_implementation_screenshot: hasImplementation,
|
|
474
|
+
comparison_result: comparisonResult,
|
|
475
|
+
design_quality: String(input.design_quality || 'not-checked'),
|
|
476
|
+
blocked_reason: blockedReason
|
|
477
|
+
});
|
|
478
|
+
const shouldApplyDesignGate = gate.mode === 'strict' || gate.completion_claim === 'done' || gate.blockers.length > 0;
|
|
479
|
+
const finalTruth = shouldApplyDesignGate ? weakestTruth(derivedTruth, gate.truth_status) : derivedTruth;
|
|
320
480
|
return {
|
|
321
481
|
schema: 'yam.ueye-run-report.v1',
|
|
322
482
|
reference_sources: references,
|
|
323
483
|
implementation_sources: implementations,
|
|
324
484
|
surface_context: buildUeyeSurfaceContext({
|
|
325
485
|
...input.surface_context,
|
|
326
|
-
truth_status: isTruthStatus(input.surface_context?.truth_status) ? input.surface_context?.truth_status :
|
|
486
|
+
truth_status: isTruthStatus(input.surface_context?.truth_status) ? input.surface_context?.truth_status : finalTruth
|
|
327
487
|
}),
|
|
488
|
+
design_completion_gate: gate,
|
|
328
489
|
comparison_result: comparisonResult,
|
|
329
490
|
design_quality: String(input.design_quality || 'not-checked'),
|
|
330
491
|
blocked_reason: blockedReason,
|
|
331
|
-
next_action: String(input.next_action || (
|
|
332
|
-
truth_status: isTruthStatus(input.truth_status) ? input.truth_status :
|
|
492
|
+
next_action: String(input.next_action || gate.blockers[0] || (finalTruth === 'verified' ? 'no action required' : 'capture or provide implementation screenshot before claiming verified visual status')),
|
|
493
|
+
truth_status: isTruthStatus(input.truth_status) ? input.truth_status : finalTruth
|
|
333
494
|
};
|
|
334
495
|
}
|
|
335
496
|
|
|
@@ -444,6 +605,9 @@ export function classifyEvidenceTruth(summary: ProofSummary = {}, options: Proof
|
|
|
444
605
|
for (const media of asList(summary.mediaProof)) {
|
|
445
606
|
rows.push(evidenceRow('evidence', media, readStructuredTruth(media, 'partial')));
|
|
446
607
|
}
|
|
608
|
+
for (const designCompletion of asList(summary.designCompletion)) {
|
|
609
|
+
rows.push(evidenceRow('visual', designCompletion, readStructuredTruth(designCompletion, 'partial')));
|
|
610
|
+
}
|
|
447
611
|
for (const runtime of asList(summary.runtime)) {
|
|
448
612
|
rows.push(evidenceRow('runtime', runtime, classifyRuntimeEvidence(runtime, options)));
|
|
449
613
|
}
|
|
@@ -473,6 +637,14 @@ export function applyProofTruthCaps(summary: ProofSummary = {}, options: ProofOp
|
|
|
473
637
|
cappedTruth = weakestTruth(cappedTruth, 'partial');
|
|
474
638
|
unverified.push('real_visual_evidence_missing');
|
|
475
639
|
}
|
|
640
|
+
const designCompletionTruth = designCompletionCap(summary.designCompletion);
|
|
641
|
+
if (designCompletionTruth) {
|
|
642
|
+
cappedTruth = weakestTruth(cappedTruth, designCompletionTruth);
|
|
643
|
+
if (designCompletionTruth === 'blocked') blockers.push('ueye_design_completion_blocked');
|
|
644
|
+
if (!['verified', 'proven'].includes(designCompletionTruth)) {
|
|
645
|
+
unverified.push('ueye_design_completion_not_verified');
|
|
646
|
+
}
|
|
647
|
+
}
|
|
476
648
|
if (requested !== cappedTruth) {
|
|
477
649
|
caps.push(`requested ${requested} capped to ${cappedTruth} by evidence`);
|
|
478
650
|
}
|
|
@@ -532,6 +704,7 @@ export function buildYamCompletionProof(summary: ProofSummary = {}, options: Pro
|
|
|
532
704
|
rollbackHint: asList(summary.rollbackHint),
|
|
533
705
|
runtimeBackendEvidence: asList(summary.runtimeBackendEvidence),
|
|
534
706
|
mediaProof: asList(summary.mediaProof),
|
|
707
|
+
designCompletion: asList(summary.designCompletion),
|
|
535
708
|
cleanup: summary.cleanup || '',
|
|
536
709
|
changed: asList(summary.changed),
|
|
537
710
|
skipped: asList(summary.skipped),
|
|
@@ -601,6 +774,12 @@ function readStructuredTruth(value: unknown = '', fallback: TruthStatus = 'parti
|
|
|
601
774
|
}
|
|
602
775
|
}
|
|
603
776
|
|
|
777
|
+
function designCompletionCap(value: unknown = ''): TruthStatus | null {
|
|
778
|
+
const items = asList(value);
|
|
779
|
+
if (!items.length) return null;
|
|
780
|
+
return items.reduce<TruthStatus>((weakest, item) => weakestTruth(weakest, readStructuredTruth(item, 'partial')), 'proven');
|
|
781
|
+
}
|
|
782
|
+
|
|
604
783
|
function strongestSupportedTruth(rows: EvidenceRow[] = []): TruthStatus {
|
|
605
784
|
if (rows.some((row) => row.truth === 'blocked')) return 'blocked';
|
|
606
785
|
if (rows.some((row) => row.truth === 'real_required_missing')) return 'real_required_missing';
|
|
@@ -686,11 +865,24 @@ function normalizeRuntimeClaim(value: unknown = ''): RuntimeClaim {
|
|
|
686
865
|
return 'unknown';
|
|
687
866
|
}
|
|
688
867
|
|
|
689
|
-
function runtimeBackendTruth(backend: RuntimeBackend, claim: RuntimeClaim,
|
|
868
|
+
function runtimeBackendTruth(backend: RuntimeBackend, claim: RuntimeClaim, details: {
|
|
869
|
+
cleanupChecked?: boolean;
|
|
870
|
+
cleanupObserved?: boolean;
|
|
871
|
+
leftRunningIntentionally?: boolean;
|
|
872
|
+
stoppedAt?: string;
|
|
873
|
+
exitCode?: number | null;
|
|
874
|
+
pid?: number | null;
|
|
875
|
+
cleanupMethod?: string;
|
|
876
|
+
} = {}): TruthStatus {
|
|
690
877
|
if (claim === 'blocked') return 'blocked';
|
|
691
878
|
if (backend === 'none' || claim === 'not_started') return 'skipped';
|
|
692
879
|
if (backend === 'unknown' || claim === 'unknown') return 'partial';
|
|
693
|
-
|
|
880
|
+
const hasClosureEvidence = Boolean(details.stoppedAt || details.exitCode !== null || details.cleanupMethod);
|
|
881
|
+
if (claim === 'cleanup_verified' || details.cleanupChecked) {
|
|
882
|
+
if (details.cleanupObserved && hasClosureEvidence) return 'proven';
|
|
883
|
+
if (details.leftRunningIntentionally && (details.pid !== null || details.cleanupMethod)) return 'partial';
|
|
884
|
+
return 'real_required_missing';
|
|
885
|
+
}
|
|
694
886
|
if (claim === 'observed' || claim === 'stopped' || claim === 'started') return 'verified';
|
|
695
887
|
return 'partial';
|
|
696
888
|
}
|
|
@@ -112,6 +112,36 @@ Use `pass`, `needs-polish`, or `fails` for each relevant design dimension before
|
|
|
112
112
|
| Accessibility | needs-polish | |
|
|
113
113
|
| Brand/mood fit | needs-polish | |
|
|
114
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
|
+
|
|
115
145
|
### P0 Blockers
|
|
116
146
|
|
|
117
147
|
- None.
|
|
@@ -152,6 +182,18 @@ Use `pass`, `needs-polish`, or `fails` for each relevant design dimension before
|
|
|
152
182
|
"preserved_url": "",
|
|
153
183
|
"truth_status": "partial"
|
|
154
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
|
+
},
|
|
155
197
|
"viewport": "",
|
|
156
198
|
"state": "",
|
|
157
199
|
"comparison_result": "not-verified",
|
package/templates/ueye-review.md
CHANGED
|
@@ -123,6 +123,36 @@ Status values: matched / similar / different / not-verified / not-applicable.
|
|
|
123
123
|
|
|
124
124
|
Result values: pass / needs-polish / fails.
|
|
125
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
|
+
|
|
126
156
|
## P0-P3 Issues
|
|
127
157
|
|
|
128
158
|
### P0 Blockers
|
|
@@ -184,6 +214,18 @@ Result values: pass / needs-polish / fails.
|
|
|
184
214
|
"preserved_url": "",
|
|
185
215
|
"truth_status": "partial"
|
|
186
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
|
+
},
|
|
187
229
|
"viewport": "",
|
|
188
230
|
"state": "",
|
|
189
231
|
"comparison_result": "not-verified",
|
package/templates/yam.project.md
CHANGED
|
@@ -46,6 +46,20 @@
|
|
|
46
46
|
- Risky changes:
|
|
47
47
|
- Public/release changes: scan for external tool names, comparison wording, and attribution wording; remove those hits unless the user explicitly approves keeping them.
|
|
48
48
|
|
|
49
|
+
## Security Policy
|
|
50
|
+
|
|
51
|
+
- Sensitive surfaces:
|
|
52
|
+
- Secrets/env handling:
|
|
53
|
+
- Auth/payment/DB policy:
|
|
54
|
+
- Deployment/release policy:
|
|
55
|
+
- Package/dependency policy:
|
|
56
|
+
|
|
57
|
+
## Report Policy
|
|
58
|
+
|
|
59
|
+
- Explain changed code in plain language:
|
|
60
|
+
- Always include remaining tasks or useful improvements:
|
|
61
|
+
- Preserve source boundaries for research/proof notes:
|
|
62
|
+
|
|
49
63
|
## Known Risks
|
|
50
64
|
|
|
51
65
|
- Auth/payment/DB/security:
|