yam-flow 0.1.8 → 1.9.1
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 +34 -0
- package/COMMANDS.md +2 -2
- package/README.md +2 -2
- package/dist/bin/yam.js +24 -3
- package/dist/lib/trust-kernel.d.ts +16 -0
- package/dist/lib/trust-kernel.js +36 -2
- package/package.json +1 -1
- package/references/final-report.md +29 -0
- package/skills/deep/SKILL.md +2 -2
- package/skills/mission/SKILL.md +2 -2
- package/skills/quick/SKILL.md +2 -1
- package/skills/ueye/SKILL.md +2 -1
- package/src/bin/yam.ts +25 -4
- package/src/lib/trust-kernel.ts +52 -2
- package/yam.manifest.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to yam-flow are documented here.
|
|
4
4
|
|
|
5
|
+
## v1.9.1 - 2026-06-19
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Extended `yam loop report --json` with guided stage conventions, `evidence_level`, `evidence_stamp`/`source_digest`, `blocked_kind`, `safe_retry`, `owner_scope`, `scope_owner`, and `side_effects` so the report can act as a clearer handoff artifact without adding a new command.
|
|
10
|
+
- Updated loop report smoke coverage to assert the new handoff fields.
|
|
11
|
+
|
|
12
|
+
### Improved
|
|
13
|
+
|
|
14
|
+
- Updated README, COMMANDS, final-report guidance, implementation skill final-response rules, and manifest principles to prefer fix-first handoff with evidence level, blocker kind, safe retry, and owner/scope clarity.
|
|
15
|
+
|
|
16
|
+
## v0.1.9 - 2026-06-18
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Expanded `yam loop report --json` into a read-only handoff artifact with `fix_first_items`, `recommended_direction`, `implementation_notes`, `why_this_next`, `blocked_by`, and `owner_route`.
|
|
21
|
+
- Added loop report smoke coverage for the new handoff fields while keeping the existing minimal and blocked report paths.
|
|
22
|
+
|
|
23
|
+
### Improved
|
|
24
|
+
|
|
25
|
+
- Updated `$quick`, `$deep`, `$mission`, and `$ueye` final response guidance so implementation work can include Study Note and handoff habits without forcing a CLI artifact for ordinary work.
|
|
26
|
+
- Updated `references/final-report.md`, README, COMMANDS, and manifest principles to treat Study Note and handoff direction as final-report practices.
|
|
27
|
+
|
|
28
|
+
### Verification
|
|
29
|
+
|
|
30
|
+
- `npm run typecheck`
|
|
31
|
+
- `npm run build`
|
|
32
|
+
- `node ./dist/bin/yam.js loop report --json` with handoff fields
|
|
33
|
+
- `npm run cli-smoke`
|
|
34
|
+
- `npm run verify:self`
|
|
35
|
+
- `npm run forbidden-names:check`
|
|
36
|
+
- `npm run package-boundary:check`
|
|
37
|
+
- `npm run dist:freshness`
|
|
38
|
+
|
|
5
39
|
## v0.1.8 - 2026-06-16
|
|
6
40
|
|
|
7
41
|
### Added
|
package/COMMANDS.md
CHANGED
|
@@ -148,7 +148,7 @@ yam tools doctor /path/to/project
|
|
|
148
148
|
yam tools doctor /path/to/project --json
|
|
149
149
|
yam context pressure /path/to/project --json
|
|
150
150
|
yam cleanup scan /path/to/project --json
|
|
151
|
-
yam loop report --route quick --intent "fix release readiness" --stage "inspect:passed:read release report" --evidence "typecheck passed" --issue-code "src/bin/yam.ts release report" --issue-role "summarizes release readiness without publishing" --issue-symptom "npm auth failure needs clearer next action" --changed-code "yam loop report" --changed-role "records loop evidence and learning note" --change-summary "added a read-only loop artifact" --why-important "it helps users learn what changed without overclaiming verification" --learning-note "fix blockers before claiming done" --json
|
|
151
|
+
yam loop report --route quick --intent "fix release readiness" --stage "inspect:passed:read release report" --evidence "typecheck passed" --evidence-level local --evidence-stamp "sha256:release-report" --blocked-kind auth_blocked --safe-retry "retry after npm whoami succeeds" --fix-first-item "npm auth must be verified before publish" --remaining-task "rerun release report after auth refresh" --recommended-direction "fix npm auth first, then publish manually" --implementation-note "keep loop report read-only" --why-this-next "auth blocks public release claims" --blocked-by "npm whoami E401" --owner-route deep --owner-scope "release readiness only" --scope-owner deep --side-effect "no publish attempted" --issue-code "src/bin/yam.ts release report" --issue-role "summarizes release readiness without publishing" --issue-symptom "npm auth failure needs clearer next action" --changed-code "yam loop report" --changed-role "records loop evidence and learning note" --change-summary "added a read-only loop artifact" --why-important "it helps users learn what changed without overclaiming verification" --learning-note "fix blockers before claiming done" --json
|
|
152
152
|
yam proof /path/to/project
|
|
153
153
|
yam proof --route deep --truth verified --command "npm run build: pass"
|
|
154
154
|
yam proof --route ueye --truth verified --visual "reference image only"
|
|
@@ -195,7 +195,7 @@ Supported report shapes:
|
|
|
195
195
|
|
|
196
196
|
- Runtime evidence mini: command/process, observation, cleanup, truth status, next action.
|
|
197
197
|
- Patch queue lite: mission lane status, changed files, verification hint, rollback hint, truth status.
|
|
198
|
-
- Loop report: intent, stage outcomes, evidence, blockers, next action, remaining tasks, and study note.
|
|
198
|
+
- Loop report: intent, guided stage outcomes, evidence level/stamp, blockers, blocker kind, safe retry, next action, fix-first items, remaining tasks, recommended direction, blocked-by notes, owner route/scope, side effects, and study note.
|
|
199
199
|
- Study note: short non-specialist explanation of the failing code, its role, observed symptom, changed code, and why it matters.
|
|
200
200
|
- Benchmark optimization loop lite: baseline, one change, rerun, keep/revert decision.
|
|
201
201
|
- Structured diagnostic next action: severity, evidence, owner route, next action, truth status.
|
package/README.md
CHANGED
|
@@ -142,7 +142,7 @@ yam ueye report --reference ./reference.png --actual .yam/screens/home.png --pre
|
|
|
142
142
|
yam proof --route ueye --truth verified --visual "implementation screenshot evidence recorded" --design-completion '{"completion_claim":"done","has_implementation_screenshot":true,"design_quality":"pass","states_checked":true,"mobile_checked":true,"contrast_checked":true,"cta_checked":true,"direction_locked":true,"truth_status":"verified"}'
|
|
143
143
|
yam media proof --requested --attempted --output ./generated.png --wait-loop --json
|
|
144
144
|
yam proof --route mission --mission-envelope '{"agent_id":"implementer","assigned_scope":"target component","changed_files":["src/file.ts"],"verification_hint":"npm run typecheck","truth_status":"partial"}'
|
|
145
|
-
yam loop report --route quick --intent "fix release readiness" --stage "inspect:passed:read release report" --evidence "typecheck passed" --issue-code "src/bin/yam.ts release report" --issue-role "summarizes release readiness without publishing" --issue-symptom "npm auth failure needs clearer next action" --changed-code "yam loop report" --changed-role "records loop evidence and learning note" --change-summary "added a read-only loop artifact" --why-important "it helps users learn what changed without overclaiming verification" --learning-note "fix blockers before claiming done" --json
|
|
145
|
+
yam loop report --route quick --intent "fix release readiness" --stage "inspect:passed:read release report" --evidence "typecheck passed" --evidence-level local --evidence-stamp "sha256:release-report" --blocked-kind auth_blocked --safe-retry "retry after npm whoami succeeds" --fix-first-item "npm auth must be verified before publish" --remaining-task "rerun release report after auth refresh" --recommended-direction "fix npm auth first, then publish manually" --implementation-note "keep loop report read-only" --why-this-next "auth blocks public release claims" --blocked-by "npm whoami E401" --owner-route deep --owner-scope "release readiness only" --scope-owner deep --side-effect "no publish attempted" --issue-code "src/bin/yam.ts release report" --issue-role "summarizes release readiness without publishing" --issue-symptom "npm auth failure needs clearer next action" --changed-code "yam loop report" --changed-role "records loop evidence and learning note" --change-summary "added a read-only loop artifact" --why-important "it helps users learn what changed without overclaiming verification" --learning-note "fix blockers before claiming done" --json
|
|
146
146
|
yam release report --json
|
|
147
147
|
yam safety "supabase db reset"
|
|
148
148
|
yam detect /path/to/project
|
|
@@ -216,7 +216,7 @@ These shapes keep reports machine-readable without turning normal work into a he
|
|
|
216
216
|
- Runtime evidence mini: compact route, command/process, observation, cleanup, truth status, and next action fields for `$deep` or `$mission` runtime claims.
|
|
217
217
|
- Patch queue lite: `$mission` lane records with pending/applied/verified/reverted/blocked state, changed files, verification hint, rollback hint, truth status, and next action.
|
|
218
218
|
- Release report JSON: `yam release report --json` summarizes typecheck, forbidden-name scan, package boundary, registry status, CLI smoke, dist freshness, diagnostics, and final truth status.
|
|
219
|
-
- Loop report JSON: `yam loop report --json` records a read-only
|
|
219
|
+
- Loop report JSON: `yam loop report --json` records a read-only handoff artifact: guided stages, evidence level/stamp, blocker kind, safe retry, owner route/scope, side effects, next action, fix-first items, remaining tasks, recommended direction, implementation notes, blocked-by notes, tool intent, truth status, and study note.
|
|
220
220
|
- Study note: `yam.study-note.v1` keeps short non-specialist explanations for what code was failing, what role it plays, how the symptom showed up, what changed, and why it matters. Missing details stay in `limits` instead of being guessed.
|
|
221
221
|
- Publish blocker evidence: release reports classify common npm auth, permission, OTP, immutable-version, cache, registry, and tarball failures into safe next actions.
|
|
222
222
|
- Publish readiness evidence: release reports run read-only registry/auth/version probes, redact account/token details, and keep npm publish outside the report.
|
package/dist/bin/yam.js
CHANGED
|
@@ -524,6 +524,12 @@ function normalizeToolIntent(value = '') {
|
|
|
524
524
|
return text;
|
|
525
525
|
return 'read_only';
|
|
526
526
|
}
|
|
527
|
+
function normalizeLoopEvidenceLevelFlag(value = '') {
|
|
528
|
+
const text = String(value || '').toLowerCase().replace(/[-\s]/g, '_');
|
|
529
|
+
if (['fixture', 'smoke', 'local', 'real'].includes(text))
|
|
530
|
+
return text;
|
|
531
|
+
return 'none';
|
|
532
|
+
}
|
|
527
533
|
function uniqueNextActionDetails(actions = []) {
|
|
528
534
|
const seen = new Set();
|
|
529
535
|
const unique = [];
|
|
@@ -1970,28 +1976,43 @@ async function loop(args = []) {
|
|
|
1970
1976
|
function loopUsage() {
|
|
1971
1977
|
console.log(`yam loop
|
|
1972
1978
|
|
|
1973
|
-
Read-only loop artifact helpers. A loop report records intent, stages, evidence, blockers, next action, and a short study note. It does not run agents, start processes, publish packages, or write files.
|
|
1979
|
+
Read-only loop artifact helpers. A loop report records intent, stages, evidence, blockers, next action, handoff fields, and a short study note. It does not run agents, start processes, publish packages, or write files.
|
|
1974
1980
|
|
|
1975
1981
|
Usage:
|
|
1976
|
-
yam loop report [--route route] [--intent text] [--loop-kind harness|release|ueye|scout|deep|mission] [--stage id:status:note] [--evidence text] [--blocked text] [--remaining-task text] [--truth status] [--intent-label read_only|write|destructive|runtime|visual|publish] [--issue-code text] [--issue-role text] [--issue-symptom text] [--changed-code text] [--changed-role text] [--change-summary text] [--why-important text] [--learning-note text] [--json]
|
|
1982
|
+
yam loop report [--route route] [--intent text] [--loop-kind harness|release|ueye|scout|deep|mission] [--stage id:status:note] [--evidence text] [--evidence-level none|fixture|smoke|local|real] [--evidence-stamp text] [--source-digest text] [--blocked text] [--blocked-kind text] [--safe-retry text] [--fix-first-item text] [--remaining-task text] [--recommended-direction text] [--implementation-note text] [--why-this-next text] [--blocked-by text] [--owner-route route] [--owner-scope text] [--scope-owner text] [--side-effect text] [--truth status] [--intent-label read_only|write|destructive|runtime|visual|publish] [--issue-code text] [--issue-role text] [--issue-symptom text] [--changed-code text] [--changed-role text] [--change-summary text] [--why-important text] [--learning-note text] [--json]
|
|
1977
1983
|
`);
|
|
1978
1984
|
}
|
|
1979
1985
|
async function loopReport(args = []) {
|
|
1980
1986
|
if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h')
|
|
1981
1987
|
return loopUsage();
|
|
1982
|
-
const flags = parseSimpleFlags(args, new Set(['route', 'intent', 'loop-kind', 'stage', 'evidence', 'blocked', 'blocker', 'next-action', 'remaining-task', 'truth', 'intent-label', 'tool-intent', 'issue-code', 'issue-role', 'issue-symptom', 'changed-code', 'changed-role', 'change-summary', 'why-important', 'learning-note', 'json']));
|
|
1988
|
+
const flags = parseSimpleFlags(args, new Set(['route', 'intent', 'loop-kind', 'stage', 'stage-convention', 'evidence', 'evidence-level', 'evidence-stamp', 'source-digest', 'blocked', 'blocker', 'blocked-kind', 'next-action', 'safe-retry', 'fix-first-item', 'remaining-task', 'recommended-direction', 'direction', 'implementation-note', 'why-this-next', 'blocked-by', 'owner-route', 'owner-scope', 'scope-owner', 'owner', 'scope', 'side-effect', 'truth', 'intent-label', 'tool-intent', 'issue-code', 'issue-role', 'issue-symptom', 'changed-code', 'changed-role', 'change-summary', 'why-important', 'learning-note', 'json']));
|
|
1983
1989
|
const blockers = [...arrayFlag(flags.blocked), ...arrayFlag(flags.blocker)];
|
|
1984
1990
|
const report = buildLoopReport({
|
|
1985
1991
|
route: normalizeRoute(flags.route) || String(flags.route || ''),
|
|
1986
1992
|
intent: String(flags.intent || ''),
|
|
1987
1993
|
loop_kind: String(flags.loop_kind || flags.route || 'harness'),
|
|
1994
|
+
stage_conventions: arrayFlag(flags.stage_convention),
|
|
1988
1995
|
stages: arrayFlag(flags.stage),
|
|
1989
1996
|
evidence: arrayFlag(flags.evidence),
|
|
1997
|
+
evidence_level: normalizeLoopEvidenceLevelFlag(flags.evidence_level),
|
|
1998
|
+
evidence_stamp: String(flags.evidence_stamp || ''),
|
|
1999
|
+
source_digest: String(flags.source_digest || ''),
|
|
1990
2000
|
blockers,
|
|
2001
|
+
blocked_kind: String(flags.blocked_kind || ''),
|
|
1991
2002
|
truth_status: isTruthStatus(flags.truth) ? flags.truth : undefined,
|
|
1992
2003
|
intent_label: normalizeToolIntent(flags.intent_label || flags.tool_intent || 'read_only'),
|
|
1993
2004
|
next_action: String(flags.next_action || ''),
|
|
2005
|
+
safe_retry: String(flags.safe_retry || ''),
|
|
2006
|
+
fix_first_items: arrayFlag(flags.fix_first_item),
|
|
1994
2007
|
remaining_tasks: arrayFlag(flags.remaining_task),
|
|
2008
|
+
recommended_direction: String(flags.recommended_direction || flags.direction || ''),
|
|
2009
|
+
implementation_notes: arrayFlag(flags.implementation_note),
|
|
2010
|
+
why_this_next: String(flags.why_this_next || ''),
|
|
2011
|
+
blocked_by: arrayFlag(flags.blocked_by),
|
|
2012
|
+
owner_route: String(flags.owner_route || flags.route || ''),
|
|
2013
|
+
owner_scope: [...arrayFlag(flags.owner_scope), ...arrayFlag(flags.scope)],
|
|
2014
|
+
scope_owner: String(flags.scope_owner || flags.owner || ''),
|
|
2015
|
+
side_effects: arrayFlag(flags.side_effect),
|
|
1995
2016
|
issue_code: String(flags.issue_code || ''),
|
|
1996
2017
|
issue_role: String(flags.issue_role || ''),
|
|
1997
2018
|
issue_symptom: String(flags.issue_symptom || ''),
|
|
@@ -6,6 +6,7 @@ export type RuntimeSubsystem = 'real_runtime' | 'tmux_physical' | 'process_clean
|
|
|
6
6
|
export type RuntimeBackend = 'none' | 'in_app_browser' | 'playwright' | 'terminal' | 'tmux' | 'zellij' | 'unknown';
|
|
7
7
|
export type RuntimeClaim = 'not_started' | 'started' | 'observed' | 'stopped' | 'cleanup_verified' | 'blocked' | 'unknown';
|
|
8
8
|
export type LoopStageStatus = 'passed' | 'failed' | 'blocked' | 'skipped' | 'partial' | 'pending' | 'recorded';
|
|
9
|
+
export type LoopEvidenceLevel = 'none' | 'fixture' | 'smoke' | 'local' | 'real';
|
|
9
10
|
export type ToolIntent = 'read_only' | 'write' | 'destructive' | 'runtime' | 'visual' | 'publish';
|
|
10
11
|
export interface SafetyHit {
|
|
11
12
|
level: SafetyLevel;
|
|
@@ -154,14 +155,29 @@ export interface LoopReport {
|
|
|
154
155
|
route: string;
|
|
155
156
|
intent: string;
|
|
156
157
|
loop_kind: string;
|
|
158
|
+
stage_conventions: string[];
|
|
157
159
|
stages: LoopStage[];
|
|
158
160
|
evidence: string[];
|
|
161
|
+
evidence_level: LoopEvidenceLevel;
|
|
162
|
+
evidence_stamp: string;
|
|
163
|
+
source_digest: string;
|
|
159
164
|
blockers: string[];
|
|
165
|
+
blocked_kind: string;
|
|
160
166
|
truth_status: TruthStatus;
|
|
161
167
|
intent_label: ToolIntent;
|
|
162
168
|
tool_intent: ToolIntent;
|
|
163
169
|
next_action: string;
|
|
170
|
+
safe_retry: string;
|
|
171
|
+
fix_first_items: string[];
|
|
164
172
|
remaining_tasks: string[];
|
|
173
|
+
recommended_direction: string;
|
|
174
|
+
implementation_notes: string[];
|
|
175
|
+
why_this_next: string;
|
|
176
|
+
blocked_by: string[];
|
|
177
|
+
owner_route: string;
|
|
178
|
+
owner_scope: string[];
|
|
179
|
+
scope_owner: string;
|
|
180
|
+
side_effects: string[];
|
|
165
181
|
study_note: StudyNote;
|
|
166
182
|
}
|
|
167
183
|
export interface UeyeRunReport {
|
package/dist/lib/trust-kernel.js
CHANGED
|
@@ -237,9 +237,14 @@ export function buildLoopReport(input = {}) {
|
|
|
237
237
|
: [];
|
|
238
238
|
const evidence = asList(input.evidence);
|
|
239
239
|
const blockers = asList(input.blockers || input.blocked);
|
|
240
|
+
const blockedBy = asList(input.blocked_by);
|
|
241
|
+
const blockedKind = shortText(input.blocked_kind || (blockers.length || blockedBy.length ? 'evidence_missing' : ''));
|
|
242
|
+
const evidenceStamp = shortText(input.evidence_stamp || input.source_digest, 320);
|
|
243
|
+
const sourceDigest = shortText(input.source_digest || input.evidence_stamp, 320);
|
|
240
244
|
const hasBlockedStage = stages.some((stage) => stage.status === 'blocked' || stage.status === 'failed');
|
|
245
|
+
const hasBlockerSignal = Boolean(blockers.length || blockedBy.length || blockedKind);
|
|
241
246
|
const requestedTruth = isTruthStatus(input.truth_status) ? input.truth_status : '';
|
|
242
|
-
const derivedTruth =
|
|
247
|
+
const derivedTruth = hasBlockerSignal || hasBlockedStage ? 'blocked'
|
|
243
248
|
: evidence.length && stages.some((stage) => stage.status === 'passed') ? 'verified'
|
|
244
249
|
: evidence.length || stages.length ? 'partial'
|
|
245
250
|
: 'assumed';
|
|
@@ -252,14 +257,31 @@ export function buildLoopReport(input = {}) {
|
|
|
252
257
|
route: String(input.route || ''),
|
|
253
258
|
intent: shortText(input.intent),
|
|
254
259
|
loop_kind: String(input.loop_kind || 'harness'),
|
|
260
|
+
stage_conventions: asList(input.stage_conventions || input.stage_convention).length
|
|
261
|
+
? asList(input.stage_conventions || input.stage_convention)
|
|
262
|
+
: ['brief', 'plan', 'implement', 'critique', 'verify', 'handoff'],
|
|
255
263
|
stages,
|
|
256
264
|
evidence,
|
|
265
|
+
evidence_level: normalizeLoopEvidenceLevel(input.evidence_level),
|
|
266
|
+
evidence_stamp: evidenceStamp,
|
|
267
|
+
source_digest: sourceDigest,
|
|
257
268
|
blockers,
|
|
269
|
+
blocked_kind: blockedKind,
|
|
258
270
|
truth_status: truth,
|
|
259
271
|
intent_label: intentLabel,
|
|
260
272
|
tool_intent: intentLabel,
|
|
261
|
-
next_action: shortText(input.next_action || (
|
|
273
|
+
next_action: shortText(input.next_action || (hasBlockerSignal ? 'resolve the blocker before claiming this loop complete' : 'record the next smallest useful action')),
|
|
274
|
+
safe_retry: shortText(input.safe_retry || (hasBlockerSignal ? 'retry only after the blocker is resolved and new evidence is recorded' : 'not required')),
|
|
275
|
+
fix_first_items: asList(input.fix_first_items || input.fix_first_item),
|
|
262
276
|
remaining_tasks: asList(input.remaining_tasks || input.remaining_task),
|
|
277
|
+
recommended_direction: shortText(input.recommended_direction || input.direction),
|
|
278
|
+
implementation_notes: asList(input.implementation_notes || input.implementation_note),
|
|
279
|
+
why_this_next: shortText(input.why_this_next),
|
|
280
|
+
blocked_by: blockedBy,
|
|
281
|
+
owner_route: normalizeOwnerRoute(input.owner_route || input.route),
|
|
282
|
+
owner_scope: asList(input.owner_scope || input.scope),
|
|
283
|
+
scope_owner: normalizeOwnerRoute(input.scope_owner || input.owner),
|
|
284
|
+
side_effects: asList(input.side_effects || input.side_effect),
|
|
263
285
|
study_note: studyNote
|
|
264
286
|
};
|
|
265
287
|
}
|
|
@@ -388,6 +410,18 @@ function normalizeToolIntentLabel(value = '') {
|
|
|
388
410
|
return text;
|
|
389
411
|
return 'read_only';
|
|
390
412
|
}
|
|
413
|
+
function normalizeOwnerRoute(value = '') {
|
|
414
|
+
const text = String(value || '').trim().replace(/^\$/, '').replace(/^yam-/, '');
|
|
415
|
+
if (['quick', 'ueye', 'question', 'scout', 'deep', 'mission'].includes(text))
|
|
416
|
+
return `$${text}`;
|
|
417
|
+
return text ? shortText(text, 80) : '';
|
|
418
|
+
}
|
|
419
|
+
function normalizeLoopEvidenceLevel(value = '') {
|
|
420
|
+
const text = String(value || '').toLowerCase().replace(/[-\s]/g, '_');
|
|
421
|
+
if (['fixture', 'smoke', 'local', 'real'].includes(text))
|
|
422
|
+
return text;
|
|
423
|
+
return 'none';
|
|
424
|
+
}
|
|
391
425
|
function shortText(value = '', limit = 240) {
|
|
392
426
|
const text = String(value || '').trim().replace(/\s+/g, ' ');
|
|
393
427
|
if (text.length <= limit)
|
package/package.json
CHANGED
|
@@ -16,8 +16,10 @@ Include these when they are useful and keep them short:
|
|
|
16
16
|
- Context pressure or cleanup findings when they could affect the next run.
|
|
17
17
|
- Publish blocker evidence when npm/release work fails.
|
|
18
18
|
- Structured diagnostic next action, when a check found a concrete next step.
|
|
19
|
+
- Study Note for implementation work: what code was wrong, what role it has, how the symptom showed up, what changed, and why it matters in short non-specialist language.
|
|
19
20
|
- Remaining tasks.
|
|
20
21
|
- Fix-first items before planned tasks.
|
|
22
|
+
- Recommended direction and why that next step matters when the handoff would otherwise be ambiguous.
|
|
21
23
|
|
|
22
24
|
## Anti-False-Completion Check
|
|
23
25
|
|
|
@@ -54,6 +56,33 @@ Examples:
|
|
|
54
56
|
- Active hooks or instruction files that conflict with the route.
|
|
55
57
|
- Warnings that keep obscuring real problems.
|
|
56
58
|
|
|
59
|
+
## Study Note
|
|
60
|
+
|
|
61
|
+
Use this when implementation changed code or fixed an error and the user would benefit from learning:
|
|
62
|
+
|
|
63
|
+
- What code had the issue.
|
|
64
|
+
- What role that code plays.
|
|
65
|
+
- How the issue showed up.
|
|
66
|
+
- What changed.
|
|
67
|
+
- Why the change matters.
|
|
68
|
+
|
|
69
|
+
Keep it short. If the information is not known, say so instead of inventing it.
|
|
70
|
+
|
|
71
|
+
## Handoff Direction
|
|
72
|
+
|
|
73
|
+
Use this when the next run needs a clear starting point:
|
|
74
|
+
|
|
75
|
+
- Fix-first items before planned work.
|
|
76
|
+
- Remaining tasks that still belong to the request or roadmap.
|
|
77
|
+
- Recommended direction.
|
|
78
|
+
- Why this next step matters.
|
|
79
|
+
- What is blocked, and by what.
|
|
80
|
+
- Evidence level or stamp when the handoff relies on a specific command, file, or report.
|
|
81
|
+
- Blocker kind and safe retry when the next run should not blindly repeat the same action.
|
|
82
|
+
- Owner route, scope owner, and side effects when more than one person or route may continue the work.
|
|
83
|
+
|
|
84
|
+
`yam loop report` can record this as a handoff artifact with `fix_first_items`, `remaining_tasks`, `recommended_direction`, `implementation_notes`, `why_this_next`, `blocked_by`, `blocked_kind`, `safe_retry`, `evidence_level`, `evidence_stamp`, `owner_route`, `owner_scope`, `scope_owner`, and `side_effects`.
|
|
85
|
+
|
|
57
86
|
## Route Weight
|
|
58
87
|
|
|
59
88
|
For `$quick`, one short paragraph or a compact verification matrix is enough.
|
package/skills/deep/SKILL.md
CHANGED
|
@@ -70,8 +70,8 @@ Deep verification may include:
|
|
|
70
70
|
Include:
|
|
71
71
|
|
|
72
72
|
- What was changed or reviewed.
|
|
73
|
+
- Study Note for implementation work: what code was wrong, what role it has, how the symptom showed up, what changed, and why it matters in short non-specialist language.
|
|
73
74
|
- Evidence gathered.
|
|
74
75
|
- Truth status.
|
|
75
76
|
- Blockers or remaining risk.
|
|
76
|
-
-
|
|
77
|
-
- Fix-first items before planned tasks.
|
|
77
|
+
- Handoff: fix-first items, remaining tasks, recommended direction, why that next step matters, blocker kind, safe retry, evidence level/stamp, side effects, and owner scope when another route or person may continue.
|
package/skills/mission/SKILL.md
CHANGED
|
@@ -102,8 +102,8 @@ Report:
|
|
|
102
102
|
|
|
103
103
|
- What the mission changed.
|
|
104
104
|
- Role/cross-verification summary.
|
|
105
|
+
- Study Note for implementation lanes: what code was wrong, what role it has, how the symptom showed up, what changed, and why it matters in short non-specialist language.
|
|
105
106
|
- Evidence gathered.
|
|
106
107
|
- Truth status.
|
|
107
108
|
- Cleanup status.
|
|
108
|
-
-
|
|
109
|
-
- Fix-first items before planned tasks.
|
|
109
|
+
- Handoff: fix-first items, remaining tasks, recommended direction, why that next step matters, blocker kind, safe retry, evidence level/stamp, side effects, and owner scope when another route or person may continue.
|
package/skills/quick/SKILL.md
CHANGED
|
@@ -76,6 +76,7 @@ Use `references/token-budget-reporter.md` when a run needs measured budget feedb
|
|
|
76
76
|
Keep it compact:
|
|
77
77
|
|
|
78
78
|
- What changed or what the scan found.
|
|
79
|
+
- Study Note when useful: what code was wrong, what role it has, how the symptom showed up, what changed, and why it matters in short non-specialist language.
|
|
79
80
|
- What was checked.
|
|
80
81
|
- What was skipped, blocked, or still risky.
|
|
81
|
-
-
|
|
82
|
+
- Handoff when useful: fix-first items, remaining tasks, recommended direction, why that next step matters, blocker kind, safe retry, evidence level/stamp, and owner scope when another route or person may continue.
|
package/skills/ueye/SKILL.md
CHANGED
|
@@ -170,5 +170,6 @@ Report:
|
|
|
170
170
|
- Review continuity/comparison result when this continues a prior Ueye run.
|
|
171
171
|
- P0-P3 issues or confirmation that no blockers were found.
|
|
172
172
|
- States/viewports checked.
|
|
173
|
+
- Study Note when UI implementation changed code: what UI code changed, what role it has, how the visible symptom appeared, and why the change matters in short non-specialist language.
|
|
173
174
|
- Truth status and visual verification cap.
|
|
174
|
-
-
|
|
175
|
+
- Handoff when useful: fix-first visual issues, remaining tasks, recommended direction, why that next step matters, blocker kind, safe retry, evidence level/stamp, and owner scope when another route or person may continue.
|
package/src/bin/yam.ts
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
detectDbSafetyText as detectTrustDbSafetyText,
|
|
25
25
|
isTruthStatus
|
|
26
26
|
} from '../lib/trust-kernel.js';
|
|
27
|
-
import type { ToolIntent } from '../lib/trust-kernel.js';
|
|
27
|
+
import type { LoopEvidenceLevel, ToolIntent } from '../lib/trust-kernel.js';
|
|
28
28
|
|
|
29
29
|
type AnyRecord = Record<string, any>;
|
|
30
30
|
|
|
@@ -525,6 +525,12 @@ function normalizeToolIntent(value = ''): ToolIntent {
|
|
|
525
525
|
return 'read_only';
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
+
function normalizeLoopEvidenceLevelFlag(value = ''): LoopEvidenceLevel {
|
|
529
|
+
const text = String(value || '').toLowerCase().replace(/[-\s]/g, '_');
|
|
530
|
+
if (['fixture', 'smoke', 'local', 'real'].includes(text)) return text as LoopEvidenceLevel;
|
|
531
|
+
return 'none';
|
|
532
|
+
}
|
|
533
|
+
|
|
528
534
|
function uniqueNextActionDetails(actions = []) {
|
|
529
535
|
const seen = new Set<string>();
|
|
530
536
|
const unique = [];
|
|
@@ -1968,28 +1974,43 @@ async function loop(args = []) {
|
|
|
1968
1974
|
function loopUsage() {
|
|
1969
1975
|
console.log(`yam loop
|
|
1970
1976
|
|
|
1971
|
-
Read-only loop artifact helpers. A loop report records intent, stages, evidence, blockers, next action, and a short study note. It does not run agents, start processes, publish packages, or write files.
|
|
1977
|
+
Read-only loop artifact helpers. A loop report records intent, stages, evidence, blockers, next action, handoff fields, and a short study note. It does not run agents, start processes, publish packages, or write files.
|
|
1972
1978
|
|
|
1973
1979
|
Usage:
|
|
1974
|
-
yam loop report [--route route] [--intent text] [--loop-kind harness|release|ueye|scout|deep|mission] [--stage id:status:note] [--evidence text] [--blocked text] [--remaining-task text] [--truth status] [--intent-label read_only|write|destructive|runtime|visual|publish] [--issue-code text] [--issue-role text] [--issue-symptom text] [--changed-code text] [--changed-role text] [--change-summary text] [--why-important text] [--learning-note text] [--json]
|
|
1980
|
+
yam loop report [--route route] [--intent text] [--loop-kind harness|release|ueye|scout|deep|mission] [--stage id:status:note] [--evidence text] [--evidence-level none|fixture|smoke|local|real] [--evidence-stamp text] [--source-digest text] [--blocked text] [--blocked-kind text] [--safe-retry text] [--fix-first-item text] [--remaining-task text] [--recommended-direction text] [--implementation-note text] [--why-this-next text] [--blocked-by text] [--owner-route route] [--owner-scope text] [--scope-owner text] [--side-effect text] [--truth status] [--intent-label read_only|write|destructive|runtime|visual|publish] [--issue-code text] [--issue-role text] [--issue-symptom text] [--changed-code text] [--changed-role text] [--change-summary text] [--why-important text] [--learning-note text] [--json]
|
|
1975
1981
|
`);
|
|
1976
1982
|
}
|
|
1977
1983
|
|
|
1978
1984
|
async function loopReport(args = []) {
|
|
1979
1985
|
if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h') return loopUsage();
|
|
1980
|
-
const flags = parseSimpleFlags(args, new Set(['route', 'intent', 'loop-kind', 'stage', 'evidence', 'blocked', 'blocker', 'next-action', 'remaining-task', 'truth', 'intent-label', 'tool-intent', 'issue-code', 'issue-role', 'issue-symptom', 'changed-code', 'changed-role', 'change-summary', 'why-important', 'learning-note', 'json']));
|
|
1986
|
+
const flags = parseSimpleFlags(args, new Set(['route', 'intent', 'loop-kind', 'stage', 'stage-convention', 'evidence', 'evidence-level', 'evidence-stamp', 'source-digest', 'blocked', 'blocker', 'blocked-kind', 'next-action', 'safe-retry', 'fix-first-item', 'remaining-task', 'recommended-direction', 'direction', 'implementation-note', 'why-this-next', 'blocked-by', 'owner-route', 'owner-scope', 'scope-owner', 'owner', 'scope', 'side-effect', 'truth', 'intent-label', 'tool-intent', 'issue-code', 'issue-role', 'issue-symptom', 'changed-code', 'changed-role', 'change-summary', 'why-important', 'learning-note', 'json']));
|
|
1981
1987
|
const blockers = [...arrayFlag(flags.blocked), ...arrayFlag(flags.blocker)];
|
|
1982
1988
|
const report = buildLoopReport({
|
|
1983
1989
|
route: normalizeRoute(flags.route) || String(flags.route || ''),
|
|
1984
1990
|
intent: String(flags.intent || ''),
|
|
1985
1991
|
loop_kind: String(flags.loop_kind || flags.route || 'harness'),
|
|
1992
|
+
stage_conventions: arrayFlag(flags.stage_convention),
|
|
1986
1993
|
stages: arrayFlag(flags.stage),
|
|
1987
1994
|
evidence: arrayFlag(flags.evidence),
|
|
1995
|
+
evidence_level: normalizeLoopEvidenceLevelFlag(flags.evidence_level),
|
|
1996
|
+
evidence_stamp: String(flags.evidence_stamp || ''),
|
|
1997
|
+
source_digest: String(flags.source_digest || ''),
|
|
1988
1998
|
blockers,
|
|
1999
|
+
blocked_kind: String(flags.blocked_kind || ''),
|
|
1989
2000
|
truth_status: isTruthStatus(flags.truth) ? flags.truth : undefined,
|
|
1990
2001
|
intent_label: normalizeToolIntent(flags.intent_label || flags.tool_intent || 'read_only'),
|
|
1991
2002
|
next_action: String(flags.next_action || ''),
|
|
2003
|
+
safe_retry: String(flags.safe_retry || ''),
|
|
2004
|
+
fix_first_items: arrayFlag(flags.fix_first_item),
|
|
1992
2005
|
remaining_tasks: arrayFlag(flags.remaining_task),
|
|
2006
|
+
recommended_direction: String(flags.recommended_direction || flags.direction || ''),
|
|
2007
|
+
implementation_notes: arrayFlag(flags.implementation_note),
|
|
2008
|
+
why_this_next: String(flags.why_this_next || ''),
|
|
2009
|
+
blocked_by: arrayFlag(flags.blocked_by),
|
|
2010
|
+
owner_route: String(flags.owner_route || flags.route || ''),
|
|
2011
|
+
owner_scope: [...arrayFlag(flags.owner_scope), ...arrayFlag(flags.scope)],
|
|
2012
|
+
scope_owner: String(flags.scope_owner || flags.owner || ''),
|
|
2013
|
+
side_effects: arrayFlag(flags.side_effect),
|
|
1993
2014
|
issue_code: String(flags.issue_code || ''),
|
|
1994
2015
|
issue_role: String(flags.issue_role || ''),
|
|
1995
2016
|
issue_symptom: String(flags.issue_symptom || ''),
|
package/src/lib/trust-kernel.ts
CHANGED
|
@@ -18,6 +18,7 @@ export type RuntimeSubsystem = 'real_runtime' | 'tmux_physical' | 'process_clean
|
|
|
18
18
|
export type RuntimeBackend = 'none' | 'in_app_browser' | 'playwright' | 'terminal' | 'tmux' | 'zellij' | 'unknown';
|
|
19
19
|
export type RuntimeClaim = 'not_started' | 'started' | 'observed' | 'stopped' | 'cleanup_verified' | 'blocked' | 'unknown';
|
|
20
20
|
export type LoopStageStatus = 'passed' | 'failed' | 'blocked' | 'skipped' | 'partial' | 'pending' | 'recorded';
|
|
21
|
+
export type LoopEvidenceLevel = 'none' | 'fixture' | 'smoke' | 'local' | 'real';
|
|
21
22
|
export type ToolIntent = 'read_only' | 'write' | 'destructive' | 'runtime' | 'visual' | 'publish';
|
|
22
23
|
|
|
23
24
|
export interface SafetyHit {
|
|
@@ -182,14 +183,29 @@ export interface LoopReport {
|
|
|
182
183
|
route: string;
|
|
183
184
|
intent: string;
|
|
184
185
|
loop_kind: string;
|
|
186
|
+
stage_conventions: string[];
|
|
185
187
|
stages: LoopStage[];
|
|
186
188
|
evidence: string[];
|
|
189
|
+
evidence_level: LoopEvidenceLevel;
|
|
190
|
+
evidence_stamp: string;
|
|
191
|
+
source_digest: string;
|
|
187
192
|
blockers: string[];
|
|
193
|
+
blocked_kind: string;
|
|
188
194
|
truth_status: TruthStatus;
|
|
189
195
|
intent_label: ToolIntent;
|
|
190
196
|
tool_intent: ToolIntent;
|
|
191
197
|
next_action: string;
|
|
198
|
+
safe_retry: string;
|
|
199
|
+
fix_first_items: string[];
|
|
192
200
|
remaining_tasks: string[];
|
|
201
|
+
recommended_direction: string;
|
|
202
|
+
implementation_notes: string[];
|
|
203
|
+
why_this_next: string;
|
|
204
|
+
blocked_by: string[];
|
|
205
|
+
owner_route: string;
|
|
206
|
+
owner_scope: string[];
|
|
207
|
+
scope_owner: string;
|
|
208
|
+
side_effects: string[];
|
|
193
209
|
study_note: StudyNote;
|
|
194
210
|
}
|
|
195
211
|
|
|
@@ -535,9 +551,14 @@ export function buildLoopReport(input: Partial<LoopReport> & Record<string, unkn
|
|
|
535
551
|
: [];
|
|
536
552
|
const evidence = asList(input.evidence);
|
|
537
553
|
const blockers = asList(input.blockers || input.blocked);
|
|
554
|
+
const blockedBy = asList(input.blocked_by);
|
|
555
|
+
const blockedKind = shortText(input.blocked_kind || (blockers.length || blockedBy.length ? 'evidence_missing' : ''));
|
|
556
|
+
const evidenceStamp = shortText(input.evidence_stamp || input.source_digest, 320);
|
|
557
|
+
const sourceDigest = shortText(input.source_digest || input.evidence_stamp, 320);
|
|
538
558
|
const hasBlockedStage = stages.some((stage) => stage.status === 'blocked' || stage.status === 'failed');
|
|
559
|
+
const hasBlockerSignal = Boolean(blockers.length || blockedBy.length || blockedKind);
|
|
539
560
|
const requestedTruth = isTruthStatus(input.truth_status) ? input.truth_status : '';
|
|
540
|
-
const derivedTruth: TruthStatus =
|
|
561
|
+
const derivedTruth: TruthStatus = hasBlockerSignal || hasBlockedStage ? 'blocked'
|
|
541
562
|
: evidence.length && stages.some((stage) => stage.status === 'passed') ? 'verified'
|
|
542
563
|
: evidence.length || stages.length ? 'partial'
|
|
543
564
|
: 'assumed';
|
|
@@ -550,14 +571,31 @@ export function buildLoopReport(input: Partial<LoopReport> & Record<string, unkn
|
|
|
550
571
|
route: String(input.route || ''),
|
|
551
572
|
intent: shortText(input.intent),
|
|
552
573
|
loop_kind: String(input.loop_kind || 'harness'),
|
|
574
|
+
stage_conventions: asList(input.stage_conventions || input.stage_convention).length
|
|
575
|
+
? asList(input.stage_conventions || input.stage_convention)
|
|
576
|
+
: ['brief', 'plan', 'implement', 'critique', 'verify', 'handoff'],
|
|
553
577
|
stages,
|
|
554
578
|
evidence,
|
|
579
|
+
evidence_level: normalizeLoopEvidenceLevel(input.evidence_level),
|
|
580
|
+
evidence_stamp: evidenceStamp,
|
|
581
|
+
source_digest: sourceDigest,
|
|
555
582
|
blockers,
|
|
583
|
+
blocked_kind: blockedKind,
|
|
556
584
|
truth_status: truth,
|
|
557
585
|
intent_label: intentLabel,
|
|
558
586
|
tool_intent: intentLabel,
|
|
559
|
-
next_action: shortText(input.next_action || (
|
|
587
|
+
next_action: shortText(input.next_action || (hasBlockerSignal ? 'resolve the blocker before claiming this loop complete' : 'record the next smallest useful action')),
|
|
588
|
+
safe_retry: shortText(input.safe_retry || (hasBlockerSignal ? 'retry only after the blocker is resolved and new evidence is recorded' : 'not required')),
|
|
589
|
+
fix_first_items: asList(input.fix_first_items || input.fix_first_item),
|
|
560
590
|
remaining_tasks: asList(input.remaining_tasks || input.remaining_task),
|
|
591
|
+
recommended_direction: shortText(input.recommended_direction || input.direction),
|
|
592
|
+
implementation_notes: asList(input.implementation_notes || input.implementation_note),
|
|
593
|
+
why_this_next: shortText(input.why_this_next),
|
|
594
|
+
blocked_by: blockedBy,
|
|
595
|
+
owner_route: normalizeOwnerRoute(input.owner_route || input.route),
|
|
596
|
+
owner_scope: asList(input.owner_scope || input.scope),
|
|
597
|
+
scope_owner: normalizeOwnerRoute(input.scope_owner || input.owner),
|
|
598
|
+
side_effects: asList(input.side_effects || input.side_effect),
|
|
561
599
|
study_note: studyNote
|
|
562
600
|
};
|
|
563
601
|
}
|
|
@@ -676,6 +714,18 @@ function normalizeToolIntentLabel(value: unknown = ''): ToolIntent {
|
|
|
676
714
|
return 'read_only';
|
|
677
715
|
}
|
|
678
716
|
|
|
717
|
+
function normalizeOwnerRoute(value: unknown = ''): string {
|
|
718
|
+
const text = String(value || '').trim().replace(/^\$/, '').replace(/^yam-/, '');
|
|
719
|
+
if (['quick', 'ueye', 'question', 'scout', 'deep', 'mission'].includes(text)) return `$${text}`;
|
|
720
|
+
return text ? shortText(text, 80) : '';
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
function normalizeLoopEvidenceLevel(value: unknown = ''): LoopEvidenceLevel {
|
|
724
|
+
const text = String(value || '').toLowerCase().replace(/[-\s]/g, '_');
|
|
725
|
+
if (['fixture', 'smoke', 'local', 'real'].includes(text)) return text as LoopEvidenceLevel;
|
|
726
|
+
return 'none';
|
|
727
|
+
}
|
|
728
|
+
|
|
679
729
|
function shortText(value: unknown = '', limit = 240): string {
|
|
680
730
|
const text = String(value || '').trim().replace(/\s+/g, ' ');
|
|
681
731
|
if (text.length <= limit) return text;
|
package/yam.manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yam",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"principles": [
|
|
5
5
|
"Direction before execution.",
|
|
6
6
|
"Start fast.",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"Token-aware by default.",
|
|
12
12
|
"Context-reuse first.",
|
|
13
13
|
"End with remaining tasks and fix-first items.",
|
|
14
|
-
"Explain what failed, what changed, and why it matters in short non-specialist language when useful."
|
|
14
|
+
"Explain what failed, what changed, and why it matters in short non-specialist language when useful.",
|
|
15
|
+
"Use handoff notes for fix-first items, remaining tasks, recommended next direction, blocker kind, safe retry, evidence level, and owner scope when useful."
|
|
15
16
|
],
|
|
16
17
|
"defaultHooks": false,
|
|
17
18
|
"routes": [
|