From bfd63ba69f7e97aeca9bcfa3732bcb80ba56f37a Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Mon, 2 Nov 2026 02:07:23 +0530 Subject: [PATCH] docs(self-repair): retain command completion metadata before stdout Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- .../references/repair-patterns.md | 1 + .../references/targeted-diagnostics.md | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/skills/loopx-self-repair/references/repair-patterns.md b/skills/loopx-self-repair/references/repair-patterns.md index 49a3405df2..4acaa58d50 100644 --- a/skills/loopx-self-repair/references/repair-patterns.md +++ b/skills/loopx-self-repair/references/repair-patterns.md @@ -5,6 +5,7 @@ teaches a reusable control-plane lesson. | Pattern | Symptoms | Evidence To Read | Likely Root | Durable Repair | | --- | --- | --- | --- | --- | +| `async_command_completion_metadata_lost` | A code cell appears complete with empty stdout, then the agent searches saved files or reissues a stateful command without checking whether its child is still running. | The original tool result's running handle, terminal exit code and stderr; caller projection code; the same command's completion; original operation/capture identity. Keep empty success, empty failure and a pending command distinct. | The caller forwarded only stdout and dropped the command tool's completion metadata; a completed wrapper was mistaken for a completed child. Empty output alone cannot establish this cause in a historical trace whose inner result is unavailable. | Preserve the tool result envelope, retain a running handle and collect the same execution's terminal result. If the handle was lost, follow original-receipt or digest-bound capture recovery before any retry. Keep admission/lease/settlement fences and original identities; qualify with pending, silent-success and silent-failure controls. See targeted diagnostics; no timeout, quota, packet or authority change is implied. | | `same_packet_json_type_alias` | Quota sharing replaces a distinct Vision or authoring observation with a reference because Boolean/number or signed-zero values compare equal in the host language. | Original captured values, projected body/ref, exact scalar types and zero signs, equal-content/key-order controls, actual CLI recovery and unchanged receipt/spend counts. | Language-level value equality was used as lossless JSON identity, while another sharing path already retained original serialized types. | Reuse one local serialization identity at the existing compatibility owner; share only complete equal JSON bodies and retain unique values/instructions. Preserve exact references, source input and existing reader/settlement ownership. Cover ordinary/native File/SQLite reads and digest refusal, and count transport rather than adding a late full-payload RPC. Keep installed/model adoption and whole-C1 benefit separate. | | `original_conversation_cli_goal_instance_drift` | `manager-inbox original-conversation` accepts an explicit `--goal-instance-id` but returns success for a stale instance, or follows the currently registered generation instead. | The physical CLI argv, selected registry profile, explicit versus omitted instance, current Goal reference, and real HTTP/source/queue/return readback in disposable File/SQLite state. | The CLI branch dropped the selector before the existing collaboration owner; current-instance inference concealed the missing caller reference. An unsupported source profile is a separate boundary, not proof that forwarding alone enables it. | Validate and forward the explicit Goal reference through the existing owner. Preserve omitted-selector compatibility and keep stale-instance, source/grant and audience checks authoritative. Cover real CLI discovery, request and control, unchanged inferred discovery, stale-instance rejection without queued work, and original recipient/result return; do not promote profiles or infer grants to make a live request pass. | | `conversation_inventory_refusal_reason_loss` | A delegation inventory stays partial because an original request is rejected as `initial_delivery_unproved`, but the App shows only a generic unreadable count. | The current authorized source, committed request/route, trusted originating Turn receipt and typed lifecycle refusal; distinguish incomplete scans and unloaded pages. | The IO adapter collapses a typed receipt conflict into a generic exception and omits the row without retaining a diagnosable identity. | Preserve the existing TS refusal and expose bounded diagnostic identities only after source/route agreement is proved and current audience/Goal checks pass. Keep the count partial, brief/work withheld and controls/return rejected; disclose the cause through existing accessible help. Other failures remain unknown. Cover File/SQLite real HTTP, source/scope changes, bounded diagnostics and fresh read after source recovery. Never rewrite live receipts, infer cancellation from another target, remove proof checks or claim the historical conflict is repaired. | diff --git a/skills/loopx-self-repair/references/targeted-diagnostics.md b/skills/loopx-self-repair/references/targeted-diagnostics.md index 5cefdc58d0..f580f922a7 100644 --- a/skills/loopx-self-repair/references/targeted-diagnostics.md +++ b/skills/loopx-self-repair/references/targeted-diagnostics.md @@ -74,6 +74,33 @@ diagnostic is not current authority. ## Measure the right latency +### Preserve the command tool's completion state + +Read the command tool's result envelope before projecting its stdout. A code cell +can finish while its child command is still running. For a tool exposing +`session_id` and `exit_code`, forwarding only `result.output` loses the distinction: + +| Observed tool result | Next action | +| --- | --- | +| Running session handle, no terminal exit code; stdout may be empty or partial | Retain the handle and collect that same command's completion through the tool's continuation API. Do not submit the command again. | +| Terminal zero exit code, empty stdout | The command exited silently. If a structured result was required, use the original operation's receipt/capture recovery; empty text does not establish its domain outcome. | +| Terminal nonzero exit code, empty stdout | Preserve the failure and available stderr/typed recovery. Empty text does not turn failure into a running command or grant a retry. | + +Respect the existing timeout, cancellation and stop conditions during collection. +For example, `text(result)` preserves these fields where `text(result.output)` +would discard them. With large output, retain the complete result in the tool's +value store or an authorized private capture and expose its completion metadata +and pinned reader; obey the original context-read contract for required content. +The child output budget does not raise the enclosing code cell's output budget. + +If the handle was already lost and the operation may have committed, recover its +original receipt or digest-bound capture before considering another execution. +Preserve Goal, Agent, Turn and operation identity. A directory listing, a wrapper's +"completed" label or a later file's existence does not prove the child outcome, +full context delivery or current authority. + +### Separate tool waits from command duration + Distinguish command start-to-exit duration from the tool's initial yield or poll wait. Separately record response bytes, output truncation, read count and time between useful operations. A fast `cat` can still consume substantial