yam-flow 0.1.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.
Files changed (52) hide show
  1. package/AGENTS.md +18 -0
  2. package/COMMANDS.md +152 -0
  3. package/DECISIONS.md +70 -0
  4. package/LICENSE +21 -0
  5. package/README.md +174 -0
  6. package/ROADMAP.md +313 -0
  7. package/dist/bin/yam.d.ts +2 -0
  8. package/dist/bin/yam.js +2005 -0
  9. package/dist/lib/trust-kernel.d.ts +99 -0
  10. package/dist/lib/trust-kernel.js +300 -0
  11. package/package.json +101 -0
  12. package/references/context-reuse.md +59 -0
  13. package/references/current-docs.md +45 -0
  14. package/references/db-supabase-safety-lite.md +40 -0
  15. package/references/doctor-scan.md +56 -0
  16. package/references/eye.md +30 -0
  17. package/references/final-report.md +61 -0
  18. package/references/honest-completion.md +61 -0
  19. package/references/hook-lite.md +55 -0
  20. package/references/markdown-management.md +56 -0
  21. package/references/memory.md +59 -0
  22. package/references/mission.md +86 -0
  23. package/references/question.md +25 -0
  24. package/references/quick.md +70 -0
  25. package/references/risk-escalation.md +27 -0
  26. package/references/runtime-orchestration.md +57 -0
  27. package/references/scout.md +38 -0
  28. package/references/token-budget-reporter.md +44 -0
  29. package/references/token-economy.md +61 -0
  30. package/references/tool-trust-layer.md +115 -0
  31. package/references/trust-kernel.md +55 -0
  32. package/references/truth-matrix.md +47 -0
  33. package/references/ueye-proof.md +109 -0
  34. package/references/ueye.md +174 -0
  35. package/references/ui-quality.md +23 -0
  36. package/references/verification-levels.md +53 -0
  37. package/skills/deep/SKILL.md +77 -0
  38. package/skills/mission/SKILL.md +105 -0
  39. package/skills/question/SKILL.md +45 -0
  40. package/skills/quick/SKILL.md +81 -0
  41. package/skills/scout/SKILL.md +71 -0
  42. package/skills/ueye/SKILL.md +132 -0
  43. package/src/bin/yam.ts +1988 -0
  44. package/src/lib/trust-kernel.ts +398 -0
  45. package/templates/mission-plan.md +46 -0
  46. package/templates/runtime-proof.md +54 -0
  47. package/templates/tuning-log.md +39 -0
  48. package/templates/ueye-comparison.md +78 -0
  49. package/templates/ueye-review.md +110 -0
  50. package/templates/yam.project.md +73 -0
  51. package/tsconfig.json +27 -0
  52. package/yam.manifest.json +48 -0
@@ -0,0 +1,398 @@
1
+ export const TRUTH_STATUSES = Object.freeze([
2
+ 'verified',
3
+ 'proven',
4
+ 'partial',
5
+ 'fixture_only',
6
+ 'fixture_instrumented_real',
7
+ 'integration_optional',
8
+ 'real_required_missing',
9
+ 'skipped',
10
+ 'blocked',
11
+ 'assumed'
12
+ ] as const);
13
+
14
+ export type TruthStatus = (typeof TRUTH_STATUSES)[number];
15
+ export type SafetyLevel = 'danger' | 'warning';
16
+ export type EvidenceKind = 'command' | 'evidence' | 'visual' | 'runtime' | 'skipped' | 'blocked' | 'assumption' | 'cleanup' | 'none';
17
+ export type RuntimeSubsystem = 'real_runtime' | 'tmux_physical' | 'process_cleanup' | 'browser_visual' | 'db_safety';
18
+
19
+ export interface SafetyHit {
20
+ level: SafetyLevel;
21
+ reason: string;
22
+ }
23
+
24
+ export interface DbSafetyScanResult {
25
+ hits: SafetyHit[];
26
+ recommendation: '$deep' | '$quick or current route';
27
+ truth: TruthStatus;
28
+ }
29
+
30
+ export interface EvidenceRow {
31
+ kind: EvidenceKind;
32
+ value: string;
33
+ truth: TruthStatus;
34
+ }
35
+
36
+ export interface RuntimeTruthRow {
37
+ subsystem: RuntimeSubsystem;
38
+ proof_level: TruthStatus;
39
+ required: boolean;
40
+ next_action: string;
41
+ }
42
+
43
+ export interface RuntimeTruthMatrix {
44
+ schema: 'yam.runtime-truth-matrix.v1';
45
+ ok: boolean;
46
+ rows: RuntimeTruthRow[];
47
+ blockers: string[];
48
+ }
49
+
50
+ export interface FakeRealPolicyResult {
51
+ schema: 'yam.fake-real-policy.v1';
52
+ ok: boolean;
53
+ proof_level: TruthStatus;
54
+ fake_claims: string[];
55
+ real_claims: string[];
56
+ blockers: string[];
57
+ }
58
+
59
+ export interface ProofSummary {
60
+ route?: unknown;
61
+ goal?: unknown;
62
+ truth?: unknown;
63
+ source?: unknown;
64
+ commands?: unknown;
65
+ evidence?: unknown;
66
+ visual?: unknown;
67
+ runtime?: unknown;
68
+ cleanup?: unknown;
69
+ changed?: unknown;
70
+ skipped?: unknown;
71
+ blocked?: unknown;
72
+ assumptions?: unknown;
73
+ unverified?: unknown;
74
+ }
75
+
76
+ export interface ProofOptions {
77
+ requireRealRuntime?: boolean;
78
+ requireVisual?: boolean;
79
+ requireTmux?: boolean;
80
+ }
81
+
82
+ export interface ProofTruthCaps {
83
+ truth: TruthStatus;
84
+ requestedTruth: TruthStatus;
85
+ evidenceRows: EvidenceRow[];
86
+ caps: string[];
87
+ blockers: string[];
88
+ unverified: string[];
89
+ fakeReal: FakeRealPolicyResult;
90
+ }
91
+
92
+ export interface YamCompletionProof {
93
+ schema: 'yam.completion-proof.v1';
94
+ generatedAt: string;
95
+ route: unknown;
96
+ goal: unknown;
97
+ truth: TruthStatus;
98
+ requestedTruth: TruthStatus;
99
+ source: unknown;
100
+ commands: string[];
101
+ evidence: string[];
102
+ visual: string[];
103
+ runtime: string[];
104
+ cleanup: unknown;
105
+ changed: string[];
106
+ skipped: string[];
107
+ blocked: string[];
108
+ assumptions: string[];
109
+ unverified: string[];
110
+ truthCaps: string[];
111
+ evidenceRows: EvidenceRow[];
112
+ fakeReal: FakeRealPolicyResult;
113
+ runtimeTruth: RuntimeTruthMatrix;
114
+ }
115
+
116
+ const TRUTH_RANK: Readonly<Record<TruthStatus, number>> = Object.freeze({
117
+ blocked: 0,
118
+ real_required_missing: 0,
119
+ skipped: 1,
120
+ assumed: 1,
121
+ fixture_only: 2,
122
+ integration_optional: 2,
123
+ fixture_instrumented_real: 3,
124
+ partial: 3,
125
+ verified: 4,
126
+ proven: 5
127
+ });
128
+
129
+ export function isTruthStatus(value: unknown = ''): value is TruthStatus {
130
+ return (TRUTH_STATUSES as readonly string[]).includes(String(value || ''));
131
+ }
132
+
133
+ export function weakestTruth(...statuses: unknown[]): TruthStatus {
134
+ const valid = statuses.filter(isTruthStatus);
135
+ if (!valid.length) return 'assumed';
136
+ return valid.reduce((weakest, status) => {
137
+ return TRUTH_RANK[status] < TRUTH_RANK[weakest] ? status : weakest;
138
+ }, valid[0]);
139
+ }
140
+
141
+ export function detectDbSafetyText(text: unknown = ''): DbSafetyScanResult {
142
+ const value = String(text || '');
143
+ const hits: SafetyHit[] = [];
144
+ const checks: Array<[SafetyLevel, RegExp, string]> = [
145
+ ['danger', /\bdrop\s+(table|schema|database|view|index)\b/i, 'DROP statement can destroy database objects'],
146
+ ['danger', /\btruncate\s+(table\s+)?[a-z0-9_".]+/i, 'TRUNCATE statement can destroy table data'],
147
+ ['danger', /\bdelete\s+from\s+[a-z0-9_".]+/i, 'DELETE FROM can destroy row data'],
148
+ ['danger', /\bupdate\s+[a-z0-9_".]+\s+set\b/i, 'UPDATE can mutate row data'],
149
+ ['warning', /\balter\s+table\s+[a-z0-9_".]+/i, 'ALTER TABLE can change schema or lock production data'],
150
+ ['danger', /\bsupabase\s+db\s+(reset|push)\b/i, 'supabase db reset/push can mutate database state'],
151
+ ['warning', /\bsupabase\s+(migration|migrations|db\s+diff|db\s+pull)\b/i, 'Supabase migration/db command needs explicit environment awareness'],
152
+ ['danger', /\b(prisma\s+migrate\s+(deploy|reset|dev)|drizzle-kit\s+(push|drop|migrate)|knex\s+migrate|sequelize\s+db:migrate)\b/i, 'ORM migration command can mutate schema/data'],
153
+ ['danger', /\bpsql\b[\s\S]{0,160}\b(drop|truncate|delete\s+from|update\s+[a-z0-9_".]+\s+set|alter\s+table)\b/i, 'psql command contains destructive SQL'],
154
+ ['warning', /\b(create\s+policy|alter\s+policy|drop\s+policy|grant\s+|revoke\s+)/i, 'RLS/policy/permission change affects data access safety']
155
+ ];
156
+ for (const [level, pattern, reason] of checks) {
157
+ if (pattern.test(value)) hits.push({ level, reason });
158
+ }
159
+ const productionSignal = /\b(prod|production|live|remote|linked|service[_-]?role|database_url|--db-url|--linked|--remote|--project-ref)\b/i.test(value);
160
+ if (productionSignal) hits.push({ level: 'warning', reason: 'production/remote credential or environment signal detected' });
161
+ const unique: SafetyHit[] = [];
162
+ const seen = new Set<string>();
163
+ for (const hit of hits) {
164
+ const key = `${hit.level}:${hit.reason}`;
165
+ if (seen.has(key)) continue;
166
+ seen.add(key);
167
+ unique.push(hit);
168
+ }
169
+ return {
170
+ hits: unique,
171
+ recommendation: unique.length ? '$deep' : '$quick or current route',
172
+ truth: 'assumed'
173
+ };
174
+ }
175
+
176
+ export function classifyEvidenceTruth(summary: ProofSummary = {}, options: ProofOptions = {}): EvidenceRow[] {
177
+ const rows: EvidenceRow[] = [];
178
+ for (const command of asList(summary.commands)) {
179
+ rows.push(evidenceRow('command', command, commandPassed(command) ? 'verified' : 'partial'));
180
+ }
181
+ for (const evidence of asList(summary.evidence)) {
182
+ rows.push(evidenceRow('evidence', evidence, classifyTextEvidence(evidence)));
183
+ }
184
+ for (const visual of asList(summary.visual)) {
185
+ rows.push(evidenceRow('visual', visual, classifyVisualEvidence(visual)));
186
+ }
187
+ for (const runtime of asList(summary.runtime)) {
188
+ rows.push(evidenceRow('runtime', runtime, classifyRuntimeEvidence(runtime, options)));
189
+ }
190
+ for (const skipped of asList(summary.skipped)) rows.push(evidenceRow('skipped', skipped, 'skipped'));
191
+ for (const blocked of asList(summary.blocked)) rows.push(evidenceRow('blocked', blocked, 'blocked'));
192
+ for (const assumption of asList(summary.assumptions)) rows.push(evidenceRow('assumption', assumption, 'assumed'));
193
+ if (summary.cleanup) rows.push(evidenceRow('cleanup', summary.cleanup, classifyCleanupEvidence(summary.cleanup)));
194
+ if (!rows.length) rows.push(evidenceRow('none', 'no evidence supplied', 'assumed'));
195
+ return rows;
196
+ }
197
+
198
+ export function applyProofTruthCaps(summary: ProofSummary = {}, options: ProofOptions = {}): ProofTruthCaps {
199
+ const evidenceRows = classifyEvidenceTruth(summary, options);
200
+ const blockers: string[] = [];
201
+ const unverified: string[] = [];
202
+ const caps: string[] = [];
203
+ const requested = isTruthStatus(summary.truth) ? summary.truth : 'assumed';
204
+ const evidenceCap = strongestSupportedTruth(evidenceRows);
205
+ let cappedTruth = weakestTruth(requested, evidenceCap);
206
+
207
+ if (asList(summary.blocked).length) cappedTruth = 'blocked';
208
+ if (options.requireRealRuntime && !hasRuntimeProof(evidenceRows)) {
209
+ cappedTruth = 'real_required_missing';
210
+ blockers.push('real_runtime_required_missing');
211
+ }
212
+ if (options.requireVisual && !hasRealVisualProof(evidenceRows)) {
213
+ cappedTruth = weakestTruth(cappedTruth, 'partial');
214
+ unverified.push('real_visual_evidence_missing');
215
+ }
216
+ if (requested !== cappedTruth) {
217
+ caps.push(`requested ${requested} capped to ${cappedTruth} by evidence`);
218
+ }
219
+ const fakeReal = evaluateFakeRealPolicy({ summary, evidenceRows, options });
220
+ if (fakeReal.blockers.length) {
221
+ cappedTruth = weakestTruth(cappedTruth, fakeReal.proof_level);
222
+ blockers.push(...fakeReal.blockers);
223
+ }
224
+ return {
225
+ truth: cappedTruth,
226
+ requestedTruth: requested,
227
+ evidenceRows,
228
+ caps,
229
+ blockers: uniqueStrings(blockers),
230
+ unverified: uniqueStrings(unverified),
231
+ fakeReal
232
+ };
233
+ }
234
+
235
+ export function buildRuntimeTruthMatrix(summary: ProofSummary = {}, options: ProofOptions = {}): RuntimeTruthMatrix {
236
+ const evidenceRows = classifyEvidenceTruth(summary, options);
237
+ const rows = [
238
+ runtimeRow('real_runtime', hasRuntimeProof(evidenceRows) ? 'proven' : options.requireRealRuntime ? 'real_required_missing' : 'integration_optional', options.requireRealRuntime),
239
+ runtimeRow('tmux_physical', hasText(asList(summary.runtime), /tmux/i) ? runtimeLevelFor(evidenceRows, /tmux/i, options.requireTmux) : options.requireTmux ? 'real_required_missing' : 'integration_optional', options.requireTmux),
240
+ runtimeRow('process_cleanup', summary.cleanup ? classifyCleanupEvidence(summary.cleanup) : 'integration_optional', false),
241
+ runtimeRow('browser_visual', hasRealVisualProof(evidenceRows) ? 'verified' : options.requireVisual ? 'real_required_missing' : 'integration_optional', options.requireVisual),
242
+ runtimeRow('db_safety', asList(summary.evidence).some((item) => /db[_ -]?safety|supabase|database/i.test(String(item))) ? 'partial' : 'integration_optional', false)
243
+ ];
244
+ const blockers = rows
245
+ .filter((row) => row.required && ['blocked', 'real_required_missing', 'integration_optional'].includes(row.proof_level))
246
+ .map((row) => `${row.subsystem}_required_missing`);
247
+ return {
248
+ schema: 'yam.runtime-truth-matrix.v1',
249
+ ok: blockers.length === 0,
250
+ rows,
251
+ blockers
252
+ };
253
+ }
254
+
255
+ export function buildYamCompletionProof(summary: ProofSummary = {}, options: ProofOptions = {}): YamCompletionProof {
256
+ const capped = applyProofTruthCaps(summary, options);
257
+ const runtimeTruth = buildRuntimeTruthMatrix(summary, options);
258
+ return {
259
+ schema: 'yam.completion-proof.v1',
260
+ generatedAt: new Date().toISOString(),
261
+ route: summary.route || 'unspecified',
262
+ goal: summary.goal || '',
263
+ truth: capped.truth,
264
+ requestedTruth: capped.requestedTruth,
265
+ source: summary.source || '',
266
+ commands: asList(summary.commands),
267
+ evidence: asList(summary.evidence),
268
+ visual: asList(summary.visual),
269
+ runtime: asList(summary.runtime),
270
+ cleanup: summary.cleanup || '',
271
+ changed: asList(summary.changed),
272
+ skipped: asList(summary.skipped),
273
+ blocked: uniqueStrings([...asList(summary.blocked), ...capped.blockers]),
274
+ assumptions: asList(summary.assumptions),
275
+ unverified: uniqueStrings([...asList(summary.unverified), ...capped.unverified]),
276
+ truthCaps: capped.caps,
277
+ evidenceRows: capped.evidenceRows,
278
+ fakeReal: capped.fakeReal,
279
+ runtimeTruth
280
+ };
281
+ }
282
+
283
+ function classifyTextEvidence(value: unknown = ''): TruthStatus {
284
+ const text = String(value || '');
285
+ if (/mock|fixture|stub|fake/i.test(text)) return 'fixture_only';
286
+ if (/browser|screenshot|playwright|test.*pass|passed|build.*pass|typecheck.*pass|lint.*pass|verified/i.test(text)) return 'verified';
287
+ if (/blocked|failed|error/i.test(text)) return 'blocked';
288
+ if (/read|inspect|review|inferred|assumed|source/i.test(text)) return 'assumed';
289
+ return 'partial';
290
+ }
291
+
292
+ function classifyVisualEvidence(value: unknown = ''): TruthStatus {
293
+ const text = String(value || '');
294
+ if (/blocked|unavailable|could not|missing/i.test(text)) return 'blocked';
295
+ if (/reference[-_ ]?only|reference image|generated|annotation|mock|fixture|text[-_ ]?only|code[-_ ]?only/i.test(text)) return 'partial';
296
+ if (/browser|screenshot|screen capture|viewport|mobile|desktop|playwright|chrome/i.test(text)) return 'verified';
297
+ return 'partial';
298
+ }
299
+
300
+ function classifyRuntimeEvidence(value: unknown = '', options: ProofOptions = {}): TruthStatus {
301
+ const text = String(value || '');
302
+ if (/blocked|missing|unavailable|failed/i.test(text)) return options.requireRealRuntime ? 'real_required_missing' : 'blocked';
303
+ if (/fixture|mock|fake/i.test(text)) return 'fixture_only';
304
+ if (/tmux|pid|process|port|server|watcher|browser qa|exit verified|closed|cleanup verified/i.test(text)) return 'proven';
305
+ return 'partial';
306
+ }
307
+
308
+ function classifyCleanupEvidence(value: unknown = ''): TruthStatus {
309
+ const text = String(value || '');
310
+ if (/exit verified|closed|stopped|no runtime started|not started|intentionally left running/i.test(text)) return 'proven';
311
+ if (/not checked|unknown|assumed/i.test(text)) return 'assumed';
312
+ if (/blocked|failed|missing/i.test(text)) return 'blocked';
313
+ return 'partial';
314
+ }
315
+
316
+ function commandPassed(value: unknown = ''): boolean {
317
+ return /pass|passed|ok|success|exit\s*0|green/i.test(String(value || '')) && !/fail|failed|error|blocked/i.test(String(value || ''));
318
+ }
319
+
320
+ function strongestSupportedTruth(rows: EvidenceRow[] = []): TruthStatus {
321
+ if (rows.some((row) => row.truth === 'blocked')) return 'blocked';
322
+ if (rows.some((row) => row.truth === 'real_required_missing')) return 'real_required_missing';
323
+ if (rows.some((row) => row.truth === 'fixture_only')) return 'fixture_only';
324
+ if (rows.some((row) => row.truth === 'proven')) return 'proven';
325
+ if (rows.some((row) => row.truth === 'verified')) return 'verified';
326
+ if (rows.some((row) => row.truth === 'partial')) return 'partial';
327
+ if (rows.some((row) => row.truth === 'skipped')) return 'skipped';
328
+ return 'assumed';
329
+ }
330
+
331
+ interface FakeRealPolicyInput {
332
+ summary?: ProofSummary;
333
+ evidenceRows?: EvidenceRow[];
334
+ options?: ProofOptions;
335
+ }
336
+
337
+ function evaluateFakeRealPolicy({ summary = {}, evidenceRows = [], options = {} }: FakeRealPolicyInput): FakeRealPolicyResult {
338
+ const fakeClaims = evidenceRows.filter((row) => ['fixture_only'].includes(row.truth)).map((row) => `${row.kind}:${row.value}`);
339
+ const realClaims = evidenceRows.filter((row) => ['verified', 'proven'].includes(row.truth)).map((row) => `${row.kind}:${row.value}`);
340
+ const blockers: string[] = [];
341
+ if (options.requireRealRuntime && !hasRuntimeProof(evidenceRows)) blockers.push('real_runtime_required_missing');
342
+ if (summary.truth === 'verified' && fakeClaims.length && !realClaims.length) blockers.push('fixture_or_fake_evidence_cannot_verify_real_status');
343
+ const proofLevel: TruthStatus = blockers.length ? 'real_required_missing'
344
+ : fakeClaims.length && !realClaims.length ? 'fixture_only'
345
+ : realClaims.some((claim) => claim.startsWith('runtime:') || claim.startsWith('cleanup:')) ? 'proven'
346
+ : realClaims.length ? 'verified'
347
+ : 'assumed';
348
+ return {
349
+ schema: 'yam.fake-real-policy.v1',
350
+ ok: blockers.length === 0,
351
+ proof_level: proofLevel,
352
+ fake_claims: fakeClaims,
353
+ real_claims: realClaims,
354
+ blockers
355
+ };
356
+ }
357
+
358
+ function hasRuntimeProof(rows: EvidenceRow[] = []): boolean {
359
+ return rows.some((row) => (row.kind === 'runtime' || row.kind === 'cleanup') && ['proven', 'verified'].includes(row.truth));
360
+ }
361
+
362
+ function hasRealVisualProof(rows: EvidenceRow[] = []): boolean {
363
+ return rows.some((row) => row.kind === 'visual' && row.truth === 'verified');
364
+ }
365
+
366
+ function runtimeLevelFor(rows: EvidenceRow[] = [], pattern: RegExp, required = false): TruthStatus {
367
+ const matching = rows.filter((row) => row.kind === 'runtime' && pattern.test(row.value));
368
+ if (!matching.length) return required ? 'real_required_missing' : 'integration_optional';
369
+ return strongestSupportedTruth(matching);
370
+ }
371
+
372
+ function runtimeRow(subsystem: RuntimeSubsystem, proofLevel: TruthStatus, required?: boolean): RuntimeTruthRow {
373
+ return {
374
+ subsystem,
375
+ proof_level: proofLevel,
376
+ required: Boolean(required),
377
+ next_action: proofLevel === 'integration_optional' || proofLevel === 'real_required_missing'
378
+ ? `collect ${subsystem} evidence when the claim requires it`
379
+ : 'no action required'
380
+ };
381
+ }
382
+
383
+ function evidenceRow(kind: EvidenceKind, value: unknown, truth: TruthStatus): EvidenceRow {
384
+ return { kind, value: String(value || ''), truth };
385
+ }
386
+
387
+ function hasText(values: unknown[] = [], pattern: RegExp): boolean {
388
+ return values.some((value) => pattern.test(String(value || '')));
389
+ }
390
+
391
+ function asList(value?: unknown): string[] {
392
+ if (!value) return [];
393
+ return Array.isArray(value) ? value.filter(Boolean).map(String) : [String(value)].filter(Boolean);
394
+ }
395
+
396
+ function uniqueStrings(values: unknown[] = []): string[] {
397
+ return [...new Set(values.filter(Boolean).map(String))];
398
+ }
@@ -0,0 +1,46 @@
1
+ # yam Mission Prompt
2
+
3
+ ```text
4
+ $mission
5
+ 아래 구현 계획은 확정됐어.
6
+
7
+ 목표:
8
+ -
9
+
10
+ 범위:
11
+ -
12
+
13
+ 금지사항:
14
+ -
15
+
16
+ Acceptance criteria:
17
+ -
18
+
19
+ 역할:
20
+ - Implementer: 범위 안에서 구현
21
+ - Reviewer: 코드/구조/리스크/방향성 검토
22
+ - UX/browser verifier: 화면/상태/브라우저 흐름 확인
23
+ - Doctor/scanner: stale context, 과검증/검증부족, false-completion risk, cleanup, 남은 fix-first 점검
24
+
25
+ Subagent 판단:
26
+ - 실제 subagent/team 사용 가능 여부:
27
+ - meaningful split:
28
+ - decision: used / downgraded_to_deep / unavailable_partial / blocked
29
+ - 이유:
30
+ - subagent가 불가능하거나 불필요하면 기본적으로 $deep으로 전환:
31
+
32
+ 검증:
33
+ - 필요한 가장 작은 검증 명령을 우선 실행
34
+ - 필요하면 tmux/dev server/browser QA/process cleanup proof 사용
35
+ - 검증하지 못한 것은 skipped/blocked/assumed로 명확히 보고
36
+
37
+ 최종 보고:
38
+ - 구현 요약
39
+ - 역할별 교차 검증 결과
40
+ - subagent decision
41
+ - 실제 evidence
42
+ - truth status
43
+ - cleanup status
44
+ - fix-first items
45
+ - remaining tasks
46
+ ```
@@ -0,0 +1,54 @@
1
+ # yam Deep/Mission Runtime Proof Summary
2
+
3
+ ## Goal
4
+
5
+ -
6
+
7
+ ## Plan
8
+
9
+ -
10
+
11
+ ## Processes
12
+
13
+ - Command:
14
+ - PID/session/pane:
15
+ - Port:
16
+ - Started:
17
+ - Stopped:
18
+ - Exit/closure verified:
19
+
20
+ ## tmux
21
+
22
+ - Used: yes / no
23
+ - Session:
24
+ - Pane:
25
+ - Before-drain observation:
26
+ - After-drain observation:
27
+ - Final observation:
28
+
29
+ ## Evidence
30
+
31
+ - Before:
32
+ - During:
33
+ - After:
34
+
35
+ ## Verification
36
+
37
+ - Command/check:
38
+ - Result:
39
+ - Truth status:
40
+
41
+ ## Cleanup
42
+
43
+ - Cleanup performed:
44
+ - Process exit verified:
45
+ - tmux pane/session closed or intentionally left running:
46
+ - Remaining process intentionally left running:
47
+
48
+ ## Blockers
49
+
50
+ - None.
51
+
52
+ ## Final Truth Status
53
+
54
+ - proven / verified / partial / fixture_only / fixture_instrumented_real / integration_optional / real_required_missing / skipped / blocked / assumed:
@@ -0,0 +1,39 @@
1
+ # yam Tuning Log
2
+
3
+ Use this to tune route wording from real use.
4
+
5
+ ## Entry
6
+
7
+ - Date:
8
+ - Project:
9
+ - Route:
10
+ - Task:
11
+
12
+ ## What Happened
13
+
14
+ - Over-read context:
15
+ - Under-verified:
16
+ - Report too long:
17
+ - Direction mismatch:
18
+ - Useful behavior:
19
+
20
+ ## Budget Measurement
21
+
22
+ - Files read:
23
+ - Commands run:
24
+ - Report lines:
25
+ - Seconds:
26
+ - Budget result:
27
+
28
+ ## Fix To Harness
29
+
30
+ - Skill to edit:
31
+ - Proposed wording:
32
+ - Keep/remove:
33
+
34
+ ## Compared Against
35
+
36
+ - Strict proof:
37
+ - Modular skills:
38
+ - Minimal core:
39
+ - yam decision:
@@ -0,0 +1,78 @@
1
+ # yam Ueye Reference Comparison
2
+
3
+ ## Input
4
+
5
+ - Implementation screenshot/URL:
6
+ - Reference screenshot/URL/path:
7
+ - Product or screen:
8
+ - Review bound:
9
+
10
+ ## Visual Evidence Inventory
11
+
12
+ | Label | Type | Path/URL | Dimensions | sha256 | Viewport | State | Role |
13
+ | --- | --- | --- | --- | --- | --- | --- | --- |
14
+ | implementation | | | unknown | unknown | | | proof |
15
+ | reference | | | unknown | unknown | | | reference direction |
16
+
17
+ ## Reference Read Proof
18
+
19
+ - Layout:
20
+ - Visual hierarchy:
21
+ - Typography:
22
+ - Color/contrast:
23
+ - Component detail:
24
+ - Interaction/motion:
25
+ - Responsiveness:
26
+ - Brand/mood fit:
27
+
28
+ ## Reference vs Implementation Matrix
29
+
30
+ Use `matched`, `similar`, `different`, `not-verified`, or `not-applicable`.
31
+
32
+ | Dimension | Status | Evidence | Suggested Fix |
33
+ | --- | --- | --- | --- |
34
+ | Layout and spacing | not-verified | | |
35
+ | Visual hierarchy | not-verified | | |
36
+ | Typography | not-verified | | |
37
+ | Color and contrast | not-verified | | |
38
+ | Component detail | not-verified | | |
39
+ | Interaction and motion | not-verified | | |
40
+ | Responsiveness | not-verified | | |
41
+ | Accessibility visuals | not-verified | | |
42
+ | Brand and mood fit | not-verified | | |
43
+
44
+ ## Design Quality Review
45
+
46
+ Use `pass`, `needs-polish`, or `fails` for each relevant design dimension before listing actionable issues.
47
+
48
+ | Dimension | Result | Evidence |
49
+ | --- | --- | --- |
50
+ | Visual hierarchy | needs-polish | |
51
+ | Layout/spacing | needs-polish | |
52
+ | Typography | needs-polish | |
53
+ | Color/contrast | needs-polish | |
54
+ | Component detail | needs-polish | |
55
+ | Interaction/motion | needs-polish | |
56
+ | Responsiveness | needs-polish | |
57
+ | Accessibility | needs-polish | |
58
+ | Brand/mood fit | needs-polish | |
59
+
60
+ ### P0 Blockers
61
+
62
+ - None.
63
+
64
+ ### P1 Major
65
+
66
+ - None.
67
+
68
+ ### P2 Quality
69
+
70
+ - None.
71
+
72
+ ### P3 Polish
73
+
74
+ - None.
75
+
76
+ ## Truth Status
77
+
78
+ - verified / partial / skipped / blocked / assumed: