@llblab/pi-actors 0.58.4 → 0.58.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -5
- package/BACKLOG.md +9 -2
- package/CHANGELOG.md +20 -0
- package/dist/lib/run-delivery.d.ts +1 -1
- package/dist/lib/run-delivery.js +47 -18
- package/dist/skills/actors/SKILL.md +2 -2
- package/dist/skills/actors/references/runs.md +1 -1
- package/docs/agent-experience.md +17 -19
- package/docs/coordinator-delivery.md +2 -2
- package/docs/output-projection-map.md +1 -1
- package/lib/run-delivery.ts +42 -21
- package/package.json +1 -1
- package/skills/actors/SKILL.md +2 -2
- package/skills/actors/references/runs.md +1 -1
package/AGENTS.md
CHANGED
|
@@ -30,9 +30,9 @@ The adopted presentation direction is **JSON structured inputs → block-YAML ru
|
|
|
30
30
|
|
|
31
31
|
Consolidate cohesive responsibilities into existing owners before creating another domain. A new domain needs a distinct responsibility and useful boundary; size, filename prefixes or development phases do not justify splitting.
|
|
32
32
|
|
|
33
|
-
Tests mirror the owning library/module/domain by default: prefer `tests/<module>.test.ts` for `lib/<module>.ts`, with contract/case groups inside that file rather than new files per feature, edge case or development cohort. When a module is consolidated or moved, reconcile its test ownership instead of retaining orphan test-file names. Explicit cross-domain exceptions include invariants, source/packed SDK journeys and their infrastructure fixtures; keep the reason clear and do not turn exceptions into another fragmented suite taxonomy. Consolidation must preserve scenarios, assertions, fixture data, pre-import isolation and teardown guarantees; move tests, never delete coverage to fit the layout. `tests/invariants.test.ts` guards file mirroring with explicit cross-domain/package exceptions, not feature-file exemptions. Serialize environment-changing contract groups; when defaults are captured at import, one isolated agent root must precede production value imports and outlive every group. Preserve native/per-case cleanup and retain uncertain state; root cleanup must not run between awaited groups. Native identity fixtures must establish actual child readiness before expecting a stable readable command identity; spawn notification alone is insufficient. Use the immediate capture owner only at its original birth boundary or an explicit controlled-child ready message, never late retry/reconstruction to promote unproven proof. Retain actual PID/identity/close evidence and require fresh ESRCH for captured child absence; a live host cannot self-certify its own exit.
|
|
33
|
+
Tests mirror the owning library/module/domain by default: prefer `tests/<module>.test.ts` for `lib/<module>.ts`, with contract/case groups inside that file rather than new files per feature, edge case or development cohort. When a module is consolidated or moved, reconcile its test ownership instead of retaining orphan test-file names. Explicit cross-domain exceptions include invariants, source/packed SDK journeys and their infrastructure fixtures; keep the reason clear and do not turn exceptions into another fragmented suite taxonomy. Consolidation must preserve scenarios, assertions, fixture data, pre-import isolation and teardown guarantees; move tests, never delete coverage to fit the layout. `tests/invariants.test.ts` guards file mirroring with explicit cross-domain/package exceptions, not feature-file exemptions. Serialize environment-changing contract groups; when defaults are captured at import, one isolated agent root must precede production value imports and outlive every group. Preserve native/per-case cleanup and retain uncertain state; root cleanup must not run between awaited groups. Native identity fixtures must establish actual child readiness before expecting a stable readable command identity; spawn notification alone is insufficient. Before a fixture temporarily rewrites canonical metadata, await its real gated workload readiness so asynchronous runner admission cannot race that test-owned mutation. Register close observers synchronously at fixture child birth and retain the observation time before awaiting Control/file receipts; a late exit listener is not completion proof. Use the immediate capture owner only at its original birth boundary or an explicit controlled-child ready message, never late retry/reconstruction to promote unproven proof. Retain actual PID/identity/close evidence and require fresh ESRCH for captured child absence; a live host cannot self-certify its own exit.
|
|
34
34
|
|
|
35
|
-
Require Pi ≥1.0.0 for all declared Pi peers. Keep source and packed lifecycle tests aligned with that baseline; do not restore an older host floor independently of those checks. Validation fixtures must use temporary agent directories, never write into the operator's live Recipe registry. Standard test/preservation/conformance processes preload tests/test-environment.mjs before product imports, forcing a fresh default agent directory even if the operator configured one. Use that preload for direct launcher tests too; retain its directories because test-runner exit alone does not prove inherited Run exit. Direct installed-package tests also require npm_execpath from an actual npm invocation or the pinned real npm CLI; a missing value is caller setup failure, not native product evidence. After editing an executable .mjs fixture, run node --check and its exact owning installed test before broad validation; TypeScript-only checking does not parse that fixture. A syntax failure can prevent child manifest persistence: retain the parent's captured frame and complete stdio/actual close, never claim all planned child frames materialized. Result acceptance is not runner exit: settle captured fixture producers before removing their state, and never treat a denied probe or elapsed wait as exit proof. Same-runtime producer fixtures cannot self-certify host exit: the parent captures the producer PID/frame before awaiting it; child manifests leave producer exit unasserted and settle only workload evidence. Distinguish privileged same-runtime launch composition from ordinary startRun/SDK or caller/worker acceptance. Durable settled receipts alone do not authorize parent cleanup: after validating positive safe captured PIDs, require a fresh ESRCH-only probe immediately before deleting fixture state; live/denied/unknown probes retain state and preserve the primary failure plus exact probe causes. Concurrent fixture workloads may finish in a different order from launch; verify exact generation membership independently of launch order, and rendered row order against the captured inventory. Force byte overflow from actual projected row sizes, not full-source byte sizes; verify each captured generation's exact binding even when content hashes repeat across Runs. Prove row-cap omission with an independent byte upper bound including the omitted minimal row, not merely 64 visible rows. Disclose synthetic legacy companions and controlled fixture timestamps separately from real public producers; they grant no body/native/fan-out authority. Failed-outcome witnesses must distinguish actual command code/canonical acceptance from detached runner exit, compare diagnostic projection/counts to canonical error metadata rather than raw stderr, and scope redaction/fallback assertions to delivered outcomes rather than prior model-owned tool arguments. Preserve the provider's original rejection before SDK error normalization can obscure it with a missing-final-answer assertion.
|
|
35
|
+
Require Pi ≥1.0.0 for all declared Pi peers. Keep source and packed lifecycle tests aligned with that baseline; do not restore an older host floor independently of those checks. Validation fixtures must use temporary agent directories, never write into the operator's live Recipe registry. Standard test/preservation/conformance processes preload tests/test-environment.mjs before product imports, forcing a fresh default agent directory even if the operator configured one. Use that preload for direct launcher tests too; retain its directories because test-runner exit alone does not prove inherited Run exit. Direct installed-package tests also require npm_execpath from an actual npm invocation or the pinned real npm CLI; a missing value is caller setup failure, not native product evidence. After editing an executable .mjs fixture, run node --check and its exact owning installed test before broad validation; TypeScript-only checking does not parse that fixture. A syntax failure can prevent child manifest persistence: retain the parent's captured frame and complete stdio/actual close, never claim all planned child frames materialized. Result acceptance is not runner exit: settle captured fixture producers before removing their state, and never treat a denied probe or elapsed wait as exit proof. Same-runtime producer fixtures cannot self-certify host exit: the parent captures the producer PID/frame before awaiting it; child manifests leave producer exit unasserted and settle only workload evidence. Distinguish privileged same-runtime launch composition from ordinary startRun/SDK or caller/worker acceptance. Durable settled receipts alone do not authorize parent cleanup: after validating positive safe captured PIDs, require a fresh ESRCH-only probe immediately before deleting fixture state; live/denied/unknown probes retain state and preserve the primary failure plus exact probe causes. Long SDK-driver cleanup may first reuse bounded read-only absence settlement on fresh PID-only rows, without changing historical captured records; the immediate final census still requires fresh ESRCH for every captured PID and the host. This wait neither signals processes nor proves original identity or whole-scope closure. Repeated same-runtime fixture settlement retains its already accepted observation only for the original row/PID in private runtime memory; copied records and changed PIDs cannot borrow it, and the parent's final fresh probes remain independent. Concurrent fixture workloads may finish in a different order from launch; verify exact generation membership independently of launch order, and rendered row order against the captured inventory. Force byte overflow from actual projected row sizes, not full-source byte sizes; verify each captured generation's exact binding even when content hashes repeat across Runs. Prove row-cap omission with an independent byte upper bound including the omitted minimal row, not merely 64 visible rows. Disclose synthetic legacy companions and controlled fixture timestamps separately from real public producers; they grant no body/native/fan-out authority. Failed-outcome witnesses must distinguish actual command code/canonical acceptance from detached runner exit, compare diagnostic projection/counts to canonical error metadata rather than raw stderr, and scope redaction/fallback assertions to delivered outcomes rather than prior model-owned tool arguments. Preserve the provider's original rejection before SDK error normalization can obscure it with a missing-final-answer assertion.
|
|
36
36
|
|
|
37
37
|
```text
|
|
38
38
|
Pi host
|
|
@@ -93,7 +93,7 @@ For ordinary Run-file investigation, follow the accepted [same-session research
|
|
|
93
93
|
- `inspector.ts`: owned-Run evidence and exact-session/generation-fenced actions through injected canonical control dependencies. `inspector-overlay.ts` and `inspector-command.ts` retain UI/navigation and host command wiring separately. **Actor Inspector** remains the product and command name, not a separate domain.
|
|
94
94
|
- `pi.ts`: Pi SDK envelope boundary. AX completion fallback identity comes from the closed terminal marker for new records or the original headers for retained captures when private details are stripped; keep the original legacy RegExp coercion order, reject noncanonical/indented/broken markers and never acknowledge by body equality; never let authored body labels or Unicode line separators override it. Preserve older header recognition and detailed-envelope precedence. Parsed ids remain hints until exact owned-journal/content admission; they grant no recipient, source or native authority.
|
|
95
95
|
- `observability.ts`, `run-ui-runtime.ts`: Trace attention, terminal reconciliation and Pi delivery. Fresh urgent-steer admission uses formatRunSteerMessage's single canonical AX layout only after the retained run/generation/directory/event lookup. Envelope.content is already frozen presentation: replay it directly without a new journal aspect, source refresh or reformatting. Attention and steer have no presentation selector or alternate new-message formatter; deliverRunAttentionNotifications uses the same canonical AX primitives for new notify/followup output. Saved envelope.content remains the compatibility boundary. The two AX checkpoint/reference helpers now have real ordinary/urgent reuse inside observability; keep ordinary first-eight coverage independent of steer's shared16KiB reservation/refusal loop. No ambient ordinary byte cap, event/detail copy, wake change or regeneration of committed content follows. Fresh attention uses shallow typed block-YAML metadata, bare without a body and delimited before an opaque zero-added-indent body. Preserve scalar-aligned500UTF-16 legacy previews, existing ellipsis and unknown local/upstream loss, original stringify/getter faults, whole reference sequences and first-eight slots before malformed filtering. Ordinary notify/followup remains unbounded; urgent steer validates raw essentials before reference reads and fits the complete final YAML/body with later-group omission coverage under16KiB. Serialization stays local to observability, not a new global formatter allowance; selection/read/acceptance authority stays here. Fresh urgent diagnostics also reuse its opaque field primitive: event/attention/stage records distinguish retryable admission, failed send request with unconfirmed delivery/presentation, and queued recovery with its exact evidence status/reason. Do not infer no effect from an exception or turn checkpoint retry into workload replay. Diagnostic display keeps only240pair-aligned raw message units and authored Markdown, with boundary U+2026/[omitted: unknown] for loss and unavailable for malformed text. This current UI projection is separate from unchanged whitespace-normalized/trimmed4096-unit last_error, original Error/cause and frozen envelope.content; create no saved format/aspect, reader, recovery loop or extra source permission. Fresh locally owned runtime notices use tools-response.ts:formatYamlNotice, a UI-only flat-field serializer without the model byte/depth ceilings: retain full well-formed fields, withhold malformed selected text explicitly, and keep existing diagnostic-preview bounds. Callback failure preserves the original onCallbackError value and opaque diagnostic; completion recovery preserves evidence status/pending phase/reason with no forced send; idle completion delivery is labeled accepted only after the original durable acceptance; teardown counts/whole literal summary path are explicitly report data, not scope closure. Watcher/retirement messages are forwarded unchanged from observability's new AX producer formatting. Watcher messages reuse the already captured detail/recovery strings: never read Error.message twice, add primitive-error coercion, change raw signatures/IDs/ts/dedup/32suffix/rearm policy or regenerate older diagnostic text. Paths stay whole dynamic literals. Retirement notices preserve optional-notify argument short-circuiting, exact error-message observations, attempted/sendStop/cancel/result/failure behavior including notifier throws, and unconfirmed closure. Stop returned and cancellation reported are not native success; fallback reason is stop path failed because the path also contains notifier execution. Do not repair already-discarded lower causes or rewrite result errors from the display. No new clipping, identities, state reads, notifier timing/levels/dedup, retries, error wrappers or native authority. Fresh completion admission creates canonical AX only after existing owner/location rechecks; an already-admitted batch returns untouched, including every older presentation format. Keep active/idle timing, acceptance, exact generation and source admission authority unchanged; fresh completion-prefix allocation follows the run-delivery contract below. Color terminal status only in `ctx.mode === "tui"`; JSON/print/RPC status must not require an initialized terminal theme or disable mandatory completion delivery. Shared ready-forest selection and ambient candidate checks are metadata-only for primary sources. Read/verify a selected primary source only when collecting eligible completion members, retaining exact source owner/generation and refusing capture promotion or lost-source stdout substitution. Unsupported complete raw-stream selections remain explicit or legacy diagnostics, never fabricated primary output; separately admitted executor-final-response text is not complete raw-stream selection.
|
|
96
|
-
- `run-delivery.ts`: owner-scoped durable packet/phase persistence and bounded projections. Fresh ordinary source admission captures presentation_format=ax_records, own-data result_layout=
|
|
96
|
+
- `run-delivery.ts`: owner-scoped durable packet/phase persistence and bounded projections. Fresh ordinary source admission captures presentation_format=ax_records, own-data result_layout=completion_yaml_files_v4 and frozen text_budget, with no presentation selector/excerpt_format; direct and ordinary UI admission share this path. The separate inactive numbered-stream capture still inherits frontmatter_v2; do not change the private default globally or relabel retained captures. Preserve all stored encodings/absence and exact replay bytes/hints, including headings_shared_kinds and frontmatter_v1/v2; reject mixed/unknown aspects without invoking accessors. Journals store snapshots, not complete text, so neither an unreleased version nor a schema fix permits rewriting old codecs. The second frontmatter capture layout quotes unknown index as YAML "?"; the first keeps its original bytes, including unquoted ?. Fresh headers begin run, state, then admitted kind:primary/diagnostic; prepend the packet-local index only when two or more results are shown. Meaningful metadata and useful whole source/location references follow; full source/generation/hash facts remain in the frozen snapshot rather than repeated per file. Display index is not member_index or native identity. Raw admitted Markdown follows the closed YAML at the left margin, without #N heading, result:/preview: wrapper, structural list indentation or whole-body literal fence. Known display loss is [N characters omitted] at the cut, except the fresh v4 exact primary-file continuation below; no added ellipsis or body clipping flags/counts in YAML. Fresh rooted captures keep unknown upstream/fallback completeness/privacy warnings in header text_warnings; only an exact known cut marker follows a cut body. Fallback has no primary kind. Retained layouts keep their original marker placement. Visible text is admitted output/final Actor response or error/failure diagnostics, never command metadata or copied command excerpts. Source text_basis remains technical. No routine group windows/status copies, members wrapper, outer counters, Batch caption or standing full-map instruction appears in new model content; captured facts remain journal data. Material whole-result/reference omission, non-done omitted states and a whole inventory reference remain explicit. Exactly one shown row omits only its display index, including with other results omitted; preserve omission/inventory facts and internal member_index/generation/correlation. The rooted_files_v4 service discriminator gates fresh compact file projection and the singleton rule; retained rooted-files-v1/v2/v3/core-v1 snapshots keep their exact indices and bytes. Do not extend this packet-local exception to numbered streams. Complete model content includes all exact references and only the necessary YAML-core packet identity/relative body-marker lengths, without fresh compiler HTML tails, under49152UTF-8 bytes for up to64candidate rows/256captured members. Equal scalar/CRLF-safe text-prefix shares freeze at admission, including service overhead; no redistribution, fixed16KiB result/2KiB preview cap, source recapture or later reallocation. Preserve every saved16KiB/48KiB allowance. Prefix admission must consider full-list/decimal discontinuities rather than miss fitting rows when omission scaffolding shrinks. Whole text has no display-cut marker when complete; known upstream clipping still forbids a full-original-output claim. The source reader selects at most48KiB from the same verified postprivacy observation; source-binding previews stay160code points. Retain chosen packet prefixes, not64independent48KiB copies. Unfit metadata rows keep bounded inventory recovery. Curate/copy/freeze members, arrays, artifacts and bindings; schema DTOs grant no publication permission and phase changes do not mutate member facts. Preserve generation/parent/source identities, exact ranges/hashes and whole references. The completion-only TUI uses independent native Markdown body components and literal Text header/marker/service components, with no global Markdown patch, source/native IO or scheduling authority. New rooted captures expose files as a header sequence: literal roots, relative paths, optional name/status, no role or diagnostic field inventory. Optional files_status/files_notes preserve real group-wide facts. Read first prefixes only a recoverable source whose selected text is incomplete, never complete answers, upstream uncertainty alone or unrelated diagnostics/artifacts/navigation. Exact primary prefixes use one-based LF file continue_from_line plus [Read from line N] at the cut; repeat partial lines, preserve CRLF and never count lone CR/wrapping as another file line. Diagnostic JSON and unmapped text keep exact character-cut markers. This exception applies only to fresh v4 snapshots; all older markers remain exact. Keep primary/diagnostic/inventory/artifact references and observed context-index/result/execution paths (metadata fallback), not absent optional technical files or repeated purpose/format/size/mutable/generation/hash fields. Retain source/privacy distinctions, declaration uncertainty, unavailable locations and missing terminal result facts; saved full bindings remain accessible and unchanged. Compact is the actual human/model content, not UI-only hiding. Reconstruct original selected references exactly; never normalize dot/symlink routes, guess cwd or treat declared targets as produced. Unresolved paths retain path_basis=as_recorded/base_unavailable with a null root and no recommendation. Saved file_navigation binds the original mutable Run-directory facts independently from the compact projection. All packet/inventory/whole-row omission metadata renders in the first header, not a service footer; no runtime text follows the last body except its known cut marker. Retained core-v1 captures keep their original references/locations and compact hiding rules; authored body lookalikes never disappear. Fresh ordinary hints use completion_yaml_core_v1 plus a whole-content digest; validated core lengths derive block positions. Retained completion_frontmatter_v1 hints keep their SHA-256-bound UTF-16 header/body/marker/service blocks and original compiler frames, dense ordered coverage and scalar/CRLF-safe endpoints. Invalid/missing hints and expansion reveal original full Text. These are display/correlation consistency, not authentication/read/action/acceptance/native authority. Malformed frontmatter-shaped stripped history cannot regain identity from a body Batch label or become absence/retry permission; ordinary thematic-break prose retains its legacy path. Retained pre-record codecs keep host rendering; older record/literal codecs keep exact original hints, dynamic fences, count spelling and separators. Fresh ordinary indices remain packet-local; no default stream activation follows. Fresh UI member locations are observed before journal locks after actual current-session selection/recheck, with captured_file_locations and frozen file_navigation. Data-only decoding does not grant current body/source visibility. Location snapshots retain16KiB, outcomes outrank lower-priority references, and each shown record has a whole location row or explicit omission; wholly omitted records stay inventory-covered. Reload/render/phase recovery never refreshes sources or frozen availability. Old absent/current_session_request captures keep their bytes, and optional full-map research stays a separate current-session action. Source/package checks do not prove the loaded host was reloaded.
|
|
97
97
|
- automatic draft/tool review domains: structurally redacted model review, journaled mutation, lineage, recovery, and explicit retry/reset safety.
|
|
98
98
|
|
|
99
99
|
The bundled Skill Recipe dependency DAG is `artifacts → actors, swarm` and `project-work → actors, artifacts, swarm`; `actors`, `music-player`, `swarm`, and `recipe-memory` have no cross-Skill Recipe dependencies.
|
|
@@ -214,7 +214,7 @@ Three ordinary executeRegisterToolUnlocked guards now project name/source AX err
|
|
|
214
214
|
|
|
215
215
|
Public first-layer UX/AX must serve both audiences from the same facts: understandable progress for the human, compressed decision context for the agent, and only a relevant drill-down when needed. Do not substitute a raw dump, add blanket fields/hints, coerce status objects into text, or promise later delivery that is not established. Delivery is not handling; a legacy kill attempt is not full-scope closure. Keep raw detail explicit and recipient-scoped at every level, including details/verbose; an identity-change refusal must not publish the replacement's status. Preserve original action/refusal facts and underlying uncertainty; separate presentation/curation fixes from lifecycle/native authority. Actor-local delivery_failed may coexist with recorded handled state; retirement exceptions may follow a move/removal. Missing Trace/correlation proves no inaction. Preserve causal/correlation evidence in its existing owner before public failure projection; do not build one generic recovery/receipt domain or release a transport-spanning lifecycle lock without equivalent generation/endpoint fencing. runs-control-delivery now retains surfaced primary failures in standard non-enumerable cause and combines later failed-status recording in ordered AggregateError.errors with only genuinely returned admitted control id/generation. Endpoint-not-ready, post-send delivered-record failure and unprintable failure text retain their distinct causes. FIFO write/close faults preserve both failures and already-written bytes, not rollback. Raw chains stay Kernel-local; ordinary serialization does not publish them. After actor-local dispatch, tools-message wraps any rejection in a bounded conservative Error, preserving the exact thrown value in non-enumerable cause without coercing it. Keep the original request target/action only (whole target or explicit omission under 16 KiB), report delivery/handling/effects uncertainty and no automatic replay, and point to fresh owned inventory. Captured admission ids/generation are deliberately not copied into that public error, including verbose: an old context or error DTO does not prove current reply scope. Do not add a second lifetime registry or weaken error semantics to publish correlation. Admission or lower-owner/facade release failures without a returned record must not gain invented correlation. The selected delivery/facade/retirement/locked-mutation/replacement boundaries preserve surfaced original/later faults; that does not recover errors already discarded below them or close B2's separate awaited-transport gate.
|
|
216
216
|
|
|
217
|
-
Agent-facing informational/completion text excerpts must disclose truncation and an exact omitted Unicode code-point count when that count is known. Fresh
|
|
217
|
+
Agent-facing informational/completion text excerpts must disclose truncation and an exact omitted Unicode code-point count when that count is known. Fresh v4 primary file prefixes use continue_from_line plus [Read from line N] at the cut; diagnostics/unmapped text keep [N characters omitted], outside YAML without a new ellipsis. Saved count spellings and prior packet layouts remain exact. Inline omission annotations retain their square brackets. Count only already-authorized privacy-projected text before clipping; do not count hidden secrets, treat UTF-16 units/bytes as characters, guess lost original lengths or widen source retention. Legacy unknown counts must be explicitly unknown, never fabricated. Apply the approved display direction to new captures/formats without rewriting already-admitted immutable packets or clipping actionable references. Every new completion admission captures canonical AX and admitted tracked primary/diagnostic counters. excerpt_format=bracketed_omissions_v1 is retained-read data only, not a generic default or selectable presentation. Saved aspect absence and every captured version preserve their exact earlier formatting. This is presentation data only, never source/visibility/work authority. Do not apply that aspect flag to unrelated legacy summaries/body clipping or infer their original counts. Fresh explicit agent Trace display counts only normalized retained turn text after existing session privacy, keeps its160-UTF-16 preview scalar-aligned and appends boundary U+2026 plus [omitted: N chars] from normalized retained turn; upstream [omitted: unknown]. This is a current read-time summary leaf, not an authored body, saved packet or new source/capture aspect. Canonical-only projectRunTraceJournal and stored/detail bytes remain unchanged; never retrofit journal/session strings or infer discarded4000-unit source counts. Malformed retained text has only an unknown-count diagnostic, without a fabricated gap/number. Malformed retained text yields an unknown-count summary, never an exact scalar count or repaired source. This changes neither saved packet formats nor the canonical-only Trace export path. Legacy outbox body500 and steer diagnostic240 lack a retained original privacy projection admitting safe exact tail counts: disclose unknown counts rather than counting raw secrets, keep source previews scalar-aligned within their original allowance, and withhold malformed visible previews without source repair. Actor redacted flags are not projection authority. This is disclosure only, not newly certified body/error privacy or broader retention; journal last_error4096 and its incomplete original-cause scope remain unchanged.
|
|
218
218
|
|
|
219
219
|
Tool result/error text contributes exactly one leading line break. Keep model-facing responses compact and state-backed. Preserve complete byte-exact command streams in bounded spill files while returning bounded tails; never feed truncated tails into pipeline stdin.
|
|
220
220
|
|
|
@@ -234,7 +234,7 @@ Private `recoverRunDescendantPreparation` is controller-owned metadata admission
|
|
|
234
234
|
|
|
235
235
|
File watchers accelerate reconciliation; a bounded interval recovers missed terminal and retained-attention events. Canonical attention observation uses stable retained ids and bounds seen memory to the current suffix across compaction; only allowlisted legacy outbox fallback uses line offsets. Ordinary `notify` and `followup` hints prime at startup without replay and require durable state or artifacts for recovery. Explicit `steer` instead re-enters through the owner journal until exact presentation records its newer generation-fenced Trace marker. New steer formatting belongs to observability, not a runtime whole-string cutter: retain the canonical checkpoint prefix, select at most eight whole references per group inside the shared 16 KiB cap, reserve later groups' omission coverage and never normalize/replace reference spelling. Fresh ordinary and urgent attention share the AX opaque checkpoint/body and literal-reference group primitives inside observability, not duplicated source/privacy logic. Attention and steer use one canonical new-message formatter without selectors; replay saved envelope.content before formatting, preserving every earlier captured grammar. Ordinary notify/followup still has no new shared16KiB cap/reservation, and its unchanged sink sends a visible notification plus only followup's non-displayed checkpoint context. Do not rewrite committed strings or turn body next/tool labels into actions. Omit malformed references, never repair them. Overlarge/malformed essential text remains pre-admission retryable unavailability through existing diagnostics, not a partially delivered checkpoint. Runtime must reuse an exact run/generation/directory/event's admitted envelope before formatting again, including old clipped content; formatter changes are not authority to rewrite history.
|
|
236
236
|
|
|
237
|
-
Ordinary terminals retain inherited delivery lineage from each nested Actor process to the top-level coordinator. Only that root coordinator schedules completion delivery; descendant sessions stay quiet and wait for their complete containing top-level tree. A completed active `turn_end` snapshots the ready forest into one immutable batch, preserves earlier boundary entries, and returns one visible custom-message entry plus one continuation, never a native steering/follow-up enqueue. Aborted/error boundaries and pending native input defer projection. Already-idle Pi retains debounced follow-up delivery. The same batch renders as one operator card and one model prompt, fenced by owner and generation and bounded at 256 durable members, 64 model-facing rows, 48 KiB of context for fresh shared-result captures (16 KiB for retained formats), and a 1 MiB journal. `run-delivery.ts` retains a selected-batch captured-member inventory before journal admission only when whole rows would be omitted. Copy identities/status/lineage and already admitted primary/artifact/diagnostic references/unavailability, excluding diagnostic excerpts, never private member locations, summaries, legacy bodies, original declaration lists or owner/steer data. Add captured artifact/diagnostic binding inventory tags only when members carry those fields so older inventory payload hashes remain unchanged. Its full source reference consumes the shared model budget before rows. Source and journal are separate effects: preflight known journal overflow before exclusive source creation; preserve exact I/O errors and unpublished partial/orphan files without overwrite, reuse, rollback, implicit repair or ACK. Reload/phases/rendering bind the exact captured metadata without source-body reads or availability refresh. File existence/hash/path is not producer, body-publication, native or durable-immutability authority. Artifact markers are ambient metadata hints only. Eligible collection admits one exact natural result binding, verifies the full retained inventory and matching status, then copies descriptor/unavailability into the packet. Preserve accepted unavailability without source reads/repair. Suppress legacy artifact path maps for every inventory-aware member, including source loss; packet parsing rejects competing legacy paths. Shared Markdown retains literal full source/counts and metadata-only provenance, stays quiet for not_declared, and never rereads result/index/source or refreshes availability during phase/render operations. Diagnostic markers are likewise ambient hints only: eligible admission checks one exact canonical natural result and matching expected terminal status before following its deterministic source, preserves saved unavailability without reads/repair, and validates the complete closed source/field set/hash. Share source decoding with the readonly saved-role reader but require/create no Result role view/index. Select error, else failure_reason, else command, retaining at most 1000 literal code points plus exact decoded-field UTF-8/counts and full metadata reference
|
|
237
|
+
Ordinary terminals retain inherited delivery lineage from each nested Actor process to the top-level coordinator. Only that root coordinator schedules completion delivery; descendant sessions stay quiet and wait for their complete containing top-level tree. A completed active `turn_end` snapshots the ready forest into one immutable batch, preserves earlier boundary entries, and returns one visible custom-message entry plus one continuation, never a native steering/follow-up enqueue. Aborted/error boundaries and pending native input defer projection. Already-idle Pi retains debounced follow-up delivery. The same batch renders as one operator card and one model prompt, fenced by owner and generation and bounded at 256 durable members, 64 model-facing rows, 48 KiB of context for fresh shared-result captures (16 KiB for retained formats), and a 1 MiB journal. `run-delivery.ts` retains a selected-batch captured-member inventory before journal admission only when whole rows would be omitted. Copy identities/status/lineage and already admitted primary/artifact/diagnostic references/unavailability, excluding diagnostic excerpts, never private member locations, summaries, legacy bodies, original declaration lists or owner/steer data. Add captured artifact/diagnostic binding inventory tags only when members carry those fields so older inventory payload hashes remain unchanged. Its full source reference consumes the shared model budget before rows. Source and journal are separate effects: preflight known journal overflow before exclusive source creation; preserve exact I/O errors and unpublished partial/orphan files without overwrite, reuse, rollback, implicit repair or ACK. Reload/phases/rendering bind the exact captured metadata without source-body reads or availability refresh. File existence/hash/path is not producer, body-publication, native or durable-immutability authority. Artifact markers are ambient metadata hints only. Eligible collection admits one exact natural result binding, verifies the full retained inventory and matching status, then copies descriptor/unavailability into the packet. Preserve accepted unavailability without source reads/repair. Suppress legacy artifact path maps for every inventory-aware member, including source loss; packet parsing rejects competing legacy paths. Shared Markdown retains literal full source/counts and metadata-only provenance, stays quiet for not_declared, and never rereads result/index/source or refreshes availability during phase/render operations. Diagnostic markers are likewise ambient hints only: eligible admission checks one exact canonical natural result and matching expected terminal status before following its deterministic source, preserves saved unavailability without reads/repair, and validates the complete closed source/field set/hash. Share source decoding with the readonly saved-role reader but require/create no Result role view/index. Select error, else failure_reason, else command, retaining at most 1000 literal code points plus exact decoded-field UTF-8/counts and full metadata reference. Keep other recorded fields in structured facts; fresh compact v4 headers omit that inventory while older packets retain their not-shown disclosure. Curate/deep-freeze excerpt data through the shared data schema, not a primary DTO. Reject legacy output on every diagnostic-aware member, including unavailable bindings, and detached excerpts. Raw result.error/stdout is never fallback. Packet reload/phases/rendering do no source IO, freshness repair or ACK. Metadata-only scope is visible; not_recorded stays quiet. Native closure and all-body/summary permission remain separate.
|
|
238
238
|
|
|
239
239
|
Returning a boundary draft is not acceptance: keep it pending until exact model context or bounded active-session parent-chain evidence proves the committed entry. Successful idle `sendMessage()` acceptance finalizes immediately; durable queued phase also proves acceptance. Only proven absence permits retry; incomplete or conflicting pending evidence stays pending with diagnostics. Exact acceptance authorizes generation-fenced terminal handled markers and releases later epochs without depending on one context callback. Retry duplicates collapse before presentation, malformed envelopes fail closed, and automatic review waits behind an active completion batch.
|
|
240
240
|
|
package/BACKLOG.md
CHANGED
|
@@ -4,6 +4,13 @@ Canonical open work: `BACKLOG.md`. Contracts and durable constraints live in `AG
|
|
|
4
4
|
|
|
5
5
|
Task IDs name bounded work, not execution order. The operator authorizes autonomous selection and execution of open pi-actors work in Grow Loop: choose dependency-ready high-value cohorts across this backlog without repeated routine permission questions. Dependencies, factual acceptance and specific safety/authority boundaries remain explicit; a gated task is not completed merely because another cohort can proceed. Completing a child does not complete its checkpoint.
|
|
6
6
|
|
|
7
|
+
## R0 — Complete the actionable-completion release through CI
|
|
8
|
+
|
|
9
|
+
Outcome: Publish the approved completion navigation changes and reliable lifecycle witnesses to npm through repository CI, then synchronize and release Pi Kit. Keep failed unpublished tags immutable; use a new patch release for corrections. Scope excludes live reload, unrelated backlog work, manual publication and weakened native-exit or Control assertions.
|
|
10
|
+
|
|
11
|
+
- [ ] **R0.4 — Publish through the existing CI owners.** Deliver the SDK cleanup corrections with original-row settlement idempotence, bounded read-only parent absence waiting and an independent final fresh ESRCH census. Validate the patch through dev → PR → main, preserve tree-bound evidence, create only the new version tag, pass the three-OS immutable-tag gate and verify exact public npm/GitHub identity. Diagnose further failures and continue useful scoped fixes/hotfixes; never bypass checks or reinterpret a failed gate as publication.
|
|
12
|
+
- [ ] **R0.5 — Synchronize and release Pi Kit.** After verified upstream npm publication, update the exact Actors pin, kit version, lockfile and inventory under `~/Repos/pi-kit/AGENTS.md`, validate its package-coherence contract and verify its CI-owned npm/GitHub publication. No installation or live reload.
|
|
13
|
+
|
|
7
14
|
## Next bounded work
|
|
8
15
|
|
|
9
16
|
- **Capability memory:** P1.3 must admit the evidence contract before P1.2c can change automatic retention/exposure. These future slices are separate from the explicit manual workflow; source/package acceptance does not authorize live migration or reload an already running host.
|
|
@@ -19,13 +26,13 @@ Outcome: JSON structured inputs, block-YAML runtime-output metadata and unchange
|
|
|
19
26
|
|
|
20
27
|
Exit: New owned runtime projections use YAML without pseudo-records or serialized JSON objects: bare when metadata-only, `---`-delimited headers only when a separate text body follows. Literal content, meaning, source/privacy bounds and saved messages remain intact. Service-carrier adoption has its own evidence gate; do not delete current framing to simulate completion.
|
|
21
28
|
|
|
22
|
-
- [ ] **F1.7 — Accept the rollout on a loaded host.** Source/headless audit is done: one shared framing owner keeps exactly one host-separation blank line on migrated paths, no runtime-authored object dump or pseudo-record remains in the migrated set, history/literal bodies are unchanged, and source/compiled/package parity passes. Remainder is the permitted loaded terminal/phone observation of one rollout candidate, including compact selected launch paths and
|
|
29
|
+
- [ ] **F1.7 — Accept the rollout on a loaded host.** Source/headless audit is done: one shared framing owner keeps exactly one host-separation blank line on migrated paths, no runtime-authored object dump or pseudo-record remains in the migrated set, history/literal bodies are unchanged, and source/compiled/package parity passes. Remainder is the permitted loaded terminal/phone observation of one rollout candidate, including compact selected launch paths and direct files-group completion references/status, conditional Read first plus exact file-line continuation and no post-Markdown runtime footer, which needs the same separate authorization as U1; keep capture codecs and live claims distinct and claim no automatic default activation.
|
|
23
30
|
|
|
24
31
|
### U1 — Loaded UI/AX acceptance
|
|
25
32
|
|
|
26
33
|
Exit: Real loaded rendering is checked separately from source/headless/native proofs. This is independent follow-up, not a claim that the already merged release received loaded-host acceptance. Reload and an operator Run require their own authorization; do not start one merely to manufacture a live Kill case.
|
|
27
34
|
|
|
28
|
-
- [ ] **U1.1 — Retest fresh completion packets and expansion.** After authorized reload, inspect actual singleton/multiple/omitted-row packets: run/state YAML/kind with packet-local indices only for multiple shown results, left-edge independent Markdown, literal unfinished blocks, exact cut
|
|
35
|
+
- [ ] **U1.1 — Retest fresh completion packets and expansion.** After authorized reload, inspect actual singleton/multiple/omitted-row packets: run/state YAML/kind with packet-local indices only for multiple shown results, left-edge independent Markdown, literal unfinished blocks, exact primary-file continuation/diagnostic cut markers, direct files-group paths/status without role/field-inventory noise, blank separation and no routine top-level completion caption/toast. Expansion and historical fallback must preserve the saved text. Verify: actual terminal/phone observation plus existing delivery/Pi owners.
|
|
29
36
|
- [ ] **U1.2 — Retest the Run dropdown.** Check shifted compact placement, independent stripes/right padding, narrow/medium/wide layout and unchanged selection/source detail. Preserve the accepted navigation and refresh behavior; do not invent a performance cause or change freshness speculatively. Verify: real Inspector plus existing overlay/Inspector properties.
|
|
30
37
|
- [ ] **U1.3 — Retest notification and Kill modals.** Check complete selected notification text, no prefix/reader indirection, Esc-only dismissal and scrolling only on physical overflow; check centered compact Kill, default backgrounds/insets, frozen underlay and no key leakage. Cancel returns to the same Inspector without Notice; success relies on selected status and failures remain visible. Verify: actual permitted modal cases, without claiming Kill is scope closure.
|
|
31
38
|
- [ ] **U1.4 — Retest Inspector chronology.** Check newest-higher numbering across 100→101/102, filter gaps without renumbering, scrolling/detail provenance and visible `#?` for unavailable history. Do not promise permanent lifetime ordinals or reconstruct missing offsets. Verify: [chronology contract](docs/actor-inspector.md#chronological-numbering-requested-replacement) on loaded terminal/phone.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
> Each release keeps at most 8 outcome records of at most 512 characters.
|
|
4
4
|
|
|
5
|
+
## 0.58.7: Completion Navigation and Native Fixture Readiness
|
|
6
|
+
|
|
7
|
+
- `Completion Navigation`: Fresh completions use direct rooted file groups, omit redundant roles/field inventories and recommend `Read first` only for recoverable incomplete text. Primary-file cuts expose exact line continuation; JSON diagnostics keep character counts. Source/privacy distinctions, fixed budgets and byte-exact historical replay remain unchanged.
|
|
8
|
+
- `Control Fixture Closure`: Public music-player Control tests retain close evidence from child birth and deliberately observe stop ACKs after close. Successful native completion and the original prompt-stop bound stay required; watchdogs are cancelled, cleanup requires fresh service absence, and failures retain roots plus original causes.
|
|
9
|
+
- `Lifecycle Fixture Readiness`: Singleton clock/reuse tests await real gated-workload readiness before temporarily rewriting canonical metadata, preventing runner admission from racing the test. The shared fixture keeps its existing readiness bound, all generation/origin/reuse assertions and fresh process-exit checks.
|
|
10
|
+
- `SDK Fixture Cleanup`: Long source/packed SDK journeys wait read-only for current PID absence before the immediate final fresh-ESRCH census, reusing the existing bounded settlement policy without changing captured records. Persistent presence, denied/unknown probes and PID reappearance still refuse cleanup and retain roots plus original causes; no process is signalled and product deadlines stay unchanged.
|
|
11
|
+
- `Coordinator Fixture Settlement`: Repeated finally cleanup retains accepted settlement only for the original runtime-local row/PID; copied records and changed PIDs cannot borrow it. First-time denied/unknown probes still fail, native bounds and genuine-close requirements remain unchanged, and independent fresh parent probes continue to gate file research and deletion.
|
|
12
|
+
|
|
13
|
+
## 0.58.6: Completion Navigation and Reliable Validation
|
|
14
|
+
|
|
15
|
+
- `Completion Navigation`: Fresh completions use direct rooted file groups, omit redundant roles/field inventories and recommend `Read first` only for recoverable incomplete text. Primary-file cuts expose exact line continuation; JSON diagnostics keep character counts. Source/privacy distinctions, fixed budgets and byte-exact historical replay remain unchanged.
|
|
16
|
+
- `Control Fixture Closure`: Public music-player Control tests retain close evidence from child birth and deliberately observe stop ACKs after close. Successful native completion and the original prompt-stop bound stay required; watchdogs are cancelled, cleanup requires fresh service absence, and failures retain roots plus original causes.
|
|
17
|
+
- `Lifecycle Fixture Readiness`: Singleton clock/reuse tests await real gated-workload readiness before temporarily rewriting canonical metadata, preventing runner admission from racing the test. The shared fixture keeps its existing readiness bound, all generation/origin/reuse assertions and fresh process-exit checks.
|
|
18
|
+
|
|
19
|
+
## 0.58.5: Actionable Completion Navigation
|
|
20
|
+
|
|
21
|
+
- `Compact Completion Files`: Fresh completion headers expose `files` directly as rooted entry groups, without role labels, read-first index pointers or diagnostic field inventories. Concise source/privacy status, exact paths and real group-wide uncertainty remain; full machine bindings are unchanged.
|
|
22
|
+
- `Selective Continuation`: `Read first` appears only for incomplete selected text recoverable from its source. Primary text prefixes add `continue_from_line` and compact `[Read from line N]` guidance, rereading partial LF/CRLF file lines. JSON diagnostics retain character counts; complete answers and upstream uncertainty alone create no reading recommendation.
|
|
23
|
+
- `Replay and Safety`: A fresh-only snapshot layout preserves earlier packet bytes, pointers, markers and budgets. Formatting reads no files, changes no source/privacy or delivery authority and leaves Actor Markdown intact. Loaded-host acceptance, integration and publication remain separate.
|
|
24
|
+
|
|
5
25
|
## 0.58.4: Host-Provided SDK Loading
|
|
6
26
|
|
|
7
27
|
- `Extension Startup`: Standalone and kit-pointer installations no longer require a physical Pi SDK package beside the extension merely to load. Bare Pi commands keep their context/session behavior; Node CLI recognition resolves the SDK only when needed and refuses unknown scripts when that optional identity is unavailable.
|
|
@@ -66,7 +66,7 @@ export interface RunCompletionBatch {
|
|
|
66
66
|
/** Retained singleton capture; absence preserves older indexed bytes. Never a new-capture selector. */
|
|
67
67
|
readonly single_result?: true;
|
|
68
68
|
/** Captured record-list shape; no public format/version choice or source authority. */
|
|
69
|
-
readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" | "completion_yaml_files_v3";
|
|
69
|
+
readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" | "completion_yaml_files_v3" | "completion_yaml_files_v4";
|
|
70
70
|
/** Immutable scope/order/range data, not a caller-selected format or allocation authority. */
|
|
71
71
|
readonly numbering?: RunCompletionNumbering;
|
|
72
72
|
/** Formatting version/data only; no recipient ownership, read or publication capability. */
|
package/dist/lib/run-delivery.js
CHANGED
|
@@ -279,7 +279,7 @@ function isFrontmatterCompletionLayout(layout) {
|
|
|
279
279
|
return layout === "frontmatter_v1" || layout === "frontmatter_v2";
|
|
280
280
|
}
|
|
281
281
|
function isRootedCompletionLayout(layout) {
|
|
282
|
-
return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2" || layout === "completion_yaml_files_v3";
|
|
282
|
+
return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2" || layout === "completion_yaml_files_v3" || layout === "completion_yaml_files_v4";
|
|
283
283
|
}
|
|
284
284
|
function isYamlCompletionLayout(layout) {
|
|
285
285
|
return layout === "completion_yaml_core_v1" || isRootedCompletionLayout(layout);
|
|
@@ -691,7 +691,7 @@ export function requestRunCompletionStream(input) {
|
|
|
691
691
|
});
|
|
692
692
|
}
|
|
693
693
|
export function admitRunCompletionBatch(input) {
|
|
694
|
-
return captureCompletionBatch(input, false, "
|
|
694
|
+
return captureCompletionBatch(input, false, "completion_yaml_files_v4");
|
|
695
695
|
}
|
|
696
696
|
/** Kernel-only opt-in; ordinary Pi capture stays fenced until session/lifecycle integration is admitted. */
|
|
697
697
|
export function captureRunCompletionStreamBatch(input) {
|
|
@@ -699,7 +699,7 @@ export function captureRunCompletionStreamBatch(input) {
|
|
|
699
699
|
}
|
|
700
700
|
/** Private ordinary candidate composition; stream capture retains its separately gated codec. */
|
|
701
701
|
export function captureRunCompletionYamlCandidateBatch(input) {
|
|
702
|
-
return captureCompletionBatch(input, false, "
|
|
702
|
+
return captureCompletionBatch(input, false, "completion_yaml_files_v4");
|
|
703
703
|
}
|
|
704
704
|
function captureCompletionBatch(input, numbered, layout = "frontmatter_v2") {
|
|
705
705
|
const now = (input.now ?? new Date()).toISOString();
|
|
@@ -1312,6 +1312,9 @@ function completionRecordRow(member, index, byIdentity, flat = false, layout, te
|
|
|
1312
1312
|
end: diagnostic.shown_bytes.start + selected.shown_bytes.end }, chars_shown: shown,
|
|
1313
1313
|
chars_omitted: diagnostic.chars_total - shown, truncated: shown < diagnostic.chars_total };
|
|
1314
1314
|
}
|
|
1315
|
+
// LF-delimited file lines, not terminal wrapping; a partial final line must be read again.
|
|
1316
|
+
const continuationLine = layout === "completion_yaml_files_v4" && primary && primary.chars_omitted > 0 && primary.shown_bytes.start === 0
|
|
1317
|
+
? primary.preview.split("\n").length : undefined;
|
|
1315
1318
|
const kind = primary ? primary.text_basis === "actor_response" ? "response" : "primary" : diagnostic ? "diagnostic" : member.output ? "legacy" : undefined;
|
|
1316
1319
|
const boilerplate = isRoutineCompletionSummary(member);
|
|
1317
1320
|
let legacy = !!member.output;
|
|
@@ -1356,7 +1359,8 @@ function completionRecordRow(member, index, byIdentity, flat = false, layout, te
|
|
|
1356
1359
|
pieces.push({ text: "[omitted: unknown] (retained excerpt starts after the source boundary)", compact: true, block: "marker" });
|
|
1357
1360
|
pieces.push({ text: value, compact: true, block: "body" });
|
|
1358
1361
|
if (chosen && chosen.chars_omitted > 0)
|
|
1359
|
-
pieces.push({ text:
|
|
1362
|
+
pieces.push({ text: continuationLine === undefined
|
|
1363
|
+
? `[${chosen.chars_omitted} characters omitted]` : `[Read from line ${continuationLine}]`, compact: true, block: "marker" });
|
|
1360
1364
|
}
|
|
1361
1365
|
else {
|
|
1362
1366
|
const complete = shared && primary && primary.shown_bytes.start === 0 && primary.shown_bytes.end === primary.bytes_total && !primary.upstream_truncated;
|
|
@@ -1419,7 +1423,8 @@ function completionRecordRow(member, index, byIdentity, flat = false, layout, te
|
|
|
1419
1423
|
pieces.push(completionPiece("artifact_declarations", String(artifacts.length), depth));
|
|
1420
1424
|
technical.artifacts = { scope: "Declared paths; existence/production unproven.", declarations: artifacts.map(([name, path]) => ({ name, path })) };
|
|
1421
1425
|
}
|
|
1422
|
-
return { pieces, technical: Object.keys(technical).length ? formatMarkdownField(flat ? "result_details" : `#${index}`, formatLiteralBlock(JSON.stringify(technical, null, 2))) : "", technical_data: technical, legacy, ...(completionText ? { completion_text: completionText } : {})
|
|
1426
|
+
return { pieces, technical: Object.keys(technical).length ? formatMarkdownField(flat ? "result_details" : `#${index}`, formatLiteralBlock(JSON.stringify(technical, null, 2))) : "", technical_data: technical, legacy, ...(completionText ? { completion_text: completionText } : {}),
|
|
1427
|
+
...(continuationLine === undefined ? {} : { continuation_line: continuationLine }) };
|
|
1423
1428
|
}
|
|
1424
1429
|
const FRONTMATTER_FRAME = "<!-- pi-actors:frontmatter ";
|
|
1425
1430
|
function readFrontmatterFrame(content) {
|
|
@@ -1638,7 +1643,7 @@ function rootedCompletionPath(path, runRoot) {
|
|
|
1638
1643
|
return { root: path.slice(0, end), path: path.slice(split + 1) };
|
|
1639
1644
|
}
|
|
1640
1645
|
/** Body-free, read-free navigation over already selected references. Roots are presentation bases, not containment proof. */
|
|
1641
|
-
function completionRootedFiles(row, member, locations, compact = false) {
|
|
1646
|
+
function completionRootedFiles(row, member, locations, compact = false, simple = false) {
|
|
1642
1647
|
const technical = completionYamlReferences(row), files = {};
|
|
1643
1648
|
const status = [];
|
|
1644
1649
|
const groups = [];
|
|
@@ -1655,11 +1660,22 @@ function completionRootedFiles(row, member, locations, compact = false) {
|
|
|
1655
1660
|
const selected = rootedCompletionPath(path, runRoot);
|
|
1656
1661
|
const index = group(selected?.root ?? (base === undefined ? null : completionYamlString(base)));
|
|
1657
1662
|
const selectedPath = selected?.path ?? path;
|
|
1658
|
-
|
|
1659
|
-
...(!selected && base === undefined ? { path_basis: "as_recorded", base_unavailable: true } : {}) }
|
|
1663
|
+
const shown = { ...entry, path: selectedPath,
|
|
1664
|
+
...(!selected && base === undefined ? { path_basis: "as_recorded", base_unavailable: true } : {}) };
|
|
1665
|
+
groups[index].entries.push(shown);
|
|
1660
1666
|
if (selected && rank < priority) {
|
|
1661
1667
|
priority = rank;
|
|
1662
|
-
|
|
1668
|
+
if (simple) {
|
|
1669
|
+
shown.status = `Read first; ${entry.status}`;
|
|
1670
|
+
if (row.continuation_line !== undefined && entry.role === "primary")
|
|
1671
|
+
shown.continue_from_line = row.continuation_line;
|
|
1672
|
+
}
|
|
1673
|
+
else
|
|
1674
|
+
files.read_first = { group: index, entry: groups[index].entries.length - 1 };
|
|
1675
|
+
}
|
|
1676
|
+
if (simple) {
|
|
1677
|
+
delete shown.role;
|
|
1678
|
+
delete shown.recorded_fields_not_shown;
|
|
1663
1679
|
}
|
|
1664
1680
|
};
|
|
1665
1681
|
for (const [role, purpose, rank] of [
|
|
@@ -1671,10 +1687,13 @@ function completionRootedFiles(row, member, locations, compact = false) {
|
|
|
1671
1687
|
continue;
|
|
1672
1688
|
const { source: rawSource, ...facts } = detail;
|
|
1673
1689
|
const { path, ...binding } = rawSource;
|
|
1690
|
+
const coverage = row.technical_data[role];
|
|
1691
|
+
const continuation = (role === "primary" || (role === "diagnostic_metadata" && !row.technical_data.primary)) &&
|
|
1692
|
+
coverage?.state === "clipped" && coverage.chars_total > coverage.chars_shown;
|
|
1674
1693
|
add(path, compact ? { role, ...(role === "primary" ? { status: facts.text_basis === "actor_response" ? "Actor response; admission privacy" : "Exported text; admission privacy, not complete Actor output" }
|
|
1675
1694
|
: role === "diagnostic_metadata" ? { status: "Recorded diagnostic metadata only; admission privacy",
|
|
1676
1695
|
...(facts.recorded_fields_not_shown ? { recorded_fields_not_shown: facts.recorded_fields_not_shown } : {}) }
|
|
1677
|
-
: { status: "Declarations only; target availability/production unproven" }) } : { role, purpose, ...facts, source: binding }, rank);
|
|
1696
|
+
: { status: "Declarations only; target availability/production unproven" }) } : { role, purpose, ...facts, source: binding }, simple && !continuation ? Infinity : rank);
|
|
1678
1697
|
delete technical[role];
|
|
1679
1698
|
}
|
|
1680
1699
|
const artifacts = technical.artifacts;
|
|
@@ -1703,7 +1722,7 @@ function completionRootedFiles(row, member, locations, compact = false) {
|
|
|
1703
1722
|
for (const item of compact ? useful : selectedFiles) {
|
|
1704
1723
|
const { path, ...facts } = item;
|
|
1705
1724
|
const purpose = item.role === "result" ? "Recorded result metadata" : item.role === "execution" ? "Recorded execution and capture locations" : "Recorded Run file";
|
|
1706
|
-
add(typeof path === "string" ? completionYamlString(path) : null, compact ? { role: item.role } : { ...facts, purpose }, item.state === "present" && item.role === "result" ? 3 : item.state === "present" && item.role === "execution" ? 4 : Infinity, directory);
|
|
1725
|
+
add(typeof path === "string" ? completionYamlString(path) : null, compact ? { role: item.role } : { ...facts, purpose }, !simple && item.state === "present" && item.role === "result" ? 3 : !simple && item.state === "present" && item.role === "execution" ? 4 : Infinity, directory);
|
|
1707
1726
|
}
|
|
1708
1727
|
}
|
|
1709
1728
|
else if (locations) {
|
|
@@ -1724,7 +1743,8 @@ function completionRootedFiles(row, member, locations, compact = false) {
|
|
|
1724
1743
|
function prepareCompletionYamlProjection(safe, candidates, references, ordered) {
|
|
1725
1744
|
const packet = { batchId: safe.batch_id, records: [] };
|
|
1726
1745
|
const rooted = isRootedCompletionLayout(safe.result_layout);
|
|
1727
|
-
const
|
|
1746
|
+
const simple = safe.result_layout === "completion_yaml_files_v4";
|
|
1747
|
+
const compact = simple || safe.result_layout === "completion_yaml_files_v3";
|
|
1728
1748
|
const localSingleton = (compact || safe.result_layout === "completion_yaml_files_v2") && !safe.numbering && candidates.length === 1;
|
|
1729
1749
|
if (!safe.batch_id.isWellFormed())
|
|
1730
1750
|
return { state: "unsupported" };
|
|
@@ -1753,8 +1773,16 @@ function prepareCompletionYamlProjection(safe, candidates, references, ordered)
|
|
|
1753
1773
|
const navigation = references.has(index) && location
|
|
1754
1774
|
? safe.file_navigation.find(item => safe.members[item.member_index] === member).locations : undefined;
|
|
1755
1775
|
if (rooted) {
|
|
1756
|
-
const files = completionRootedFiles(row, member, navigation, compact);
|
|
1757
|
-
if (
|
|
1776
|
+
const files = completionRootedFiles(row, member, navigation, compact, simple);
|
|
1777
|
+
if (simple) {
|
|
1778
|
+
if (files.groups)
|
|
1779
|
+
metadata.files = files.groups;
|
|
1780
|
+
if (files.status)
|
|
1781
|
+
metadata.files_status = files.status;
|
|
1782
|
+
if (files.notes)
|
|
1783
|
+
metadata.files_notes = files.notes;
|
|
1784
|
+
}
|
|
1785
|
+
else if (Object.keys(files).length)
|
|
1758
1786
|
metadata.files = files;
|
|
1759
1787
|
}
|
|
1760
1788
|
else {
|
|
@@ -1776,7 +1804,8 @@ function prepareCompletionYamlProjection(safe, candidates, references, ordered)
|
|
|
1776
1804
|
if (piece.block) {
|
|
1777
1805
|
if (!piece.text.isWellFormed())
|
|
1778
1806
|
return { state: "unsupported" };
|
|
1779
|
-
if (rooted && piece.block === "marker" && !/^\[[0-9]+ characters omitted\]$/u.test(piece.text)
|
|
1807
|
+
if (rooted && piece.block === "marker" && !/^\[[0-9]+ characters omitted\]$/u.test(piece.text) &&
|
|
1808
|
+
!(simple && row.continuation_line !== undefined && piece.text === `[Read from line ${row.continuation_line}]`)) {
|
|
1780
1809
|
metadata.text_warnings ??= [];
|
|
1781
1810
|
metadata.text_warnings.push(piece.text);
|
|
1782
1811
|
}
|
|
@@ -1792,7 +1821,7 @@ function prepareCompletionYamlProjection(safe, candidates, references, ordered)
|
|
|
1792
1821
|
packet.records.push({ metadata, parts });
|
|
1793
1822
|
}
|
|
1794
1823
|
const service = rooted ? {
|
|
1795
|
-
header_layout: compact ? "rooted_files_v3" : safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
|
|
1824
|
+
header_layout: simple ? "rooted_files_v4" : compact ? "rooted_files_v3" : safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
|
|
1796
1825
|
} : {};
|
|
1797
1826
|
const omitted = safe.members.length - candidates.length;
|
|
1798
1827
|
if (omitted) {
|
|
@@ -2332,7 +2361,7 @@ export function readRunCompletionPresentation(content, value) {
|
|
|
2332
2361
|
hint.content_sha256 !== createHash("sha256").update(content).digest("hex"))
|
|
2333
2362
|
return full;
|
|
2334
2363
|
const segments = [];
|
|
2335
|
-
const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2" || core.packet.service?.header_layout === "rooted_files_v3";
|
|
2364
|
+
const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2" || core.packet.service?.header_layout === "rooted_files_v3" || core.packet.service?.header_layout === "rooted_files_v4";
|
|
2336
2365
|
const facts = Object.fromEntries(Object.entries(core.packet.service ?? {}).filter(([key]) => key !== "header_layout"));
|
|
2337
2366
|
for (const [index, record] of core.packet.records.entries()) {
|
|
2338
2367
|
if (index)
|
|
@@ -2582,7 +2611,7 @@ export function encodeCompletionYamlCarrier(input) {
|
|
|
2582
2611
|
(!packet.records.length && !Object.hasOwn(packet, "service")))
|
|
2583
2612
|
return unavailable;
|
|
2584
2613
|
const localSingleton = packet.records.length === 1 && completionYamlMapping(packet.service) &&
|
|
2585
|
-
(packet.service.header_layout === "rooted_files_v2" || packet.service.header_layout === "rooted_files_v3") && !Object.hasOwn(packet.service, "numbering");
|
|
2614
|
+
(packet.service.header_layout === "rooted_files_v2" || packet.service.header_layout === "rooted_files_v3" || packet.service.header_layout === "rooted_files_v4") && !Object.hasOwn(packet.service, "numbering");
|
|
2586
2615
|
const rows = [];
|
|
2587
2616
|
for (let index = 0; index < Math.max(1, packet.records.length); index++) {
|
|
2588
2617
|
const row = packet.records[index];
|
|
@@ -81,7 +81,7 @@ Rollout is partial: compact launch/attachment receipts use block YAML; other ope
|
|
|
81
81
|
|
|
82
82
|
Compact launches use bare block-YAML mappings for the Run/state/launch facts and nested observed locations, explicitly identify actual existing-Run reuse, and preserve multiline scalar contents. One leading response-separator LF supplies invocation spacing; it is outside the pure metadata emitter and is not a `---` wrapper. Model/thinking provenance groups are labeled model and thinking, without a redundant _policy suffix; structured data and saved text stay unchanged. A complete direct file-location row needs no repeated session-map hint; absent/unavailable/omitted rows retain one optional next node naming inspect, target=runtime, view=runs and verbose=true. It never executes automatically. Exact locations, verbose details and saved completion formats stay unchanged.
|
|
83
83
|
|
|
84
|
-
Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. Prepend index only when two or more results are shown; exactly one shown result omits it even if other results were omitted. Omission/inventory facts remain explicit. Display index is not member_index or generation; default indices are packet-local. This new-capture rule neither restyles saved messages nor changes numbered-stream presentation. Whole-result/reference omissions and non-done omitted states stay explicit.
|
|
84
|
+
Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. Prepend index only when two or more results are shown; exactly one shown result omits it even if other results were omitted. Omission/inventory facts remain explicit. Display index is not member_index or generation; default indices are packet-local. This new-capture rule neither restyles saved messages nor changes numbered-stream presentation. Whole-result/reference omissions and non-done omitted states stay explicit. Recoverable primary-file prefixes use continue_from_line and [Read from line N] at the cut. Lines are one-based LF file lines, not wrapping; reread a partial line. JSON diagnostics and unmapped text retain [N characters omitted], counting admitted Unicode scalars, never raw/private loss; no extra clipping ellipsis or body clipping flags/counts in YAML. Unknown upstream completeness/privacy remains separately visible at the body boundary, not a fabricated count or a known positive loss. Untracked fallback has no kind and cannot become primary. Full text fitting its share has no display-cut marker; upstream uncertainty still prevents a completeness claim. New packets share48KiB UTF-8 including references/framing across at most64candidate rows, with frozen equal shares and no unused-share redistribution or fixed16KiB result/2KiB preview cap. Captured members remain bounded at256. Text is admitted work output/final response or explicit error/failure diagnostics, never launch commands. Successful composition/retry/Pi text-print can retain text_basis:actor_response; scope and exact references remain technical, while original coverage facts remain structured retained data. The model receives one complete content with whole source/generation/location references or truthful omission/inventory, not a standing full-map instruction. The TUI renders compiler headers/markers as Text and each body as independent native Markdown; only whole validated header reference/location rows and framing disappear in compact view. Body-authored YAML, next/tool/batch and omission lookalikes remain content. Content-bound hashes/ranges/blocks are display consistency, not authentication, source/read/action or acceptance authority. Invalid/missing hints and expansion reveal full original text, without Run-source IO. Old saved codecs, budgets, labels, excerpts, counts and hints replay exactly with no refresh, repair, ACK/resend or restyling—including earlier #N packets and the first frontmatter encoding. Fresh unavailable indices use quoted YAML "?"; an old saved unquoted value is not silently corrected. Routine successful delivery adds no separate completions/delivery-accepted toast; actual failures and handled-generation fences remain. These source/package rules do not prove that an already loaded session was reloaded. Fresh explicit agent Trace previews append boundary … and [omitted: N chars] from normalized retained turn, with a separate upstream [omitted: unknown]. N counts only display loss after existing session privacy, not discarded original/source text. Short well-formed summaries stay unchanged, including authored older-looking markers; malformed retained text yields Agent turn [omitted: unknown] (malformed retained text), never a guessed count or repaired scalar. This is read-time display only, not a rewrite/version of saved packets or sources. Other legacy clipping is not yet uniformly covered. Follow retained references selectively without inventing completeness or permission. Agent Trace ids reference recorded entry provenance, not aggregate traversal order or chronological event numbers. Native entry keys survive sibling growth; bounded legacy/ambiguous/private-metadata fallbacks are not permanent identities, source immutability or new read/work permission.
|
|
85
85
|
|
|
86
86
|
Current completion index fields are packet-local, not persistent historical indices; earlier saved #N headings keep their original meaning. Session completion streams are adopted work in progress, not an available action; do not invent a start-stream command, initialize a missing counter or reinterpret old headings. A kernel-only path commits numbered snapshots/counters/activation atomically. Its internal runtime bridge requires trusted fresh-session opt-in plus current manager/generation binding; the default entrypoint does not opt in and no public tool/command exposes it. Unknown state does not fall back to local numbering on that path. Startup/reload/resume, including ambiguous imports, cannot resume a stream automatically; stored numbers remain data, not a new session grant. A pending target or projected scope is not an active stream. Missing state never authorizes bootstrap, and unknown/conflicting delivery never authorizes bypass or reallocation. Saved numbers stay exact; an admitted unavailable counter or unfitting whole range freezes an unknown index (quoted "?" in fresh YAML, #? in older layouts) rather than resetting or partially numbering a packet.
|
|
87
87
|
|
|
@@ -168,7 +168,7 @@ Run = Recipe + Trace + Control
|
|
|
168
168
|
5. Send `actors_control_apply` only for an action declared and consumed by that controlled Recipe.
|
|
169
169
|
6. Use terminal state, result, declared artifacts, and execution evidence to prove completion. When an outcome includes a retained primary-source, declaration-inventory or diagnostic-metadata reference, use that exact reference for further reading, not guessed captures or sibling files. Literal previews may be clipped; their field/range/counts describe what was shown. Diagnostic sources contain recorded command/error/failure-reason metadata only, not complete primary output; other recorded fields may be referenced without being shown. Artifact inventories list declarations only: they do not assert that target files exist or were produced, or grant body-read permission. Explicit unavailability has no guessed legacy body/path fallback.
|
|
170
170
|
|
|
171
|
-
Compact launch receipts include `run_files` as bare nested YAML with useful exact observed context-index/result/execution/metadata paths and any unavailable-location status, only after current-session/physical identity admission. Routine absent optional files and repeated format/size/mutable/generation metadata stay out of compact content; unavailable or over-budget rows remain explicit. Machine `file_navigation` details stay JSON-compatible; saved terminal messages retain their own original encodings. Selectively ordinary-read those starting locations when needed; layout/size hints are not body, privacy, terminal or native proof. No evidence bodies or session-wide catalog map are read to build this row. New terminal packets also freeze bounded location rows for captured completion members at fresh current-session admission. Fresh rooted completion headers group useful source/artifact and observed context-index/result/execution paths (metadata fallback) under literal roots with relative
|
|
171
|
+
Compact launch receipts include `run_files` as bare nested YAML with useful exact observed context-index/result/execution/metadata paths and any unavailable-location status, only after current-session/physical identity admission. Routine absent optional files and repeated format/size/mutable/generation metadata stay out of compact content; unavailable or over-budget rows remain explicit. Machine `file_navigation` details stay JSON-compatible; saved terminal messages retain their own original encodings. Selectively ordinary-read those starting locations when needed; layout/size hints are not body, privacy, terminal or native proof. No evidence bodies or session-wide catalog map are read to build this row. New terminal packets also freeze bounded location rows for captured completion members at fresh current-session admission. Fresh rooted completion headers group useful source/artifact and observed context-index/result/execution paths (metadata fallback) under literal roots with files as a sequence of relative-entry groups, optional name/status and no role or diagnostic field inventory. Read first appears in one source status only when selected text is incomplete and that file retains more; complete answers or upstream uncertainty alone do not trigger it. Exact primary prefixes add continue_from_line and [Read from line N] at the cut; LF/CRLF file lines are one-based, a partial line is repeated and wrapping/lone CR do not add lines. A long single line can still exceed a reader budget. Diagnostic JSON keeps character counts, not invented file lines. Group-wide status/notes remain optional sibling files_status/files_notes; no cwd guess, source refresh or automatic read follows. Unknown bases stay explicit. Source status preserves admission privacy, Actor-response/exported-text and diagnostic-metadata-only distinctions; declarations remain unverified. Unavailable locations and missing terminal-result locations stay visible. Full generation/hash/location facts stay in machine detail/saved snapshots, not repeated per file. Runtime navigation/omission/inventory facts remain above the Actor Markdown, not in a footer; retained packets keep their original projection. Each shown result keeps its whole Run-file row or explicit per-record omission; wholly omitted results stay covered by result omission/inventory. This describes Run-row coverage, not a complete file/tree inventory. Older captured formats retain their original shown/omitted/total counters; unavailability remains explicit. Ordinary-read selected paths only when needed. Packet reload/render never refreshes sources, and old absent/request-only formats keep their text. Source/npm SDK verifies an explicitly requested ordinary read from a delivered terminal result path; this is research, never routine completion polling or new primary/privacy/clock/native authority. Use the request only for file investigation, not routine completion/status polling. Copied locations/hints remain data, never transferred scope; older batches keep their original text.
|
|
172
172
|
|
|
173
173
|
For selective investigation of already cataloged files, use `actors_inspect target=runtime view=runs verbose=true`, then ordinary file tools on its current-session root-first navigation. Ordinary maps keep latest-registration order between roots and prioritize known failed subtrees within each root. For a failed investigation add status=failed: inventory is filtered, while the full owned map prioritizes observed failed subtrees across roots, always ancestors first. Priority uses only exact-generation matched inventory observations, not complete terminal truth. Launches and compatible singleton attachments populate the catalog; reads do not backfill missing locations. A `catalog: unavailable` launch warning is not workload failure: do not spawn again merely to repair navigation. The starting map's format hints do not certify syntax, encoding or complete output. See [Runs](./references/runs.md) for selective recorded-capture research and resume boundaries.
|
|
174
174
|
|
|
@@ -24,7 +24,7 @@ actors_inspect target=run:<id> view=trace
|
|
|
24
24
|
actors_inspect target=run:<id> view=control
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Fresh root completions use YAML frontmatter (run, state, admitted kind), followed by raw left-edge Markdown. Prepend the packet-local index only when two or more results are shown. Exactly one shown result omits its index even with omitted results; preserve omission/inventory metadata, internal member/generation/correlation and every saved message. This rule does not apply to numbered streams. New source captures put all runtime metadata above that body, with no service/file footer. files
|
|
27
|
+
Fresh root completions use YAML frontmatter (run, state, admitted kind), followed by raw left-edge Markdown. Prepend the packet-local index only when two or more results are shown. Exactly one shown result omits its index even with omitted results; preserve omission/inventory metadata, internal member/generation/correlation and every saved message. This rule does not apply to numbered streams. New source captures put all runtime metadata above that body, with no service/file footer. files is a sequence of literal-root/relative-entry groups without role or diagnostic field inventories. Optional name/status preserve useful meaning; files_status/files_notes retain real group-wide facts. Read first prefixes a source only when its selected text is incomplete and the file retains more, never for a complete answer, unknown upstream loss alone or unrelated metadata. Exact primary prefixes add continue_from_line with [Read from line N] at the cut: one-based LF file lines including CRLF, rereading a partial line. Wrapping/lone CR do not add lines; one long line can still exceed a reader's budget. Diagnostic JSON and unmapped text keep character counts, not invented file-line mapping. Concise facts replace repeated purposes/format/size/mutable/generation dumps; full bindings remain in saved snapshots. Status keeps admission privacy, Actor-response/exported-text, metadata-only diagnostics and unverified declarations distinct. Unavailable locations and missing terminal-result locations stay explicit; Actor Markdown and path/name bytes are unchanged. External paths use separate roots; unknown bases remain explicit rather than guessed from cwd or Run id. Exact line-continuation or character-cut markers alone may follow the cut body; unknown-loss warnings and packet omission/inventory facts stay in the header. Retained captures preserve their old bytes and presentation. No external #N heading, result:/preview: wrapper, list nesting, whole-body fence, Batch caption, members wrapper or routine outer counter is added. Primary/final Actor response uses kind:primary; explicit error/failure diagnostic text uses kind:diagnostic, never a launch command. Untracked fallback has no kind and keeps unknown original completeness/privacy explicit outside YAML. Mapped primary cuts use [Read from line N]; other known cuts use [N characters omitted]. Neither adds an ellipsis or clipping counters/flags in metadata. Unknown upstream loss remains separately unknown and does not assert a known positive omission. Exact useful source/location paths remain in complete model content, while generation/hash/parent bindings stay in the frozen snapshot, with whole references or explicit omission, captured inventory recovery and non-done omitted states. The compact TUI independently renders literal headers/markers and native Markdown bodies from validated content-bound blocks; only whole header reference/location rows and framing are hidden. Expansion and invalid/missing hints reveal original text. Hashes/layout/markers establish consistency/correlation only, never authentication, read/action permission, acceptance or native truth. Authored YAML/next/tool/batch/omission lookalikes stay body content. Fresh packets share48KiB UTF-8 including service data, equally between up to64candidate rows, with256captured members and no redistribution of unused shares or fixed16KiB/2KiB text cap. Full admitted text fitting its share without upstream uncertainty has no cut marker; otherwise use the scalar/CRLF-safe prefix and exact retained-source loss. Allocation/text is frozen at admission; rendering/recovery does not reread sources or reallocate. Unsupported Pi event/control output is withheld. Source basis stays in reference metadata; retained structured coverage facts are not exposed as YAML clipping fields. Pending/queued/presented older formats—including #N records and the first frontmatter draft—keep exact bytes, hints and budgets. Encoding names are storage replay data, not public product choices, source permissions or work authority. No standing full-map instruction or automatic research/read follows; use selective same-session investigation when needed.
|
|
28
28
|
|
|
29
29
|
Current completion index values restart within each packet; they are not session-wide historical references. Completion streams are adopted but not enabled, and no start-stream command is available yet. Do not infer an active stream or reset a counter from missing metadata or a pending target, and never relabel older saved packets. The kernel-only allocator now commits fixed scope/order/indices, the counter and first-packet target activation together, and an internal fresh-session bridge can use it after current manager/generation admission. The default runtime does not opt in; no public action exposes it. Event reason or a matching ID alone is insufficient. Old callbacks/wrappers cannot act after replacement; fresh wrappers must belong to the current original manager. Startup/reload/resume and ambiguous imports remain closed to stream capture/ACK, without changing saved packets or inferring a counter from history. Its whole-range exhaustion or admitted counter unavailability yields a frozen unknown index (quoted "?" in fresh YAML; #? in older saved layouts), never partial indices or an automatic fresh stream. Old packets retain their original scope while a pending switch waits; uncertainty does not permit reallocation. Stream state outlives packet cleanup/receipt rotation. Malformed/missing state remains refused, not a zero counter or proof of non-connection.
|
|
30
30
|
|
package/docs/agent-experience.md
CHANGED
|
@@ -4,9 +4,9 @@ Status: Adopted project-wide design standard. The operator has selected **JSON i
|
|
|
4
4
|
|
|
5
5
|
## One first AX contract
|
|
6
6
|
|
|
7
|
-
AX is one canonical Agent Experience being prepared for its first release, not a product family of numbered drafts or user/model-selectable formats. The selected target is YAML metadata plus optional opaque authored content; the former Markdown-list key/value grammar is an implemented pre-unification layout, not another target to preserve for new output. Ordinary source and normally built package Batch admission now capture ax_records/
|
|
7
|
+
AX is one canonical Agent Experience being prepared for its first release, not a product family of numbered drafts or user/model-selectable formats. The selected target is YAML metadata plus optional opaque authored content; the former Markdown-list key/value grammar is an implemented pre-unification layout, not another target to preserve for new output. Ordinary source and normally built package Batch admission now capture ax_records/completion_yaml_files_v4 over the unchanged completion_yaml_core_v1 carrier, and fresh attention/steer use typed block-YAML metadata plus opaque raw body text. The inactive numbered-stream path and saved frontmatter_v1/v2 retain their older layouts. Bounded source/compiled/actual-default accepted-path evidence exists; it does not establish default-disk, global lifetime-policy or loaded-host acceptance. Remaining rollout is tracked in [BACKLOG.md](../BACKLOG.md).
|
|
8
8
|
|
|
9
|
-
A completion group is the result sequence itself, not a container with members. Each result's YAML metadata begins run, state, then kind:primary for admitted primary text/final Actor response or kind:diagnostic for explicit diagnostics. The admitted Markdown follows from the left margin, outside metadata, with no #N heading, result:/preview: wrapper or whole-body literal fence. One blank separator distinguishes records.
|
|
9
|
+
A completion group is the result sequence itself, not a container with members. Each result's YAML metadata begins run, state, then kind:primary for admitted primary text/final Actor response or kind:diagnostic for explicit diagnostics. The admitted Markdown follows from the left margin, outside metadata, with no #N heading, result:/preview: wrapper or whole-body literal fence. One blank separator distinguishes records. A recoverable primary-text cut uses [Read from line N] with the matching file entry's continue_from_line. Lines are one-based LF-delimited source-file lines (including CRLF), not terminal wrapping; a partly shown line is read again. Diagnostic JSON and text without an exact file-line mapping retain [N characters omitted], counting admitted Unicode scalars. No extra ellipsis or body clipping counters appear in YAML. New rooted captures keep unknown upstream completeness/privacy in header text_warnings without inventing a count or claiming a known positive loss. Retained captures preserve their original body-boundary warnings. Untracked fallback has no primary kind. Missing text stays explicit; a checkpoint retains its Actor-authored notification body. Successful automatic delivery has no extra receipt, routine outer counters, members wrapper, Batch caption, time window, status-summary copies or standing full-map instruction; real failures stay reportable. Exact useful source/location paths remain in complete model content; generation/hash bindings remain in the saved snapshot and full machine detail rather than repeated per file, with whole-reference/result omission and non-done omitted states explicit. Prepend the packet-local index only when two or more results are shown. Exactly one visible row omits its display index even with omitted results; omission/inventory facts and internal member/generation/correlation stay unchanged. This rule does not apply to numbered streams. Fresh ordinary packets put minimal packet identity and relative body/marker lengths in YAML metadata, without compiler HTML tails. Older saved layouts retain their original compiler boundary/correlation framing; neither encoding grants authenticity, read permission or acceptance. Their compatibility boundary is governed separately below; never strip required historical framing. This is one new-capture contract, not a selectable AX product version.
|
|
10
10
|
|
|
11
11
|
Illustrative compact completion shape (not actual Run data):
|
|
12
12
|
|
|
@@ -37,11 +37,13 @@ Storage compatibility is separate: already-captured Batch snapshots need their o
|
|
|
37
37
|
|
|
38
38
|
## Rooted completion files
|
|
39
39
|
|
|
40
|
-
New source captures use a private `
|
|
40
|
+
New source captures use a private `completion_yaml_files_v4` snapshot layout and `rooted_files_v4` service discriminator for compact useful-field navigation and the existing singleton rule. This is replay data, not an input selector or a new status engine. The YAML carrier/hint stays `completion_yaml_core_v1`. Existing snapshots, including rooted v1/v2/v3, keep their exact previous projection, indices and bindings.
|
|
41
41
|
|
|
42
|
-
All runtime metadata belongs above the selected Markdown. New compact views have no service footer, appended file list or runtime warning after the body. A known cut
|
|
42
|
+
All runtime metadata belongs above the selected Markdown. New compact views have no service footer, appended file list or runtime warning after the body. A known primary-file cut adds `[Read from line N]`; diagnostic JSON and unmapped text keep `[N characters omitted]`. Unknown loss/privacy and whole-reference omissions belong in header fields. Authored Markdown, filenames and paths keep their original language/bytes; compiler keys and purpose explanations are English.
|
|
43
43
|
|
|
44
|
-
`files
|
|
44
|
+
`files` is a sequence of literal roots with relative `entries[].path`. Select primary/diagnostic/inventory references, declared artifacts and observed context-index/result/execution paths (metadata fallback), not every technical file. Entries omit `role` and diagnostic field inventories; keep path/name and concise admitted status. Status preserves Actor-response/exported-text, admission privacy, diagnostic-only scope and unverified declarations. Optional `files_status` and `files_notes` retain real group-wide uncertainty and notes beside the sequence. Routine absent optional files and repeated purpose/format/size/mutable/generation/hash facts stay out; full bindings remain in the snapshot.
|
|
45
|
+
|
|
46
|
+
Prefix one entry's status with `Read first;` only when the displayed primary or selected error/failure diagnostic omits retained text recoverable from that source. Complete answers, upstream uncertainty alone, extra diagnostics, declared artifacts and result/execution metadata never trigger it. For a primary prefix starting at file byte zero, `continue_from_line` names the first not-fully-shown LF-delimited file line, repeated in `[Read from line N]` at the cut. CRLF stays intact; lone CR and terminal wrapping do not add file lines. A single long line can still exceed a reader's budget. JSON diagnostic text has no such file-line mapping and retains character counts. No automatic read, current-file guarantee or permission transfer follows.
|
|
45
47
|
|
|
46
48
|
Paths under the observed Run root share that group. External absolute paths have their own literal parent roots. Relative, malformed or dot-segment paths without a safe captured base remain as recorded under a null root with explicit base unavailability; no cwd/Run-id guess, normalization, source read or symlink resolution is allowed. A reader combines a known root and its relative path, never its own cwd. Packet-level inventory references likewise use one root plus relative leaf.
|
|
47
49
|
|
|
@@ -53,22 +55,18 @@ run: "review"
|
|
|
53
55
|
state: "done"
|
|
54
56
|
kind: "primary"
|
|
55
57
|
files:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
status: "Actor response; admission privacy"
|
|
65
|
-
path: "evidence/primary.txt"
|
|
66
|
-
- role: "artifact"
|
|
67
|
-
name: "report"
|
|
68
|
-
path: "artifacts/report.md"
|
|
58
|
+
- root: "/work/runs/review"
|
|
59
|
+
entries:
|
|
60
|
+
- status: "Read first; Actor response; admission privacy"
|
|
61
|
+
continue_from_line: 143
|
|
62
|
+
path: "evidence/primary.txt"
|
|
63
|
+
- name: "report"
|
|
64
|
+
path: "artifacts/report.md"
|
|
65
|
+
files_status: "Declared artifact paths; existence/production unproven"
|
|
69
66
|
---
|
|
70
67
|
|
|
71
|
-
The selected Actor Markdown
|
|
68
|
+
The selected Actor Markdown is truncated here.
|
|
69
|
+
[Read from line 143]
|
|
72
70
|
```
|
|
73
71
|
|
|
74
72
|
The unchanged 48 KiB packet budget includes every root, entry and compiler hint. Outcomes retain priority over optional Run-file rows; whole omitted rows/locations remain explicitly covered. Stored member data, file-navigation DTOs, privacy/source fences and phase recovery are unchanged.
|
|
@@ -113,7 +113,7 @@ Phases are monotonic:
|
|
|
113
113
|
|
|
114
114
|
Every journal mutation uses the canonical token-owned lock, expected-phase fencing, owner and generation validation, and atomic replacement. Repeated transitions are idempotent. Corrupt, oversized, foreign-owner, or stale-generation state fails closed with bounded diagnostics.
|
|
115
115
|
|
|
116
|
-
Ordinary source completion admission has one fresh path: presentation_format=ax_records, private result_layout=
|
|
116
|
+
Ordinary source completion admission has one fresh path: presentation_format=ax_records, private result_layout=completion_yaml_files_v4 and frozen text_budget, without excerpt_format or a public selector. The inactive numbered-stream kernel path keeps its separate frontmatter_v2 default. Bounded source/compiled and actual-default source/packed acceptance observes the normal index path and in-memory entry/context/provider/hint tuple. Unchanged storage/registered-renderer/accepted-history-reopen facts transfer only on the successful original-current-manager path; this is neither fresh default-disk observation nor global lifetime-policy, native-scope or loaded-host acceptance. Direct admission and ordinary run-ui-runtime use it after unchanged owner/location checks; an existing batch stays untouched. Each shown record begins YAML frontmatter with run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit error/failure excerpts. Untracked fallback has no kind and retains unknown completeness/privacy outside YAML. The closed header is followed by raw, unindented Markdown, with no #N heading, result:/preview: wrapper or compiler literal fence around the body. Exact primary-file prefixes use continue_from_line and [Read from line N] at the cut, with one-based LF/CRLF file lines and a partial line read again. Diagnostic JSON and unmapped text keep [N characters omitted], counting admitted postprivacy scalars, not private/native output. No extra ellipsis follows. Unknown upstream loss remains separate. Original coverage and full source/generation/hash/location bindings remain structured frozen member data. Compact headers select useful exact rooted paths and concise deterministic status, not per-file technical dumps. Keep admission-privacy/source-kind/metadata-only/declaration uncertainty, unavailable locations, missing terminal-result locations and whole-reference omission visible; omit routine absent optional files. No source reads or probes participate in formatting. Routine summaries/windows/status copies/standing map instructions remain journal facts, not duplicated model content. Prepend a packet-local index only when two or more results are shown; exactly one shown result omits only that display field even if other results were omitted. Internal member_index, generation and correlation remain unchanged; the rooted_files_v4 discriminator gates fresh compact navigation and this rule, not member count in an older snapshot or numbered-stream scope. Material omitted_results, non-done omitted_states and whole result_inventory recovery stay explicit. Each shown record has a whole run_files row or explicit omission, with unavailable reasons retained; omitted records do not leave orphan location rows. Outcomes precede lower-priority references under the total48KiB UTF-8/64candidate-row bound including framing. Prefix admission considers full-list and decimal-count discontinuities, freezes equal scalar/CRLF-safe shares without unused-share redistribution, and never clips references or rewrites a retained excerpt. Older captures retain their original16KiB/48KiB budgets.
|
|
117
117
|
|
|
118
118
|
Fresh ordinary source hints carry the core format and whole-content digest; the validated YAML core carries only packet identity and relative body/marker lengths, from which boundaries are derived. It adds no fresh HTML tail or duplicate coordinate table. These are consistency facts, not source or acceptance authority.
|
|
119
119
|
|
|
@@ -131,7 +131,7 @@ Removing fresh collection of untracked bodies would leave affected old/intermedi
|
|
|
131
131
|
|
|
132
132
|
### Retained capture compatibility
|
|
133
133
|
|
|
134
|
-
The numbered wire strings ax_records_v1/v2/v3, old indexed/single_result captures and result_layout records/run_headers/headings/headings_flat_omissions/headings_outcomes/headings_shared_results/headings_shared_kinds/frontmatter_v1/frontmatter_v2 are retained storage encodings, not public alternatives. Fresh ordinary source admission chooses own-data
|
|
134
|
+
The numbered wire strings ax_records_v1/v2/v3, old indexed/single_result captures and result_layout records/run_headers/headings/headings_flat_omissions/headings_outcomes/headings_shared_results/headings_shared_kinds/frontmatter_v1/frontmatter_v2 are retained storage encodings, not public alternatives. Fresh ordinary source admission chooses own-data completion_yaml_files_v4 with canonical ax_records and text_budget (over the unchanged completion_yaml_core_v1 carrier); earlier completion_yaml_core_v1 and completion_yaml_files_v1/v2/v3 snapshots retain their exact old layouts and indices, never single_result. Absence preserves its original indexed/singleton codec; inherited aspects never restyle data and accessors are refused without invocation. Earlier record/header/count/kind grammar and each captured16KiB/48KiB share remain exact. The first frontmatter draft retains its original bytes and hints, including unquoted unknown index ?. Retained v2 fixed that one YAML case by writing index: "?"; numeric indices and other fields/body bytes are unchanged, and the presentation-hint schema remains completion_frontmatter_v1 because its block structure is unchanged. Preserve the frozen v1 unknown-content fingerprint90e29fb36087e2620fe0cf150b4238bce8a6d1dcc68ee922a1cf71ee8604610e and prior shared-result fingerprint4428de318b8ebaa029d3588ab7e8e705b9a80fa5cf08b6a2cc7151916207e266. Journals store snapshots rather than complete text: neither an unreleased product, a YAML correction nor member count permits relabeling/migration. Pending/queued/presented replay must reproduce original model bytes and hints without operator journal scans, source refresh or message rewrites. Removing compatibility requires a separate history-lifetime decision.
|
|
135
135
|
|
|
136
136
|
Steer envelopes already store complete content. Both attention and steer now have one canonical new-message formatter with no presentation selector; the redundant legacy formatting branches/path/body helpers are removed where no retained-data consumer needs them. Existing steer identity is reused before formatting and saved content bypasses the formatter in every pending/queued/presented recovery path. Removing stored Batch codecs later requires a separate retention/data-lifetime decision; an unreleased product is not permission to change previously captured delivery bytes.
|
|
137
137
|
|
|
@@ -91,7 +91,7 @@ F1.6 source-audit correction: Pi 1.0 native custom-message storage, session reco
|
|
|
91
91
|
### 10. Completion Projection, Compiler Frame and Native Renderer
|
|
92
92
|
|
|
93
93
|
- **Owners:** `run-delivery.ts:1510` `completionRecordRow`, `:1683` `assembleFrontmatter`, `:1886` `projectCompletionRecords`, `:2110` `projectRunCompletionBatchPresentation`, `:2233` `readRunCompletionPresentation`, `:2283` retained projection, `:2328` message formatting. `run-ui-runtime.ts:68` `registerRunCompletionRenderer` is wired at `extension-runtime.ts:122`.
|
|
94
|
-
- **Current:** Fresh ordinary `
|
|
94
|
+
- **Current:** Fresh ordinary `completion_yaml_files_v4` snapshots use the unchanged strict YAML-core carrier. Header files is a sequence of literal roots with selected relative source/artifact/Run-file entries and concise admitted status, without roles or diagnostic field inventories. Optional files_status/files_notes retain group-wide facts. Read first prefixes only a recoverable truncated source; exact primary prefixes add continue_from_line and [Read from line N]. Full source bindings remain in the snapshot. Unknown-base paths stay explicitly as recorded. Native compact presentation exposes those file groups and places omission/inventory facts in the first header, never after the Markdown. Only exact file-line continuation or known character-cut markers remain beside a truncated body. Exactly one shown result omits its packet-local display index, including with omissions; multiple shown results retain indices. Internal member/generation/correlation and omission/inventory facts stay unchanged. Earlier rooted-v1/v2/v3, core-v1 and historical layouts keep their exact indices, projection and hiding/footer behavior; numbered streams are separate.
|
|
95
95
|
- **Prepared wire core:** `run-delivery.ts` `encodeCompletionYamlCarrier` / `readCompletionYamlCarrier` provide the accepted pure/nondefault mechanics; the prototype encodes and typed native view decodes them. Ordinary source/default capture uses the rooted snapshot layout; the earlier core-v1 snapshot and inactive numbered-stream frontmatter_v2 remain separate replay/gated paths. Strict-core Pi correlation and source/packed SDK evidence bind the selected content without granting native or read authority. They encode one `_completion` packet ID/codec and relative body/marker lengths, then derive dense ranges while decoding. Canonical bare headers are independent YAML fragments separated by codec-owned blank lines, not one mapping or a standard YAML multi-document stream; body-present headers are delimited and raw parts remain opaque. All-omitted is bare service metadata, not a fake Run. Empty selected bodies are distinct from absent bodies; empty-marker-only wrappers are refused. Input uses named top-level result keys with explicit depth/work bounds; loaded-host acceptance remains F1.7/U1-gated, and meaningful service warnings must not be hidden wholesale.
|
|
96
96
|
- **Prepared source projection (nondefault):** `projectRunCompletionYamlPrototype` projects current AX/frontmatter selected snapshots through one shared private fitter; it returns content, a format/digest-only hint and fitting facts, not a newly admitted or relabeled Batch. Frozen budgets/prefixes remain immutable. Canonical header/raw-part costs are measured additively, with unsupported data distinct from byte overflow; final content must agree with the unchanged core encoder/decoder. This prototype API remains data-only and source-class restricted. The ordinary rooted capture reuses internal YAML assembly and the same independently measured quotas/inventory rather than relabeling an old frozen snapshot. Native renderer support is prepared below; actual carrier acceptance remains a separate gate.
|
|
97
97
|
- **Native view:** `readRunCompletionPresentation` derives frozen typed segments from the strict core and exact minimal format/digest hint; the registered renderer keeps new rooted file groups and all meaningful service facts in headers, then renders each body as independent native Markdown with literal Text metadata/markers. Retained core-v1 captures keep their earlier reference hiding and service placement. Valid-core missing/invalid hints and declared-new malformed content expose original full Text; expansion keeps that same source. Malformed content without a safely readable own new-format declaration retains historical dispatch, not a body-scanning heuristic. Headless widths/padding and old-history preservation are proved. Repo SDK 1.0.0's public `CustomMessageComponent` falls back to one Markdown component when a renderer is absent, returns undefined or throws, joining text-block arrays; a fresh component probe confirms this boundary, not session/interactive dispatch. Preserve that fallback unchanged: full content supplied to Markdown is neither independent-body rendering nor literal-visibility proof. Independent Markdown belongs only to the validated registered compact branch; registered degraded/expanded views keep original Text. Actual source-admitted native storage/context/provider/reopen and loaded terminal/phone behavior remain separate acceptance.
|
package/lib/run-delivery.ts
CHANGED
|
@@ -69,7 +69,7 @@ export interface RunCompletionBatch {
|
|
|
69
69
|
/** Retained singleton capture; absence preserves older indexed bytes. Never a new-capture selector. */
|
|
70
70
|
readonly single_result?: true;
|
|
71
71
|
/** Captured record-list shape; no public format/version choice or source authority. */
|
|
72
|
-
readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" | "completion_yaml_files_v3";
|
|
72
|
+
readonly result_layout?: "records" | "run_headers" | "headings" | "headings_flat_omissions" | "headings_outcomes" | "headings_shared_results" | "headings_shared_kinds" | "frontmatter_v1" | "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" | "completion_yaml_files_v3" | "completion_yaml_files_v4";
|
|
73
73
|
/** Immutable scope/order/range data, not a caller-selected format or allocation authority. */
|
|
74
74
|
readonly numbering?: RunCompletionNumbering;
|
|
75
75
|
/** Formatting version/data only; no recipient ownership, read or publication capability. */
|
|
@@ -468,7 +468,7 @@ function isFrontmatterCompletionLayout(layout: unknown): boolean {
|
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
function isRootedCompletionLayout(layout: unknown): boolean {
|
|
471
|
-
return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2" || layout === "completion_yaml_files_v3";
|
|
471
|
+
return layout === "completion_yaml_files_v1" || layout === "completion_yaml_files_v2" || layout === "completion_yaml_files_v3" || layout === "completion_yaml_files_v4";
|
|
472
472
|
}
|
|
473
473
|
|
|
474
474
|
function isYamlCompletionLayout(layout: unknown): boolean {
|
|
@@ -899,7 +899,7 @@ export function requestRunCompletionStream(input: { tempDir: string; ownerId: st
|
|
|
899
899
|
}
|
|
900
900
|
|
|
901
901
|
export function admitRunCompletionBatch(input: AdmitRunCompletionBatchInput): RunCompletionBatch {
|
|
902
|
-
return captureCompletionBatch(input, false, "
|
|
902
|
+
return captureCompletionBatch(input, false, "completion_yaml_files_v4");
|
|
903
903
|
}
|
|
904
904
|
|
|
905
905
|
/** Kernel-only opt-in; ordinary Pi capture stays fenced until session/lifecycle integration is admitted. */
|
|
@@ -909,10 +909,10 @@ export function captureRunCompletionStreamBatch(input: AdmitRunCompletionBatchIn
|
|
|
909
909
|
|
|
910
910
|
/** Private ordinary candidate composition; stream capture retains its separately gated codec. */
|
|
911
911
|
export function captureRunCompletionYamlCandidateBatch(input: AdmitRunCompletionBatchInput): RunCompletionBatch {
|
|
912
|
-
return captureCompletionBatch(input, false, "
|
|
912
|
+
return captureCompletionBatch(input, false, "completion_yaml_files_v4");
|
|
913
913
|
}
|
|
914
914
|
|
|
915
|
-
function captureCompletionBatch(input: AdmitRunCompletionBatchInput, numbered: boolean, layout: "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" | "completion_yaml_files_v3" = "frontmatter_v2"): RunCompletionBatch {
|
|
915
|
+
function captureCompletionBatch(input: AdmitRunCompletionBatchInput, numbered: boolean, layout: "frontmatter_v2" | "completion_yaml_core_v1" | "completion_yaml_files_v1" | "completion_yaml_files_v2" | "completion_yaml_files_v3" | "completion_yaml_files_v4" = "frontmatter_v2"): RunCompletionBatch {
|
|
916
916
|
const now = (input.now ?? new Date()).toISOString();
|
|
917
917
|
if (Object.hasOwn(input, "presentationFormat")) throw new Error("Completion presentation selection is not supported; new batches use AX.");
|
|
918
918
|
if (Object.hasOwn(input, "numbering")) throw new Error("Completion numbering is assigned only by journal capture");
|
|
@@ -1495,7 +1495,7 @@ export function readRunCompletionRecordMarker(content: string): { batchId: strin
|
|
|
1495
1495
|
export type CompletionBlock = readonly [kind: "header" | "body" | "marker" | "service", start: number, end: number];
|
|
1496
1496
|
type CompletionPiece = { text: string; compact: boolean; block?: CompletionBlock[0]; field?: readonly [string, string] };
|
|
1497
1497
|
type CompletionRow = { pieces: CompletionPiece[]; technical: string; technical_data: Record<string, unknown>; legacy: boolean;
|
|
1498
|
-
completion_text?: Readonly<RunCompletionText
|
|
1498
|
+
completion_text?: Readonly<RunCompletionText>; continuation_line?: number };
|
|
1499
1499
|
|
|
1500
1500
|
function completionPiece(key: string, value: string, depth = 0, compact = true): CompletionPiece {
|
|
1501
1501
|
return { text: formatMarkdownField(key, value, depth), compact, field: [key, value] };
|
|
@@ -1546,6 +1546,9 @@ function completionRecordRow(member: RunCompletionBatchMember, index: number, by
|
|
|
1546
1546
|
end: diagnostic.shown_bytes.start + selected.shown_bytes.end }, chars_shown: shown,
|
|
1547
1547
|
chars_omitted: diagnostic.chars_total - shown, truncated: shown < diagnostic.chars_total };
|
|
1548
1548
|
}
|
|
1549
|
+
// LF-delimited file lines, not terminal wrapping; a partial final line must be read again.
|
|
1550
|
+
const continuationLine = layout === "completion_yaml_files_v4" && primary && primary.chars_omitted > 0 && primary.shown_bytes.start === 0
|
|
1551
|
+
? primary.preview.split("\n").length : undefined;
|
|
1549
1552
|
const kind = primary ? primary.text_basis === "actor_response" ? "response" : "primary" : diagnostic ? "diagnostic" : member.output ? "legacy" : undefined;
|
|
1550
1553
|
const boilerplate = isRoutineCompletionSummary(member);
|
|
1551
1554
|
let legacy = !!member.output;
|
|
@@ -1584,7 +1587,8 @@ function completionRecordRow(member: RunCompletionBatchMember, index: number, by
|
|
|
1584
1587
|
if (frontmatter) {
|
|
1585
1588
|
if (chosen && chosen.shown_bytes.start > 0) pieces.push({ text: "[omitted: unknown] (retained excerpt starts after the source boundary)", compact: true, block: "marker" });
|
|
1586
1589
|
pieces.push({ text: value, compact: true, block: "body" });
|
|
1587
|
-
if (chosen && chosen.chars_omitted > 0) pieces.push({ text:
|
|
1590
|
+
if (chosen && chosen.chars_omitted > 0) pieces.push({ text: continuationLine === undefined
|
|
1591
|
+
? `[${chosen.chars_omitted} characters omitted]` : `[Read from line ${continuationLine}]`, compact: true, block: "marker" });
|
|
1588
1592
|
} else {
|
|
1589
1593
|
const complete = shared && primary && primary.shown_bytes.start === 0 && primary.shown_bytes.end === primary.bytes_total && !primary.upstream_truncated;
|
|
1590
1594
|
pieces.push(...completionPreview(value, depth, !!chosen && chosen.shown_bytes.start > 0,
|
|
@@ -1635,7 +1639,8 @@ function completionRecordRow(member: RunCompletionBatchMember, index: number, by
|
|
|
1635
1639
|
pieces.push(completionPiece("artifact_declarations", String(artifacts.length), depth));
|
|
1636
1640
|
technical.artifacts = { scope: "Declared paths; existence/production unproven.", declarations: artifacts.map(([name, path]) => ({ name, path })) };
|
|
1637
1641
|
}
|
|
1638
|
-
return { pieces, technical: Object.keys(technical).length ? formatMarkdownField(flat ? "result_details" : `#${index}`, formatLiteralBlock(JSON.stringify(technical, null, 2))) : "", technical_data: technical, legacy, ...(completionText ? { completion_text: completionText } : {})
|
|
1642
|
+
return { pieces, technical: Object.keys(technical).length ? formatMarkdownField(flat ? "result_details" : `#${index}`, formatLiteralBlock(JSON.stringify(technical, null, 2))) : "", technical_data: technical, legacy, ...(completionText ? { completion_text: completionText } : {}),
|
|
1643
|
+
...(continuationLine === undefined ? {} : { continuation_line: continuationLine }) };
|
|
1639
1644
|
}
|
|
1640
1645
|
|
|
1641
1646
|
const FRONTMATTER_FRAME = "<!-- pi-actors:frontmatter ";
|
|
@@ -1810,7 +1815,7 @@ function rootedCompletionPath(path: CompletionYamlData, runRoot?: string): { roo
|
|
|
1810
1815
|
}
|
|
1811
1816
|
|
|
1812
1817
|
/** Body-free, read-free navigation over already selected references. Roots are presentation bases, not containment proof. */
|
|
1813
|
-
function completionRootedFiles(row: CompletionRow, member: RunCompletionBatchMember, locations?: RunDirectoryNavigation, compact = false): Record<string, CompletionYamlData> {
|
|
1818
|
+
function completionRootedFiles(row: CompletionRow, member: RunCompletionBatchMember, locations?: RunDirectoryNavigation, compact = false, simple = false): Record<string, CompletionYamlData> {
|
|
1814
1819
|
const technical = completionYamlReferences(row), files: Record<string, CompletionYamlData> = {};
|
|
1815
1820
|
const status: string[] = [];
|
|
1816
1821
|
const groups: Array<{ root: CompletionYamlData; entries: Record<string, CompletionYamlData>[] }> = [];
|
|
@@ -1825,11 +1830,18 @@ function completionRootedFiles(row: CompletionRow, member: RunCompletionBatchMem
|
|
|
1825
1830
|
const selected = rootedCompletionPath(path, runRoot);
|
|
1826
1831
|
const index = group(selected?.root ?? (base === undefined ? null : completionYamlString(base)));
|
|
1827
1832
|
const selectedPath = selected?.path ?? path;
|
|
1828
|
-
|
|
1829
|
-
...(!selected && base === undefined ? { path_basis: "as_recorded", base_unavailable: true } : {}) }
|
|
1833
|
+
const shown: Record<string, CompletionYamlData> = { ...entry, path: selectedPath,
|
|
1834
|
+
...(!selected && base === undefined ? { path_basis: "as_recorded", base_unavailable: true } : {}) };
|
|
1835
|
+
groups[index]!.entries.push(shown);
|
|
1830
1836
|
if (selected && rank < priority) {
|
|
1831
|
-
priority = rank;
|
|
1837
|
+
priority = rank;
|
|
1838
|
+
if (simple) {
|
|
1839
|
+
shown.status = `Read first; ${entry.status}`;
|
|
1840
|
+
if (row.continuation_line !== undefined && entry.role === "primary") shown.continue_from_line = row.continuation_line;
|
|
1841
|
+
}
|
|
1842
|
+
else files.read_first = { group: index, entry: groups[index]!.entries.length - 1 };
|
|
1832
1843
|
}
|
|
1844
|
+
if (simple) { delete shown.role; delete shown.recorded_fields_not_shown; }
|
|
1833
1845
|
};
|
|
1834
1846
|
for (const [role, purpose, rank] of [
|
|
1835
1847
|
["primary", "Full result text", 0], ["diagnostic_metadata", "Recorded error and command metadata", 1],
|
|
@@ -1839,10 +1851,13 @@ function completionRootedFiles(row: CompletionRow, member: RunCompletionBatchMem
|
|
|
1839
1851
|
if (!detail) continue;
|
|
1840
1852
|
const { source: rawSource, ...facts } = detail;
|
|
1841
1853
|
const { path, ...binding } = rawSource as Record<string, CompletionYamlData>;
|
|
1854
|
+
const coverage = row.technical_data[role] as ReturnType<typeof completionCoverage> | undefined;
|
|
1855
|
+
const continuation = (role === "primary" || (role === "diagnostic_metadata" && !row.technical_data.primary)) &&
|
|
1856
|
+
coverage?.state === "clipped" && coverage.chars_total > coverage.chars_shown;
|
|
1842
1857
|
add(path!, compact ? { role, ...(role === "primary" ? { status: facts.text_basis === "actor_response" ? "Actor response; admission privacy" : "Exported text; admission privacy, not complete Actor output" }
|
|
1843
1858
|
: role === "diagnostic_metadata" ? { status: "Recorded diagnostic metadata only; admission privacy",
|
|
1844
1859
|
...(facts.recorded_fields_not_shown ? { recorded_fields_not_shown: facts.recorded_fields_not_shown } : {}) }
|
|
1845
|
-
: { status: "Declarations only; target availability/production unproven" }) } : { role, purpose, ...facts, source: binding }, rank);
|
|
1860
|
+
: { status: "Declarations only; target availability/production unproven" }) } : { role, purpose, ...facts, source: binding }, simple && !continuation ? Infinity : rank);
|
|
1846
1861
|
delete technical[role];
|
|
1847
1862
|
}
|
|
1848
1863
|
const artifacts = technical.artifacts as { scope: string; declarations: { name: CompletionYamlData; path: CompletionYamlData }[] } | undefined;
|
|
@@ -1867,7 +1882,7 @@ function completionRootedFiles(row: CompletionRow, member: RunCompletionBatchMem
|
|
|
1867
1882
|
const { path, ...facts } = item;
|
|
1868
1883
|
const purpose = item.role === "result" ? "Recorded result metadata" : item.role === "execution" ? "Recorded execution and capture locations" : "Recorded Run file";
|
|
1869
1884
|
add(typeof path === "string" ? completionYamlString(path) : null, compact ? { role: item.role } : { ...facts, purpose },
|
|
1870
|
-
item.state === "present" && item.role === "result" ? 3 : item.state === "present" && item.role === "execution" ? 4 : Infinity, directory);
|
|
1885
|
+
!simple && item.state === "present" && item.role === "result" ? 3 : !simple && item.state === "present" && item.role === "execution" ? 4 : Infinity, directory);
|
|
1871
1886
|
}
|
|
1872
1887
|
} else if (locations) {
|
|
1873
1888
|
if (compact) status.push(`Run locations unavailable: ${locations.reason}`);
|
|
@@ -1890,7 +1905,8 @@ function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: r
|
|
|
1890
1905
|
references: ReadonlySet<number>, ordered: readonly RunCompletionBatchMember[]): PreparedCompletionYamlProjection {
|
|
1891
1906
|
const packet: CompletionYamlPacket = { batchId: safe.batch_id, records: [] };
|
|
1892
1907
|
const rooted = isRootedCompletionLayout(safe.result_layout);
|
|
1893
|
-
const
|
|
1908
|
+
const simple = safe.result_layout === "completion_yaml_files_v4";
|
|
1909
|
+
const compact = simple || safe.result_layout === "completion_yaml_files_v3";
|
|
1894
1910
|
const localSingleton = (compact || safe.result_layout === "completion_yaml_files_v2") && !safe.numbering && candidates.length === 1;
|
|
1895
1911
|
if (!safe.batch_id.isWellFormed()) return { state: "unsupported" };
|
|
1896
1912
|
for (const [index, { row, location }] of candidates.entries()) {
|
|
@@ -1911,8 +1927,12 @@ function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: r
|
|
|
1911
1927
|
const navigation = references.has(index) && location
|
|
1912
1928
|
? safe.file_navigation!.find(item => safe.members[item.member_index] === member)!.locations : undefined;
|
|
1913
1929
|
if (rooted) {
|
|
1914
|
-
const files = completionRootedFiles(row, member, navigation, compact);
|
|
1915
|
-
if (
|
|
1930
|
+
const files = completionRootedFiles(row, member, navigation, compact, simple);
|
|
1931
|
+
if (simple) {
|
|
1932
|
+
if (files.groups) metadata.files = files.groups;
|
|
1933
|
+
if (files.status) metadata.files_status = files.status;
|
|
1934
|
+
if (files.notes) metadata.files_notes = files.notes;
|
|
1935
|
+
} else if (Object.keys(files).length) metadata.files = files;
|
|
1916
1936
|
} else {
|
|
1917
1937
|
const technical = completionYamlReferences(row);
|
|
1918
1938
|
if (Object.keys(technical).length) metadata.references = technical;
|
|
@@ -1928,7 +1948,8 @@ function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: r
|
|
|
1928
1948
|
const add = (part: CompletionYamlPart) => { if (parts.length) parts.push({ marker: "\n" }); parts.push(part); };
|
|
1929
1949
|
for (const piece of row.pieces) if (piece.block) {
|
|
1930
1950
|
if (!piece.text.isWellFormed()) return { state: "unsupported" };
|
|
1931
|
-
if (rooted && piece.block === "marker" && !/^\[[0-9]+ characters omitted\]$/u.test(piece.text)
|
|
1951
|
+
if (rooted && piece.block === "marker" && !/^\[[0-9]+ characters omitted\]$/u.test(piece.text) &&
|
|
1952
|
+
!(simple && row.continuation_line !== undefined && piece.text === `[Read from line ${row.continuation_line}]`)) {
|
|
1932
1953
|
metadata.text_warnings ??= [];
|
|
1933
1954
|
(metadata.text_warnings as CompletionYamlData[]).push(piece.text);
|
|
1934
1955
|
} else add(piece.block === "body" ? { body: piece.text } : { marker: piece.text });
|
|
@@ -1940,7 +1961,7 @@ function prepareCompletionYamlProjection(safe: RunCompletionBatch, candidates: r
|
|
|
1940
1961
|
packet.records.push({ metadata, parts });
|
|
1941
1962
|
}
|
|
1942
1963
|
const service: Record<string, CompletionYamlData> = rooted ? {
|
|
1943
|
-
header_layout: compact ? "rooted_files_v3" : safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
|
|
1964
|
+
header_layout: simple ? "rooted_files_v4" : compact ? "rooted_files_v3" : safe.result_layout === "completion_yaml_files_v2" ? "rooted_files_v2" : "rooted_files_v1",
|
|
1944
1965
|
} : {};
|
|
1945
1966
|
const omitted = safe.members.length - candidates.length;
|
|
1946
1967
|
if (omitted) {
|
|
@@ -2373,7 +2394,7 @@ export function readRunCompletionPresentation(content: string, value: unknown):
|
|
|
2373
2394
|
!completionYamlKeys(hint, ["format", "content_sha256"]) || hint.format !== completionYamlCodec ||
|
|
2374
2395
|
hint.content_sha256 !== createHash("sha256").update(content).digest("hex")) return full;
|
|
2375
2396
|
const segments: NonNullable<RunCompletionPresentationView["segments"]>[number][] = [];
|
|
2376
|
-
const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2" || core.packet.service?.header_layout === "rooted_files_v3";
|
|
2397
|
+
const rooted = core.packet.service?.header_layout === "rooted_files_v1" || core.packet.service?.header_layout === "rooted_files_v2" || core.packet.service?.header_layout === "rooted_files_v3" || core.packet.service?.header_layout === "rooted_files_v4";
|
|
2377
2398
|
const facts = Object.fromEntries(Object.entries(core.packet.service ?? {}).filter(([key]) => key !== "header_layout"));
|
|
2378
2399
|
for (const [index, record] of core.packet.records.entries()) {
|
|
2379
2400
|
if (index) segments.push({ kind: "separator", text: "\n" });
|
|
@@ -2606,7 +2627,7 @@ export function encodeCompletionYamlCarrier(input: unknown): { state: "available
|
|
|
2606
2627
|
(Object.hasOwn(packet, "service") && (!completionYamlMapping(packet.service) || !Object.keys(packet.service).length)) ||
|
|
2607
2628
|
(!packet.records.length && !Object.hasOwn(packet, "service"))) return unavailable;
|
|
2608
2629
|
const localSingleton = packet.records.length === 1 && completionYamlMapping(packet.service) &&
|
|
2609
|
-
(packet.service.header_layout === "rooted_files_v2" || packet.service.header_layout === "rooted_files_v3") && !Object.hasOwn(packet.service, "numbering");
|
|
2630
|
+
(packet.service.header_layout === "rooted_files_v2" || packet.service.header_layout === "rooted_files_v3" || packet.service.header_layout === "rooted_files_v4") && !Object.hasOwn(packet.service, "numbering");
|
|
2610
2631
|
const rows: string[] = [];
|
|
2611
2632
|
for (let index = 0; index < Math.max(1, packet.records.length); index++) {
|
|
2612
2633
|
const row: CompletionYamlData | undefined = packet.records[index];
|
package/package.json
CHANGED
package/skills/actors/SKILL.md
CHANGED
|
@@ -81,7 +81,7 @@ Rollout is partial: compact launch/attachment receipts use block YAML; other ope
|
|
|
81
81
|
|
|
82
82
|
Compact launches use bare block-YAML mappings for the Run/state/launch facts and nested observed locations, explicitly identify actual existing-Run reuse, and preserve multiline scalar contents. One leading response-separator LF supplies invocation spacing; it is outside the pure metadata emitter and is not a `---` wrapper. Model/thinking provenance groups are labeled model and thinking, without a redundant _policy suffix; structured data and saved text stay unchanged. A complete direct file-location row needs no repeated session-map hint; absent/unavailable/omitted rows retain one optional next node naming inspect, target=runtime, view=runs and verbose=true. It never executes automatically. Exact locations, verbose details and saved completion formats stay unchanged.
|
|
83
83
|
|
|
84
|
-
Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. Prepend index only when two or more results are shown; exactly one shown result omits it even if other results were omitted. Omission/inventory facts remain explicit. Display index is not member_index or generation; default indices are packet-local. This new-capture rule neither restyles saved messages nor changes numbered-stream presentation. Whole-result/reference omissions and non-done omitted states stay explicit.
|
|
84
|
+
Fresh automatic completions have one AX capture path with no format selector: YAML frontmatter begins run, state, then kind:primary for admitted primary/final Actor response or kind:diagnostic for explicit diagnostics. Markdown follows unindented outside the closed metadata block, without #N heading, result:/preview: wrapper or whole-body literal fence. Prepend index only when two or more results are shown; exactly one shown result omits it even if other results were omitted. Omission/inventory facts remain explicit. Display index is not member_index or generation; default indices are packet-local. This new-capture rule neither restyles saved messages nor changes numbered-stream presentation. Whole-result/reference omissions and non-done omitted states stay explicit. Recoverable primary-file prefixes use continue_from_line and [Read from line N] at the cut. Lines are one-based LF file lines, not wrapping; reread a partial line. JSON diagnostics and unmapped text retain [N characters omitted], counting admitted Unicode scalars, never raw/private loss; no extra clipping ellipsis or body clipping flags/counts in YAML. Unknown upstream completeness/privacy remains separately visible at the body boundary, not a fabricated count or a known positive loss. Untracked fallback has no kind and cannot become primary. Full text fitting its share has no display-cut marker; upstream uncertainty still prevents a completeness claim. New packets share48KiB UTF-8 including references/framing across at most64candidate rows, with frozen equal shares and no unused-share redistribution or fixed16KiB result/2KiB preview cap. Captured members remain bounded at256. Text is admitted work output/final response or explicit error/failure diagnostics, never launch commands. Successful composition/retry/Pi text-print can retain text_basis:actor_response; scope and exact references remain technical, while original coverage facts remain structured retained data. The model receives one complete content with whole source/generation/location references or truthful omission/inventory, not a standing full-map instruction. The TUI renders compiler headers/markers as Text and each body as independent native Markdown; only whole validated header reference/location rows and framing disappear in compact view. Body-authored YAML, next/tool/batch and omission lookalikes remain content. Content-bound hashes/ranges/blocks are display consistency, not authentication, source/read/action or acceptance authority. Invalid/missing hints and expansion reveal full original text, without Run-source IO. Old saved codecs, budgets, labels, excerpts, counts and hints replay exactly with no refresh, repair, ACK/resend or restyling—including earlier #N packets and the first frontmatter encoding. Fresh unavailable indices use quoted YAML "?"; an old saved unquoted value is not silently corrected. Routine successful delivery adds no separate completions/delivery-accepted toast; actual failures and handled-generation fences remain. These source/package rules do not prove that an already loaded session was reloaded. Fresh explicit agent Trace previews append boundary … and [omitted: N chars] from normalized retained turn, with a separate upstream [omitted: unknown]. N counts only display loss after existing session privacy, not discarded original/source text. Short well-formed summaries stay unchanged, including authored older-looking markers; malformed retained text yields Agent turn [omitted: unknown] (malformed retained text), never a guessed count or repaired scalar. This is read-time display only, not a rewrite/version of saved packets or sources. Other legacy clipping is not yet uniformly covered. Follow retained references selectively without inventing completeness or permission. Agent Trace ids reference recorded entry provenance, not aggregate traversal order or chronological event numbers. Native entry keys survive sibling growth; bounded legacy/ambiguous/private-metadata fallbacks are not permanent identities, source immutability or new read/work permission.
|
|
85
85
|
|
|
86
86
|
Current completion index fields are packet-local, not persistent historical indices; earlier saved #N headings keep their original meaning. Session completion streams are adopted work in progress, not an available action; do not invent a start-stream command, initialize a missing counter or reinterpret old headings. A kernel-only path commits numbered snapshots/counters/activation atomically. Its internal runtime bridge requires trusted fresh-session opt-in plus current manager/generation binding; the default entrypoint does not opt in and no public tool/command exposes it. Unknown state does not fall back to local numbering on that path. Startup/reload/resume, including ambiguous imports, cannot resume a stream automatically; stored numbers remain data, not a new session grant. A pending target or projected scope is not an active stream. Missing state never authorizes bootstrap, and unknown/conflicting delivery never authorizes bypass or reallocation. Saved numbers stay exact; an admitted unavailable counter or unfitting whole range freezes an unknown index (quoted "?" in fresh YAML, #? in older layouts) rather than resetting or partially numbering a packet.
|
|
87
87
|
|
|
@@ -168,7 +168,7 @@ Run = Recipe + Trace + Control
|
|
|
168
168
|
5. Send `actors_control_apply` only for an action declared and consumed by that controlled Recipe.
|
|
169
169
|
6. Use terminal state, result, declared artifacts, and execution evidence to prove completion. When an outcome includes a retained primary-source, declaration-inventory or diagnostic-metadata reference, use that exact reference for further reading, not guessed captures or sibling files. Literal previews may be clipped; their field/range/counts describe what was shown. Diagnostic sources contain recorded command/error/failure-reason metadata only, not complete primary output; other recorded fields may be referenced without being shown. Artifact inventories list declarations only: they do not assert that target files exist or were produced, or grant body-read permission. Explicit unavailability has no guessed legacy body/path fallback.
|
|
170
170
|
|
|
171
|
-
Compact launch receipts include `run_files` as bare nested YAML with useful exact observed context-index/result/execution/metadata paths and any unavailable-location status, only after current-session/physical identity admission. Routine absent optional files and repeated format/size/mutable/generation metadata stay out of compact content; unavailable or over-budget rows remain explicit. Machine `file_navigation` details stay JSON-compatible; saved terminal messages retain their own original encodings. Selectively ordinary-read those starting locations when needed; layout/size hints are not body, privacy, terminal or native proof. No evidence bodies or session-wide catalog map are read to build this row. New terminal packets also freeze bounded location rows for captured completion members at fresh current-session admission. Fresh rooted completion headers group useful source/artifact and observed context-index/result/execution paths (metadata fallback) under literal roots with relative
|
|
171
|
+
Compact launch receipts include `run_files` as bare nested YAML with useful exact observed context-index/result/execution/metadata paths and any unavailable-location status, only after current-session/physical identity admission. Routine absent optional files and repeated format/size/mutable/generation metadata stay out of compact content; unavailable or over-budget rows remain explicit. Machine `file_navigation` details stay JSON-compatible; saved terminal messages retain their own original encodings. Selectively ordinary-read those starting locations when needed; layout/size hints are not body, privacy, terminal or native proof. No evidence bodies or session-wide catalog map are read to build this row. New terminal packets also freeze bounded location rows for captured completion members at fresh current-session admission. Fresh rooted completion headers group useful source/artifact and observed context-index/result/execution paths (metadata fallback) under literal roots with files as a sequence of relative-entry groups, optional name/status and no role or diagnostic field inventory. Read first appears in one source status only when selected text is incomplete and that file retains more; complete answers or upstream uncertainty alone do not trigger it. Exact primary prefixes add continue_from_line and [Read from line N] at the cut; LF/CRLF file lines are one-based, a partial line is repeated and wrapping/lone CR do not add lines. A long single line can still exceed a reader budget. Diagnostic JSON keeps character counts, not invented file lines. Group-wide status/notes remain optional sibling files_status/files_notes; no cwd guess, source refresh or automatic read follows. Unknown bases stay explicit. Source status preserves admission privacy, Actor-response/exported-text and diagnostic-metadata-only distinctions; declarations remain unverified. Unavailable locations and missing terminal-result locations stay visible. Full generation/hash/location facts stay in machine detail/saved snapshots, not repeated per file. Runtime navigation/omission/inventory facts remain above the Actor Markdown, not in a footer; retained packets keep their original projection. Each shown result keeps its whole Run-file row or explicit per-record omission; wholly omitted results stay covered by result omission/inventory. This describes Run-row coverage, not a complete file/tree inventory. Older captured formats retain their original shown/omitted/total counters; unavailability remains explicit. Ordinary-read selected paths only when needed. Packet reload/render never refreshes sources, and old absent/request-only formats keep their text. Source/npm SDK verifies an explicitly requested ordinary read from a delivered terminal result path; this is research, never routine completion polling or new primary/privacy/clock/native authority. Use the request only for file investigation, not routine completion/status polling. Copied locations/hints remain data, never transferred scope; older batches keep their original text.
|
|
172
172
|
|
|
173
173
|
For selective investigation of already cataloged files, use `actors_inspect target=runtime view=runs verbose=true`, then ordinary file tools on its current-session root-first navigation. Ordinary maps keep latest-registration order between roots and prioritize known failed subtrees within each root. For a failed investigation add status=failed: inventory is filtered, while the full owned map prioritizes observed failed subtrees across roots, always ancestors first. Priority uses only exact-generation matched inventory observations, not complete terminal truth. Launches and compatible singleton attachments populate the catalog; reads do not backfill missing locations. A `catalog: unavailable` launch warning is not workload failure: do not spawn again merely to repair navigation. The starting map's format hints do not certify syntax, encoding or complete output. See [Runs](./references/runs.md) for selective recorded-capture research and resume boundaries.
|
|
174
174
|
|
|
@@ -24,7 +24,7 @@ actors_inspect target=run:<id> view=trace
|
|
|
24
24
|
actors_inspect target=run:<id> view=control
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Fresh root completions use YAML frontmatter (run, state, admitted kind), followed by raw left-edge Markdown. Prepend the packet-local index only when two or more results are shown. Exactly one shown result omits its index even with omitted results; preserve omission/inventory metadata, internal member/generation/correlation and every saved message. This rule does not apply to numbered streams. New source captures put all runtime metadata above that body, with no service/file footer. files
|
|
27
|
+
Fresh root completions use YAML frontmatter (run, state, admitted kind), followed by raw left-edge Markdown. Prepend the packet-local index only when two or more results are shown. Exactly one shown result omits its index even with omitted results; preserve omission/inventory metadata, internal member/generation/correlation and every saved message. This rule does not apply to numbered streams. New source captures put all runtime metadata above that body, with no service/file footer. files is a sequence of literal-root/relative-entry groups without role or diagnostic field inventories. Optional name/status preserve useful meaning; files_status/files_notes retain real group-wide facts. Read first prefixes a source only when its selected text is incomplete and the file retains more, never for a complete answer, unknown upstream loss alone or unrelated metadata. Exact primary prefixes add continue_from_line with [Read from line N] at the cut: one-based LF file lines including CRLF, rereading a partial line. Wrapping/lone CR do not add lines; one long line can still exceed a reader's budget. Diagnostic JSON and unmapped text keep character counts, not invented file-line mapping. Concise facts replace repeated purposes/format/size/mutable/generation dumps; full bindings remain in saved snapshots. Status keeps admission privacy, Actor-response/exported-text, metadata-only diagnostics and unverified declarations distinct. Unavailable locations and missing terminal-result locations stay explicit; Actor Markdown and path/name bytes are unchanged. External paths use separate roots; unknown bases remain explicit rather than guessed from cwd or Run id. Exact line-continuation or character-cut markers alone may follow the cut body; unknown-loss warnings and packet omission/inventory facts stay in the header. Retained captures preserve their old bytes and presentation. No external #N heading, result:/preview: wrapper, list nesting, whole-body fence, Batch caption, members wrapper or routine outer counter is added. Primary/final Actor response uses kind:primary; explicit error/failure diagnostic text uses kind:diagnostic, never a launch command. Untracked fallback has no kind and keeps unknown original completeness/privacy explicit outside YAML. Mapped primary cuts use [Read from line N]; other known cuts use [N characters omitted]. Neither adds an ellipsis or clipping counters/flags in metadata. Unknown upstream loss remains separately unknown and does not assert a known positive omission. Exact useful source/location paths remain in complete model content, while generation/hash/parent bindings stay in the frozen snapshot, with whole references or explicit omission, captured inventory recovery and non-done omitted states. The compact TUI independently renders literal headers/markers and native Markdown bodies from validated content-bound blocks; only whole header reference/location rows and framing are hidden. Expansion and invalid/missing hints reveal original text. Hashes/layout/markers establish consistency/correlation only, never authentication, read/action permission, acceptance or native truth. Authored YAML/next/tool/batch/omission lookalikes stay body content. Fresh packets share48KiB UTF-8 including service data, equally between up to64candidate rows, with256captured members and no redistribution of unused shares or fixed16KiB/2KiB text cap. Full admitted text fitting its share without upstream uncertainty has no cut marker; otherwise use the scalar/CRLF-safe prefix and exact retained-source loss. Allocation/text is frozen at admission; rendering/recovery does not reread sources or reallocate. Unsupported Pi event/control output is withheld. Source basis stays in reference metadata; retained structured coverage facts are not exposed as YAML clipping fields. Pending/queued/presented older formats—including #N records and the first frontmatter draft—keep exact bytes, hints and budgets. Encoding names are storage replay data, not public product choices, source permissions or work authority. No standing full-map instruction or automatic research/read follows; use selective same-session investigation when needed.
|
|
28
28
|
|
|
29
29
|
Current completion index values restart within each packet; they are not session-wide historical references. Completion streams are adopted but not enabled, and no start-stream command is available yet. Do not infer an active stream or reset a counter from missing metadata or a pending target, and never relabel older saved packets. The kernel-only allocator now commits fixed scope/order/indices, the counter and first-packet target activation together, and an internal fresh-session bridge can use it after current manager/generation admission. The default runtime does not opt in; no public action exposes it. Event reason or a matching ID alone is insufficient. Old callbacks/wrappers cannot act after replacement; fresh wrappers must belong to the current original manager. Startup/reload/resume and ambiguous imports remain closed to stream capture/ACK, without changing saved packets or inferring a counter from history. Its whole-range exhaustion or admitted counter unavailability yields a frozen unknown index (quoted "?" in fresh YAML; #? in older saved layouts), never partial indices or an automatic fresh stream. Old packets retain their original scope while a pending switch waits; uncertainty does not permit reallocation. Stream state outlives packet cleanup/receipt rotation. Malformed/missing state remains refused, not a zero counter or proof of non-connection.
|
|
30
30
|
|