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.
- package/AGENTS.md +18 -0
- package/COMMANDS.md +152 -0
- package/DECISIONS.md +70 -0
- package/LICENSE +21 -0
- package/README.md +174 -0
- package/ROADMAP.md +313 -0
- package/dist/bin/yam.d.ts +2 -0
- package/dist/bin/yam.js +2005 -0
- package/dist/lib/trust-kernel.d.ts +99 -0
- package/dist/lib/trust-kernel.js +300 -0
- package/package.json +101 -0
- package/references/context-reuse.md +59 -0
- package/references/current-docs.md +45 -0
- package/references/db-supabase-safety-lite.md +40 -0
- package/references/doctor-scan.md +56 -0
- package/references/eye.md +30 -0
- package/references/final-report.md +61 -0
- package/references/honest-completion.md +61 -0
- package/references/hook-lite.md +55 -0
- package/references/markdown-management.md +56 -0
- package/references/memory.md +59 -0
- package/references/mission.md +86 -0
- package/references/question.md +25 -0
- package/references/quick.md +70 -0
- package/references/risk-escalation.md +27 -0
- package/references/runtime-orchestration.md +57 -0
- package/references/scout.md +38 -0
- package/references/token-budget-reporter.md +44 -0
- package/references/token-economy.md +61 -0
- package/references/tool-trust-layer.md +115 -0
- package/references/trust-kernel.md +55 -0
- package/references/truth-matrix.md +47 -0
- package/references/ueye-proof.md +109 -0
- package/references/ueye.md +174 -0
- package/references/ui-quality.md +23 -0
- package/references/verification-levels.md +53 -0
- package/skills/deep/SKILL.md +77 -0
- package/skills/mission/SKILL.md +105 -0
- package/skills/question/SKILL.md +45 -0
- package/skills/quick/SKILL.md +81 -0
- package/skills/scout/SKILL.md +71 -0
- package/skills/ueye/SKILL.md +132 -0
- package/src/bin/yam.ts +1988 -0
- package/src/lib/trust-kernel.ts +398 -0
- package/templates/mission-plan.md +46 -0
- package/templates/runtime-proof.md +54 -0
- package/templates/tuning-log.md +39 -0
- package/templates/ueye-comparison.md +78 -0
- package/templates/ueye-review.md +110 -0
- package/templates/yam.project.md +73 -0
- package/tsconfig.json +27 -0
- 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:
|