@llblab/pi-actors 0.56.0 → 0.57.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 (38) hide show
  1. package/AGENTS.md +9 -9
  2. package/BACKLOG.md +4 -23
  3. package/CHANGELOG.md +13 -0
  4. package/README.md +5 -2
  5. package/dist/lib/execution-output.js +13 -2
  6. package/dist/lib/observability.js +9 -14
  7. package/dist/lib/registry.js +132 -157
  8. package/dist/lib/run-ui-runtime.js +18 -27
  9. package/dist/lib/runs-process-windows-mi.d.ts +71 -0
  10. package/dist/lib/runs-process-windows-mi.js +146 -3
  11. package/dist/lib/tools-inspect.js +109 -59
  12. package/dist/lib/tools-local.js +16 -8
  13. package/dist/lib/tools-message.js +76 -65
  14. package/dist/lib/tools-response.d.ts +18 -0
  15. package/dist/lib/tools-response.js +88 -21
  16. package/dist/lib/tools-spawn.js +19 -12
  17. package/dist/skills/actors/SKILL.md +3 -3
  18. package/dist/skills/actors/references/diagnostics.md +3 -0
  19. package/docs/README.md +1 -0
  20. package/docs/actor-inspector.md +2 -2
  21. package/docs/agent-experience.md +9 -1
  22. package/docs/inactive-foundations-inventory.md +73 -0
  23. package/docs/inspection.md +9 -8
  24. package/docs/output-projection-map.md +16 -14
  25. package/docs/windows-process-observation.md +2 -2
  26. package/lib/execution-output.ts +13 -2
  27. package/lib/observability.ts +9 -11
  28. package/lib/registry.ts +138 -164
  29. package/lib/run-ui-runtime.ts +18 -34
  30. package/lib/runs-process-windows-mi.ts +167 -3
  31. package/lib/tools-inspect.ts +109 -59
  32. package/lib/tools-local.ts +26 -15
  33. package/lib/tools-message.ts +85 -58
  34. package/lib/tools-response.ts +97 -20
  35. package/lib/tools-spawn.ts +19 -12
  36. package/package.json +1 -1
  37. package/skills/actors/SKILL.md +3 -3
  38. package/skills/actors/references/diagnostics.md +3 -0
@@ -0,0 +1,73 @@
1
+ # Inactive Foundations Inventory
2
+
3
+ Status: evidence inventory for a future removal decision. **Nothing is removed or activated by this document.** Its job is to separate reviewed runtime dependencies from packaged foundations that no default path currently drives, so a later cleanup is decided by wiring, consumers and guards rather than by filename or a disabled default.
4
+
5
+ Canonical open work and gates live in [BACKLOG.md](../BACKLOG.md); this file records the reachability/package facts those gates depend on.
6
+
7
+ ## Method
8
+
9
+ - **Entry and wiring:** read `index.ts` (the packaged artifact entry) and `lib/extension-runtime.ts` to see which ports an ordinary `createActorExtensionRuntime(pi)` call supplies.
10
+ - **Static reachability:** parse every `./x.ts` import (static and dynamic) across `index.ts` and `lib/`, then walk from the entry.
11
+ - **Packaging:** compare against the real npm manifest with `npm pack --dry-run --json`.
12
+ - **Parity:** `npm run build:check` proves `dist/` matches source; the packed/installed test family replays the compiled tree.
13
+ - **CI references:** `.github/workflows/*` shows which non-packaged sources a research workflow still builds.
14
+
15
+ Repeatable reachability check (same result as recorded below):
16
+
17
+ ```sh
18
+ node -e '
19
+ const fs=require("node:fs"),path=require("node:path");
20
+ const files=["index.ts",...fs.readdirSync("lib").filter(f=>f.endsWith(".ts")).map(f=>"lib/"+f)];
21
+ const g=new Map();
22
+ for(const f of files){const t=fs.readFileSync(f,"utf8"),d=new Set();
23
+ for(const m of t.matchAll(/(?:from|import\()\s*"(\.[^"]+\.ts)"/gu))d.add(path.normalize(path.join(path.dirname(f),m[1])));
24
+ g.set(f,[...d]);}
25
+ const seen=new Set(),stack=["index.ts"];
26
+ while(stack.length){const c=stack.pop();if(seen.has(c))continue;seen.add(c);for(const d of g.get(c)??[])stack.push(d);}
27
+ const lib=files.filter(f=>f.startsWith("lib/"));
28
+ console.log("entry-reachable:",lib.filter(f=>seen.has(f)).length+"/"+lib.length);
29
+ console.log("unreachable:",lib.filter(f=>!seen.has(f)).map(f=>f.slice(4)).join(" ")||"(none)");
30
+ '
31
+ ```
32
+
33
+ ## Current measurements
34
+
35
+ | Fact | Value |
36
+ | --- | --- |
37
+ | `lib/` TypeScript modules | 87 |
38
+ | Reachable from `index.ts` | 85 |
39
+ | Entry-unreachable but packaged | `runs-process-windows-mi.ts`, `preflight-diagnostics.ts` |
40
+ | npm tarball (0.56.1 candidate) | 452 files |
41
+ | `dist/` parity | `build:check` current |
42
+
43
+ ## Reviewed runtime dependencies (must not be treated as dead)
44
+
45
+ | Owner | Why it is a real dependency |
46
+ | --- | --- |
47
+ | Most `lib/` modules | Reachable from `index.ts` through the extension runtime, tools, delivery or Inspector wiring. |
48
+ | `preflight-diagnostics.ts` | Entry-unreachable yet packaged **and used** by the packaged `scripts/async-runner.mjs` via dynamic import; the preflight path is a supported script surface, not a leftover. |
49
+ | `run-delivery.ts` `ax_records` / `completion_yaml_core_v1` paths | The active fresh completion capture; only the *numbered stream* part of this owner is inactive. |
50
+
51
+ ## Packaged foundations with no default driver
52
+
53
+ | Foundation | Owner(s) | Consumer today | Default wiring | Interleaved guard | Activation gate |
54
+ | --- | --- | --- | --- | --- | --- |
55
+ | Independent supervision / owner-loss authority | `run-supervision.ts`, `runs-supervision.ts` | `extension-runtime.ts` only when optional `supervisionPorts` are supplied; `index.ts` supplies none, so `getRunAdmissionObserver` returns `undefined` and no owner is constructed | Off | Optional-dependency contract; controller ports require an unadopted original-clock/native-scope carrier | A/B/C then `D1` (BACKLOG §4) |
56
+ | Public completion streams / session-wide numbering | `run-delivery.ts` stream section, `run-ui-runtime.ts` admission hooks | Optional `completionStreamSessionAdmission` / `captureCompletionBatch`; no production provider. Kernel-only capture additionally requires an existing valid stream journal | Off | Missing/corrupt stream state stays unavailable rather than starting at zero; packet-local indices remain authoritative for saved bytes | `S1.1`–`S1.4` (BACKLOG §3) |
57
+ | Native launch ledger | `runs-native-launches.ts` | Called by `runs-control/results/start/retention`, but only through the private `readPendingCommandSpawnAdmission()` claim inside `withRunWorkAdmission`; ordinary launches never populate it | Inert | `assertNoRetainedNativeLaunchScope` fences start/retention against stale native scope; a recorded native admission is single-claim | `C1`/`C2`/`D1` |
58
+ | Native Windows MI reader | `runs-process-windows-mi.ts` | **No production importer**: the shipped fresh-process reader is inline PowerShell in `runs-process.ts` with the corrected UTF-8 decoding | Inert | Kept separate from the released reader so a prototype cannot silently replace it; unsupported UTC admission stays refused | `N1.2p`, `N1.3`, `N1.6` (BACKLOG §7) |
59
+ | Native helper source | `native/windows-mi/windows-mi.cpp` | Only `.github/workflows/windows-native-observation.yml` (research build); **not in the npm manifest** | Not shipped | Container is research-only; manifest-bound provenance/asset decision is unadopted | `N1.3`, `N1.5` |
60
+ | Evidence/context export roles beyond the selected subset | `runs-context-exports.ts`, `runs-execution-evidence.ts`, `runs-session-exports.ts`, `run-evidence-policy.ts` | Reachable, but only the selected reference/role subsets publish; broader retention/selection predicates stay gated | Partial | Producer/privacy/identity fences and explicit unavailability instead of fabricated bodies | `A3.1`/`A3.2`/`A3.3` |
61
+ | MPRIS playback surface | none (no `lib/` module) | — | Absent | Music playback stays behind the existing `music-player` singleton Control surface | `M1.1`–`M1.4` (BACKLOG §5) |
62
+ | Portable composition bundles / CodeMode | none (no `lib/` module) | — | Absent | Recorded as design intake only; host CodeMode calls existing tools | `T1.1`–`T1.3` (BACKLOG §6) |
63
+
64
+ ## Consequences for a removal decision
65
+
66
+ - A file being default-off is not evidence of dead code: supervision, stream numbering and the native ledger all sit behind optional ports or private admissions that are exercised by tests.
67
+ - Removing any row above would also remove a **guard** (unavailable-not-zero, stale native scope refusal, single-claim admission) that the active paths rely on for their refusals.
68
+ - The only rows with no runtime consumer at all are the native MI reader, the native helper source, MPRIS and the composition transport; each already carries its own backward gate, so removal stays a separate, explicitly justified decision.
69
+ - `preflight-diagnostics.ts` must never be classified by entry reachability alone.
70
+
71
+ ## Open decision
72
+
73
+ No removal is authorized here. A later cleanup should pick concrete rows, restate which gate replaces their guard, and re-run the reachability, `build:check` and packed/installed evidence for its own tree.
@@ -12,22 +12,22 @@ The shared compact Run status/default view in [Run supervision](./run-supervisio
12
12
  | --- | --- | --- |
13
13
  | `run:<id>` | `recipe`, `trace`, `control` | Inspect one accessible Run generation |
14
14
  | `runtime` | `status`, `runs`, `triage` | Inspect package policy, owned Run inventory, or aggregate operational pressure |
15
- | `recipes` | `status`, `summary`, `doctor`, `imports`, `reviews` | Inspect user Recipe discovery, active Skill components, exact resolution, imports, and automatic-review recovery |
15
+ | `recipes` | `status`, `summary`/`registry`, `doctor`, `imports`, `reviews` | Inspect user Recipe discovery, active Skill components, exact resolution, imports, and automatic-review recovery |
16
16
  | `tool:<name>` | `status`, `schema` | Inspect persistent-tool activation/usage or its current callable schema |
17
17
 
18
- `verbose=false` normally returns compact text and `verbose=true` returns structured details. `tool:<name> view=schema` is always structured because its callable parameter schema has no useful compact equivalent.
18
+ `verbose=false` normally returns compact YAML and `verbose=true` returns JSON without evaluating the compact formatter. `tool:<name> view=schema` always returns the structured callable definition: bare YAML with native parameter nodes when renderable, otherwise the exact legacy JSON fallback; explicit verbose output stays JSON.
19
19
 
20
- Fresh compact Run/tool/Recipe responses now use flat AX records. Run views retain only the existing run/view header, not a new default Run status or automatic evidence body. Tool status preserves activation/callability/source/usage facts and renders required/optional argument names as real sequences, including a single item; none and unknown remain distinct. Recipe registry retains its original count/current-policy/partial-catalog facts. Focused doctor adds no source exposure: the already-portable source_location is kept whole inside the existing literal renderer, with exact identity/resolution/rejection values and opaque multiline Markdown.
20
+ Fresh compact Run/tool/Recipe responses use bare block-YAML metadata. Run views retain only the existing run/view header, not a new default Run status or automatic evidence body. Tool status preserves activation/callability/source/usage facts and renders required/optional argument names as real sequences, including a single item; none and unknown remain distinct. Selected scalars and complete argument groups fit the 16 KiB compact allowance or carry explicit whole-field/group omission coverage; malformed selected text is unavailable without repair. Recipe registry retains its original count/current-policy/partial-catalog facts. Focused doctor adds no source exposure: the already-portable source_location is kept as a whole quoted scalar or explicitly omitted, with exact identity/resolution/rejection values and opaque multiline Markdown.
21
21
 
22
- Compact text selects at most the first existing hint. Only exact recipes doctor, imports verbose=true or summary verbose=true inspect strings become a typed read-only next node; any other string, including call/spawn/register advice, stays an opaque instruction value without whitespace normalization or command parsing. No hint executes, repairs arguments or grants scope. Full next_actions and all machine fields remain unchanged in details/verbose JSON. No new global output cap, truncated reference, reader or source budget is added. Runtime compact rendering now likewise uses flat fields: status keeps version/schema/review policy, runs keeps the complete exact-owner inventory count, and triage keeps its existing failure/control/backpressure/Trace/attention counts. A240-row controlled owned inventory remains240even with lines=1; verbose navigation remains independent, while triage pending66does not shrink to its40detail rows. There is no new snapshot/default status, duration, source reader/cap or routine next action. The source/installed owners verify this subset, not actual loaded phone/terminal rendering.
22
+ Compact text selects at most the first existing hint. Only exact recipes doctor, imports verbose=true or summary verbose=true inspect strings become a typed read-only next node; any other string, including call/spawn/register advice, stays an opaque instruction value without whitespace normalization or command parsing. No hint executes, repairs arguments or grants scope. Full next_actions and all machine fields remain unchanged in details/verbose JSON. No new global output cap, truncated reference, reader or source budget is added. Runtime compact rendering likewise uses bare YAML fields: status keeps version/schema/review policy, runs keeps the complete exact-owner inventory count, and triage keeps its existing failure/control/backpressure/Trace/attention counts. A240-row controlled owned inventory remains240even with lines=1; verbose navigation remains independent, while triage pending66does not shrink to its40detail rows. There is no new snapshot/default status, duration, source reader/cap or routine next action. The source/installed owners verify this subset, not actual loaded phone/terminal rendering.
23
23
 
24
24
  ## Locally authored request errors
25
25
 
26
- The ten refusal sites owned by tools-inspect now use flat AX errors for unsupported target/view/Trace source, invalid tool target, misplaced Recipe identity, missing registered tool and unavailable callable schema. Supported target/view/source choices are real lists, including a one-item list where appropriate. target_kind is only the selector family, not proof of owner admission. Request strings and selected activation facts remain opaque values; authored next/tool lines gain no action authority. Missing-tool refusal retains the no-spawn-substitution safety note and its known Recipe doctor next; unavailable schema retains callability/activation defaults and its known tool-status next. Other guards add no routine hint. The compact success hint recognizer remains the same closed three Recipe literals, not a general command parser.
26
+ The ten refusal sites owned by tools-inspect use bare block-YAML errors for unsupported target/view/Trace source, invalid tool target, misplaced Recipe identity, missing registered tool and unavailable callable schema. Supported target/view/source choices are real lists, including a one-item list where appropriate. target_kind is only the selector family, not proof of owner admission. Request strings and selected activation facts remain opaque values; authored next/tool lines gain no action authority. Missing-tool refusal retains the no-spawn-substitution safety note and its known Recipe doctor next; unavailable schema retains callability/activation defaults and its known tool-status next. Other guards add no routine hint. The compact success hint recognizer remains the same closed three Recipe literals, not a general command parser.
27
27
 
28
- These new owned error texts share the existing16KiB model-text allowance, including the unchanged public adapter's single leading LF. Fixed compiler facts/lists and safety reserve space; each variable starts with the shorter complete value or omission row, so later admission cannot shrink the baseline and falsely justify an omission. Optional complete next is retained if it fits with that baseline, then whole variable fields are selected in source order. An unfit scalar has field-local state=omitted/reason=response_too_large/shown=0/omitted=1/total=1, never a shortened target or raw/private character count. An unfit action has next_action omission coverage rather than a fake next command. This is a new presentation bound for these local errors only, not an input/source/work quota, successful inspect cap or new machine schema. Direct Error.message stays unprefixed until the existing adapter applies spacing; malformed request strings are not repaired or assigned scalar-completeness proof.
28
+ These new owned error texts share the existing16KiB model-text allowance, including the unchanged public adapter's single leading LF. Fixed compiler facts/lists and safety reserve space; each variable starts with the shorter complete value or omission row, so later admission cannot shrink the baseline and falsely justify an omission. Optional complete next is retained if it fits with that baseline, then whole variable fields are selected in source order. An unfit scalar has field-local state=omitted/reason=response_too_large/shown=0/omitted=1/total=1, never a shortened target or raw/private character count. An unfit action has next_action omission coverage rather than a fake next command. This presentation bound is not an input/source/work quota or new machine schema; successful compact metadata has its own whole-field/group selection described above, while full JSON remains independent. Direct Error.message stays unprefixed until the existing adapter applies spacing; malformed request strings are not repaired or assigned scalar-completeness proof.
29
29
 
30
- Validation order, callbacks/getters/String observations, basic Error type/construction sites and successful details/verbose/schema outputs stay unchanged. No catch-all intercepts dependency/authorization/session exceptions, preserves a guessed source id, exposes private causes or changes old fail-soft catches. Those errors retain their owning behavior rather than being relabeled AX. Recipe discovery/status hooks may already have executed before a later local refusal; this does not certify no effects, handling failure or safe replay. Source/installed whole-owner properties cover all ten branches in both verbose modes, exact byte boundary plus public spacing, whole-value/action omission, original exceptions including primitive/undefined/hostile getters, session-fence precedence and unchanged journals.
30
+ Refusal validation order, callbacks/getters/String observations and basic Error type/construction sites stay unchanged. Machine details and verbose JSON retain their contracts; generated schema text follows the YAML/fallback rule above. No catch-all intercepts dependency/authorization/session exceptions, preserves a guessed source id, exposes private causes or changes old fail-soft catches. Those errors retain their owning behavior rather than being relabeled AX. Recipe discovery/status hooks may already have executed before a later local refusal; this does not certify no effects, handling failure or safe replay. Source/installed whole-owner properties cover all ten branches in both verbose modes, exact byte boundary plus public spacing, whole-value/action omission, original exceptions including primitive/undefined/hostile getters, session-fence precedence and unchanged journals.
31
31
 
32
32
  ## Run Targets
33
33
 
@@ -89,13 +89,14 @@ Controlled partial-preview/Unicode and genuine-private-writer-from-controlled-re
89
89
  ```text
90
90
  inspect target=recipes view=status
91
91
  inspect target=recipes view=summary
92
+ inspect target=recipes view=registry
92
93
  inspect target=recipes view=doctor identity=music-player/playback
93
94
  inspect target=recipes view=imports verbose=true
94
95
  inspect target=recipes view=reviews verbose=true
95
96
  ```
96
97
 
97
98
  - `status` reports registry/watch state, active/shadowed/invalid/disabled user Recipes, active Skill components, drafts, usage, and diagnostics.
98
- - `summary` returns the compact discovery-oriented projection of the same current context.
99
+ - `summary` returns the compact discovery-oriented projection of the same current context. `registry` is the same inspection path under a second accepted view name: with identical `verbose` and other inputs it returns identical facts, details and rendering, so only `verbose` selects compact text versus structured output. The compact label stays `recipes: registry` for both names.
99
100
  - `doctor` diagnoses one canonical `<skill>/<recipe>` identity when `identity` is provided; without an identity it reports registry remediation evidence.
100
101
  - `imports` exposes active Skill namespaces and component import inventory for resolution diagnosis.
101
102
  - `reviews` exposes bounded automatic draft/tool review state and recovery guidance.
@@ -37,43 +37,45 @@ Terminal observation -> frozen completion/attention capture
37
37
 
38
38
  ### 3. Synchronous Registered Output and Local Usage/Launch Errors
39
39
 
40
- - **Owners:** `tools-spawn.ts:86` `spawnGuardText` / `:106` `runIdFromTarget`; `tools-local.ts:69` `formatRuntimeToolUsageHint`, `:128` `formatRuntimeToolArgumentError`, and execute's `dispatchEntered` cutoff. `lib/execution.ts:1081` `executeRegisteredTool` returns selected `formatted.text` plus machine details at `:1142`.
41
- - **Current:** Local guards are pseudo-fields; usage guidance mixes prose, JSON call examples and argument lists. `lib/execution-output.ts:91` `formatOutput` and `:112` `formatFailureOutput` own stdout/stderr trim/tail selection, runtime labels and truncation notices.
42
- - **Target / guard:** Owned guard/guidance facts become YAML. Actual JSON invocation examples remain instructional source; selected command/report JSON remains content. If separately selected body text is present, use a delimited header without changing existing source selection. Do not claim current formatted tails are original complete stdout. After executor entry/async handoff, the local catch preserves its original failure rather than treating wording as a repairable argument error. Host schema/clone/coercion errors may occur before facade guards.
40
+ - **Owners:** `tools-spawn.ts:86` `spawnGuardText` / `:111` `runIdFromTarget`; `tools-local.ts:71` `runtimeToolUsageMetadata`, `:84` `formatRuntimeToolUsageHint`, `:137` `formatRuntimeToolArgumentError`, and execute's `dispatchEntered` cutoff. `lib/execution.ts:1081` `executeRegisteredTool` returns selected `formatted.text` plus machine details at `:1142`.
41
+ - **Current:** Owned guard and usage facts are bare block YAML through the shared `renderYamlMetadata`/`frameMetadataDocument` primitives. Pre-launch spawn guards present `field`/`result`/`accepted_format`/`id_rule` with one whole selected `value` or an explicit `value_omission` record. The pre-dispatch argument-repair error presents `tool`/`required`/`optional` in a closed `---` header, then the original validation prose and the verbatim `JSON.stringify` invocation example at the left margin. `lib/execution-output.ts` `formatFailureOutput` emits `exit_code`/`killed` metadata with a delimited header before the unchanged `stderr:`/`stdout:` bodies, and a failure with no selected stream text stays metadata-only bare YAML instead of an invented body. `formatOutput` still owns trim/tail selection, the truncation notice and full-output temp file; the leading LF remains host invocation spacing.
42
+ - **Target / guard:** Owned guard/guidance facts are YAML. Actual JSON invocation examples remain instructional source and are never parsed or reserialized; the validation prose stays body content. If separately selected body text is present, one delimited header separates it without changing existing source selection. Do not claim current formatted tails are original complete stdout. After executor entry/async handoff, the local catch preserves its original failure rather than treating wording as a repairable argument error. Host schema/clone/coercion errors may occur before facade guards. Exit-status metadata is not a native/closure or signal-authenticity claim, and stream bodies are never parsed back into fields.
43
43
  - **Proof owners:** `tests/tools-spawn.test.ts`, `tests/tools-local.test.ts`, `tests/tools.test.ts:304`, `tests/execution-output.test.ts`; packed dispatch-failure preservation at installed `:2656`.
44
44
 
45
45
  ### 4. Control Receipts and Public Failures
46
46
 
47
- - **Owners:** `lib/tools-message.ts:23` `controlGuardText`, `:66` `compactControlResult`, `:120` `createControlToolDefinition`; conservative actor-local failure catch at `:224`, replacement-state withholding at `:246–248`, verbose JSON at `:258`.
48
- - **Current:** Pseudo-fields distinguish request, delivery, handling, legacy kill attempt/closure uncertainty and one selected next action. Verbose text is JSON of request/result, also retained separately as machine `details`; exact cause chains stay private.
49
- - **Target / guard:** Metadata-only receipts/refusals become bare YAML, including native option sequences and nested verbose facts. Preserve whole identity/option bounds and existing caller facts. No private causes, inferred correlation, automatic retry, new recipient lease or no-effects/closure claim follows. Kill/archive/prune/dependency failures remain separately owned and may follow effects.
47
+ - **Owners:** `lib/tools-message.ts` `controlGuardText`, `compactControlResult`, `createControlToolDefinition`; conservative actor-local failure catch, replacement-state withholding and verbose JSON in the same file.
48
+ - **Current:** Receipts, guard refusals and the awaiting-dispatch failure notice are bare block YAML with native option sequences and a typed read-only `next` or one opaque `next.instruction`. Shared `tools-response` selection helpers keep whole selected values or explicit whole-field/sequence omission records under the existing16KiB cap including the public LF. Delivery/handling, legacy kill attempt/closure uncertainty and request distinctions are unchanged. Verbose text is still JSON of request/result, also retained separately as machine `details`; exact cause chains stay private.
49
+ - **Target / guard:** Metadata-only receipts/refusals stay bare YAML, including nested verbose facts when they migrate. Preserve whole identity/option bounds and existing caller facts. No private causes, inferred correlation, automatic retry, new recipient lease or no-effects/closure claim follows. Kill/archive/prune/dependency failures remain separately owned and may follow effects.
50
50
  - **Proof owners:** `tests/tools-message.test.ts` guard/host/refusal/privacy/context-change families; `tests/runs-control-delivery.test.ts` and awaited-Control cases in `tests/async-runs.test.ts`. YAML migration does not resolve those authority/transport gates.
51
51
 
52
52
  ### 5. Inspect: Compact, Verbose and Schema
53
53
 
54
54
  - **Owners:** `lib/tools-inspect.ts:188` `compactRuntime`, `:201` `formatInspectFailure`, `:508` `inspectRun`, `:597` `inspectTool`, `:637` `compactResult`, execute at `:728`; `tools-response.ts:436` `formatInspectionHint` / `:443` `compactRecipeRegistry`.
55
- - **Current:** Compact paths use pseudo-fields. **Every verbose view and `tool:* view=schema` even without verbose** selects generated pretty JSON. Compact Run views supply a run/view header, not a newly available body/status snapshot. Recipe/source hints and authored advice have distinct typed versus opaque paths.
56
- - **Target / guard:** Runtime-generated compact/verbose/JSON-Schema presentation becomes YAML. Underlying `tool.parameters` JSON Schema and machine details do not change. `view=schema` is generated definition metadata, not the literal-source-file exception. Preserve filtering/redaction, partiality, exact portable sources and selected next actions; no new read, default snapshot or timing route is authorized.
55
+ - **Current:** Refusals and compact success paths now render as bare block-YAML documents: the ten locally authored refusals use a field-local whole-field coverage record (`state: omitted`), and compact Run headers, runtime status/runs/triage, tool status and Recipe registry/doctor use native numbers/booleans/sequences with one typed read-only `next` or one opaque `next.instruction`. Opaque identity/source/boundary/advice scalars and complete required/optional argument sequences are whole or explicitly omitted through the shared `selectYamlField`/`growYamlDocument` owner under the same 16 KiB basis. Verbose JSON bypasses compact formatting, and emitter unavailability never becomes undefined text. The always-structured `tool:* view=schema` text is now the same bare block-YAML metadata (native `parameters` nodes, absent fields absent) while its machine `details` object stays unchanged JSON; a pathological schema beyond the shared emitter's execution ceiling keeps the exact legacy JSON text instead of being clipped. Compact Run views supply a run/view header, not a newly available body/status snapshot. Recipe/source hints and authored advice have distinct typed versus opaque paths.
56
+ - **Target / guard:** Remaining runtime-generated compact/verbose/JSON-Schema presentation becomes YAML. Underlying `tool.parameters` JSON Schema and machine details do not change. `view=schema` is generated definition metadata, not the literal-source-file exception. Preserve filtering/redaction, partiality, exact portable sources and selected next actions; no new read, default snapshot or timing route is authorized.
57
57
  - **Proof owners:** `tests/tools-inspect.test.ts` refusals, schemas, views, privacy, current-session navigation and failed-priority families; installed inspection contracts at `:2492`.
58
58
 
59
59
  ### 6. Registration, Listing, Deletion and Draft Promotion
60
60
 
61
61
  - **Owners:** `lib/tools-register.ts:61` delegates to Registry. `lib/registry.ts:94` `registryListText`, `:176` `registrationReceiptText`, `:352` `draftReceiptText`, `:501` `registryDeletionText` and their list/promote/delete/register transaction callers.
62
- - **Current:** Pseudo-fields and real selected sequences for tool/result/source/callability, args/warnings/names/coverage; source references may be fenced literals. Draft promotion has its own selected/coerced display facts. Delete has a manual reload note.
62
+ - **Current:** Source registration/update, listing, deletion/not-found and draft-promotion receipts use bare block YAML under the shared16KiB complete-response cap. Names/arguments/warnings are native sequences; empty selected lists stay `[]` and whole omissions/unavailability retain coverage. Normal callability is Boolean; draft keeps its selected display string. Source references stay exact scalar values, fitting warnings retain priority, and reload/invocation advice stays opaque. Independent review, compiled/package acceptance and loaded-host observation require separate evidence; source syntax does not establish them.
63
63
  - **Target / guard:** Metadata-only returns become bare YAML. Preserve actual persistence versus current callability, reuse of selected values, warning priority, whole-group omissions and source references. Do not normalize old flags into stronger activation truth. Formatting/notifier/unlink/reactivation failures may follow writes; a reload instruction is not permission to reload.
64
64
  - **Proof owners:** `tests/registry.test.ts` ordinary/draft/list/delete/activation-order families; `tests/registration-truth.test.ts` and installed registry/runtime owner replay.
65
65
 
66
66
  ### 7. Registry Refusals and Transaction Diagnostics
67
67
 
68
68
  - **Owners:** `registry.ts` `assertRegisterToolInputModes` (`:776`), `reservedRegistrationNameText` / `executeRegisterToolUnlocked` (`:827,:840`), `duplicateRegistrationText` (`:374`), `assertTemplateIsNotNestedRecipe` / `getInputTemplate` (`:588,:606`), `normalizeDefaults` / `buildAuthoredRecipe` (`:653,:702`). Selected error formatters are `draftPathFailureText`, `sourceNormalizationFailureText`, `candidateAdmissionFailureText`, `draftRecipeFailureText`, `registrationTransactionFailureText` (`:315,:279,:254,:384,:231`).
69
- - **Current → target:** Locally selected pseudo-record facts become bare YAML, with opaque selected advice/reasons/diagnostics and complete or explicitly omitted source literals. This is not a global exception wrapper.
69
+ - **Current:** Locally authored mode/name/source/template/draft/transaction refusals are bare block YAML through the shared `tools-response` `selectYamlField`/`growYamlDocument` helpers plus the local document builder: fixed fields stay compiler literals, choice sets stay native sequences, and each opaque selected value is one whole double-quoted scalar or an explicit whole-field omission record, seeded shorter and grown monotonically under the existing16KiB cap including the public LF. Authored text therefore stays scalar content with escaped line breaks rather than becoming metadata. Registry activation/promotion/deletion notice text (`registryNoticeText`) still uses flat report/tool fields and is not part of this refusal migration.
70
+ - **Target / guard:** Opaque selected advice/reasons/diagnostics remain whole or explicitly omitted; a syntax change must not turn authored text into keys or actions. This is not a global exception wrapper.
70
71
  - **Guard / proof:** Preserve guard/getter/String/join/Error order, existing diagnostic clipping, source-mode/duplicate predicates, cleanup and post-effect faults. A joined legacy diagnostic/summary is not a newly complete list; do not parse it into one or add raw causes/body/value echoes. Exact cases live in `tests/registry.test.ts` source/defaults/template/path/diagnostic/transaction groups; runtime/source/dependency failures retain their own owners.
71
72
 
72
73
  ### 8. Registry, Callback, Watcher and Teardown Notices
73
74
 
74
- - **Owners:** `registry.ts:224` `registryNoticeText`; `lib/runtime.ts:96` `notify`, `:189` `formatRecipeToolWarnings`, `:336` `createRecipeToolReloadWatcher`. Runtime callback/steer diagnostics are in `run-ui-runtime.ts:49,151,335,400,692`; watcher/retirement notices in `observability.ts:254,1007,1016`.
75
- - **Current → target:** Owned pseudo-record reports/category sequences/counts become bare YAML when metadata-only; selected diagnostics stay opaque. Keep the actual `ctx.ui.notify`/forwarding owner: runtime's notifier is `hasUI`-gated, but the reload watcher has direct notify sites. Progress/chrome is separate below.
76
- - **Guard / proof:** Do not add a model-output cap to uncapped UI text, expose raw causes, change callback/rearm/dedup or read new error properties. Retirement notification is inside the stop path, so notifier failure can follow effects. Steer UI preview versus persisted error bounds remain separate. `tests/runtime.test.ts`, `tests/registry.test.ts:74,113`, callback/teardown cases in `tests/run-ui-runtime.test.ts`, watcher/retirement cases in `tests/observability.test.ts` own these boundaries.
75
+ - **Owners:** `registry.ts` `registryNoticeText`; `lib/runtime.ts` `notify`, `formatRecipeToolWarnings`, `createRecipeToolReloadWatcher`. Runtime callback/steer/teardown notices are in `run-ui-runtime.ts` (`formatSteerDiagnosticMessage`, callback failure, completion recovery, steer recovery, shutdown teardown); watcher/retirement notices in `observability.ts`.
76
+ - **Current:** Runtime callback failure, completion recovery/acceptance, steer admission/delivery/recovery diagnostics and the shutdown teardown report are bare block-YAML metadata with native counters and an explicit receipt/report stage through the shared UI-only `formatYamlNotice` owner. Watcher and retirement notices use it too. These UI projections retain complete well-formed selected fields without borrowing model byte/depth ceilings; malformed selected text is explicitly unavailable. The 240-pair steer preview and its unknown-loss markers are unchanged, as is each existing leading-LF convention. Registry activation/promotion/deletion and startup warnings still use their flat report/category layout.
77
+ - **Target / guard:** Remaining owned pseudo-record reports/category sequences become bare YAML when metadata-only; selected diagnostics stay opaque. Keep the actual `ctx.ui.notify`/forwarding owner: runtime's notifier is `hasUI`-gated, but the reload watcher has direct notify sites. Progress/chrome is separate below.
78
+ - **Guard / proof:** Do not expose raw causes, change callback/rearm/dedup or read new error properties; a notice bound never truncates an identity or a diagnostic mid-value. Retirement notification is inside the stop path, so notifier failure can follow effects. Steer UI preview versus persisted error bounds remain separate. `tests/runtime.test.ts`, `tests/registry.test.ts`, callback/teardown/steer cases in `tests/run-ui-runtime.test.ts`, watcher/retirement cases in `tests/observability.test.ts` own these boundaries.
77
79
 
78
80
  ## Captured Delivery and UI
79
81
 
@@ -114,7 +116,7 @@ F1.6 source-audit correction: Pi 1.0 native custom-message storage, session reco
114
116
  ### 13. Inspector, Trace and Progress Chrome
115
117
 
116
118
  - **Owners:** `inspector-command.ts:13` command/UI entry; `inspector.ts:100,120,128` selected kill feedback and owner/generation action; `inspector-overlay.ts:411,467,490,640` kill/confirmation/popup recognition and `:743,804,826,896,919,935,945` list/detail/document projections. `trace-projection.ts:196,243,293` supplies observed Trace/Control/agent data; session privacy remains in `session-evidence.ts`. `observability.ts:935,947` → `run-ui-runtime.ts:504` owns animated status.
117
- - **Current:** Literal semantic documents use pseudo-records/nested sequences with ephemeral compiler-label provenance, selected text uses native wrapping, and popup coloring recognizes current anchored AX feedback. Trace previews retain existing normalization/160-unit selection and unknown-loss semantics. Stripes, ranks, paging, focus, animation and modal choice labels are UI chrome, not model serialization.
119
+ - **Current:** Literal semantic documents use pseudo-records/nested sequences with ephemeral compiler-label provenance, selected text uses native wrapping, and popup coloring recognizes current anchored AX feedback. Verified against every current Kill producer result: failed/rejected render as error, unavailable (state-only) as warning, and authored text that merely contains those header lines stays warning because only the exact leading pair counts. Trace previews retain existing normalization/160-unit selection and unknown-loss semantics. Stripes, ranks, paging, focus, animation and modal choice labels are UI chrome, not model serialization.
118
120
  - **Target / guard:** Owned document metadata is a YAML migration owner; do not interpret source lines as metadata or turn all chrome into YAML. Preserve original selected body/preview basis, columns/separators, safety/choices, frozen underlay and once-only generation action. A syntax change must update anchored feedback recognition without granting source labels meaning.
119
121
  - **Proof owners:** `tests/inspector.test.ts`, `tests/inspector-overlay.test.ts` documents/wrapping/Trace gaps/modal/safety families, `tests/trace-projection.test.ts`, session privacy and run-ui callback-animation tests. Headless/source tests do not prove actual terminal/phone rendering.
120
122
 
@@ -156,7 +156,7 @@ The native producer now has one unrouted source owner at `native/windows-mi/wind
156
156
 
157
157
  The complete private adapter will return validated legacy-shaped property rows and a closed acquisition outcome, never expected identities, verifier decisions, Run metadata or lifecycle capabilities. Its implemented observation stage retains typed timestamp components and raw optional-field facts explicitly as `decoded_unadmitted`, with no date-to-legacy promotion, process invocation, asset loading or profile-admission port. Initial raw-null refusal belongs before normalization; native producer properties and the asset/invocation seam are separate slices. This stage alone cannot supply a process identity or establish freshness. Scalar and shared profiles stay distinct; shared rows require unique exact selected-PID correlation regardless of result order. Preserve the consumed string/optional normalization above, including `.trim()` and UTF-16 code units, lone surrogates and non-BMP pairs. Unexpected MI types, missing required properties and unsupported representations make the entire optimized observation unusable; no stronger path lookup, argv reconstruction or identity-format migration is permitted.
158
158
 
159
- The same private owner separately implements `decodeProvenanceBinding` for an already parsed, flat JSON-value fragment with exactly `source_sha256`, `executable_sha256`, `executable_bytes`, `originating_source_commit` and `originating_build_job`. Complete lowercase ASCII hash/commit lexemes, positive safe-integer byte counts and exact positive decimal-string job identifiers decode into fresh primitive claims labeled `decoded_binding_unadmitted`; malformed fragments return only `unusable/invalid_binding`. Source and installed compiled properties cover those boundaries, including final line terminators and copy independence. This is not a complete manifest, trusted descriptor, byte reader or asset verifier: it checks no file/hash, authentic origin, compiler, dependency or profile and grants no execution permission. Full-manifest format/resource bounds, trusted exact-byte selection, fixed asset lookup and invocation remain separate preparation work; arbitrary executable JavaScript objects are outside this JSON-value contract.
159
+ The same private owner separately implements `decodeProvenanceBinding` for an already parsed, flat JSON-value fragment with exactly `source_sha256`, `executable_sha256`, `executable_bytes`, `originating_source_commit` and `originating_build_job`. Complete lowercase ASCII hash/commit lexemes, positive safe-integer byte counts and exact positive decimal-string job identifiers decode into fresh primitive claims labeled `decoded_binding_unadmitted`; malformed fragments return only `unusable/invalid_binding`. Source and installed compiled properties cover those boundaries, including final line terminators and copy independence. That fragment alone is not a complete manifest, trusted descriptor, byte reader or asset verifier: it checks no file/hash, authentic origin, compiler, dependency or profile and grants no execution permission; arbitrary executable JavaScript objects are outside this JSON-value contract. The same private owner now also carries the unrouted acquisition preparation: `readHelperManifest` (complete-manifest reader bounded at 32 KiB, one strict UTF-8 JSON document, exact reviewed key set, closed version/architecture/protocol/profile lexemes, positive safe-integer byte count capped at 8 MiB, bounded ASCII compiler/SDK/build-argument/dependency lexemes) returning fresh `manifest_unadmitted` claims; `resolveHelperAsset` (fixed versioned `native/windows-mi/win32-x64/<helper-version>/` lookup derived only from this module's own `lib/`/`dist/lib/` URL, refusing non-win32-x64 targets, non-semver versions and any other module path, with no cwd, PATH or caller location search); `loadHelperAsset` (injected bounded reader with a one-byte overflow probe for the complete manifest, exact declared executable size including its own one-byte growth probe, then exact SHA-256 equality, else a closed unusable reason); and `helperInvocation` (a shell-free `{command, args, options}` spec with the selected executable as `command` and only the profile/PIDs as `args` (the executable is not repeated as an argument), with `shell:false`/`windowsHide:true`, no spawn, retry, fallback or policy bypass). All of it stays unrouted: `runs-process.ts` keeps the shipped PowerShell acquisition, no package asset exists, and the raw-null refusal plus unsupported UTC-profile admission are unchanged.
160
160
 
161
161
  Do not promote the prototype's broad `candidateDate` range wholesale. The initial candidate is UTC-only; production eligibility requires a positively recognized environment/representation profile and real PowerShell serialization witnesses, including precision boundaries. An MI timestamp's zero offset alone, a runner label, a local JavaScript timezone or equality with an expected identity is not that predicate. The first experiment did not record a complete environment-admission witness. Establish the exact native environment/version facts and executable predicate in the broader differential before claiming a supported optimized profile; until that predicate is evidenced, keep profile admission unsupported. Non-UTC/historical profiles remain baseline-only unless separately admitted.
162
162
 
@@ -217,7 +217,7 @@ Deterministic ports and native producer properties separately cover PID boundari
217
217
 
218
218
  ### Preparation, shipping and activation boundaries
219
219
 
220
- The dependency-ready preparation is the unrouted private adapter/codec, mirrored properties, promoted native source and reviewed candidate artifact build/retention path. Keep the package's binary inventory unchanged until asset ownership is approved. No global SDK spawn interceptor or research-marker layer is justified by this integration question.
220
+ The dependency-ready preparation is the unrouted private adapter/codec and acquisition seam (manifest reader, exact-byte verifier, fixed versioned lookup, shell-free invocation spec), mirrored properties, promoted native source and reviewed candidate artifact build/retention path. Keep the package's binary inventory unchanged until asset ownership is approved. No global SDK spawn interceptor or research-marker layer is justified by this integration question.
221
221
 
222
222
  Before shipping assets, independently review codec/fallback, native resource closure and provenance/distribution, then verify source/dist lookup, offline normal build/prepack, package inventory and exact shipping-byte differential. Before default activation, separately admit the routing change and pass unchanged source-and-packed genuine SDK/native validation through the actual shipping path. The fixed Run layout, workloads, watchdogs, settlement/close/research boundaries, privacy/history/budgets and independently fresh checks remain those of the existing contract; standalone helper latency does not prove recovered SDK settlement.
223
223
 
@@ -10,6 +10,7 @@ import { join } from "node:path";
10
10
  import { sanitizeFilePart } from "./identity.ts";
11
11
  import * as Limits from "./limits.ts";
12
12
  import * as Paths from "./paths.ts";
13
+ import * as ToolsResponse from "./tools-response.ts";
13
14
 
14
15
  export interface FormattedOutput {
15
16
  text: string;
@@ -116,8 +117,18 @@ export function formatFailureOutput(
116
117
  stdout: string,
117
118
  stderr: string,
118
119
  ): FormattedOutput {
119
- const parts = [`Exit code ${code}${killed ? " (killed)" : ""}`];
120
+ const parts: string[] = [];
120
121
  if (stderr.trim()) parts.push(`stderr:\n${stderr.trimEnd()}`);
121
122
  if (stdout.trim()) parts.push(`stdout:\n${stdout.trimEnd()}`);
122
- return formatOutput(toolName, "error", parts.join("\n\n"));
123
+ // Compiler-owned exit status is far below the shared metadata bound.
124
+ const header = (ToolsResponse.renderYamlMetadata({ exit_code: code, killed }, Limits.RUN_DELIVERY_MODEL_MAX_BYTES) as
125
+ Extract<ToolsResponse.YamlMetadataRendering, { state: "available" }>).text;
126
+ // A failure with no selected stream text stays metadata-only bare YAML; no filler body is invented.
127
+ if (parts.length === 0) return { text: formatToolText(ToolsResponse.frameMetadataDocument(header)), truncated: false };
128
+ // The existing formatter keeps trim/tail/temp-file/loss basis; only the exit label moves into YAML.
129
+ const formatted = formatOutput(toolName, "error", parts.join("\n\n"));
130
+ return {
131
+ ...formatted,
132
+ text: formatToolText(ToolsResponse.frameMetadataDocument(header, formatted.text.replace(/^\n+/u, ""))),
133
+ };
123
134
  }
@@ -32,7 +32,7 @@ import { readRunCompletionTextSource, readRunResultArtifactInventory, readRunRes
32
32
  import type { RunPrimaryTextBinding } from "./runs-outcomes.ts";
33
33
  import { readJsonlFileResilient } from "./state-readers.ts";
34
34
  import { Document } from "yaml";
35
- import { formatLiteralBlock, formatMarkdownField } from "./tools-response.ts";
35
+ import { formatYamlNotice } from "./tools-response.ts";
36
36
 
37
37
  export type RunObservedStatus =
38
38
  | "running"
@@ -290,13 +290,12 @@ export function createRunStateWatcher(input: {
290
290
  code === "rearmed"
291
291
  ? "; terminal watch acceleration restored"
292
292
  : "; terminal reconciliation remains active and watcher rearm will retry";
293
+ // Captured detail/recovery strings are reused as-is; only the projection becomes bare block YAML.
293
294
  diagnostics.push({
294
295
  code,
295
296
  id: ++diagnosticId,
296
- message: [formatMarkdownField("watcher", code), formatMarkdownField("scope", scope),
297
- formatMarkdownField("path", formatLiteralBlock(path)),
298
- ...(detail ? [formatMarkdownField("diagnostic", detail.slice(2))] : []),
299
- formatMarkdownField("recovery", recovery.slice(2))].join("\n"),
297
+ message: formatYamlNotice({ watcher: code, scope, path,
298
+ ...(detail ? { diagnostic: detail.slice(2) } : {}), recovery: recovery.slice(2) }),
300
299
  path,
301
300
  scope,
302
301
  ts: new Date().toISOString(),
@@ -1006,12 +1005,11 @@ export function findRunRetirementCandidates(
1006
1005
  }
1007
1006
 
1008
1007
  function formatRunRetirementNotice(run: string, action: RunRetirementExecution["action"], message = ""): string {
1009
- const fields = [formatMarkdownField("run", run.startsWith("run:") ? run.slice(4) : run), formatMarkdownField("retirement", action)];
1010
- if (action === "stop") fields.push(formatMarkdownField("result", "request returned"), formatMarkdownField("reason", "child runs reached terminal state"));
1011
- else if (action === "cancel") fields.push(formatMarkdownField("result", "cancellation reported"), formatMarkdownField("reason", "stop path failed"));
1012
- else fields.push(formatMarkdownField("result", action === "skip" ? "skipped" : "failed"), formatMarkdownField("diagnostic", message));
1013
- fields.push(formatMarkdownField("closure", "unconfirmed"));
1014
- return fields.join("\n");
1008
+ return formatYamlNotice({ run: run.startsWith("run:") ? run.slice(4) : run, retirement: action,
1009
+ ...(action === "stop" ? { result: "request returned", reason: "child runs reached terminal state" }
1010
+ : action === "cancel" ? { result: "cancellation reported", reason: "stop path failed" }
1011
+ : { result: action === "skip" ? "skipped" : "failed", diagnostic: message }),
1012
+ closure: "unconfirmed" });
1015
1013
  }
1016
1014
 
1017
1015
  export async function executeRunRetirements(