[GH-ISSUE #4693] [Bug] Kuna caller failure remapping retains resolved cleanup ownership #2450

Closed
opened 2026-10-17 21:04:50 +00:00 by bsakaguchi · 4 comments
Owner

Originally created by @morluto on GitHub (Oct 17, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4693

Before submitting

  • Searched open/closed issues for Kuna cleanup remapping and KunaQueryErrors; #4689 addresses operation identity, not this resolved-owner state.
  • The fixture contains no credentials or private data.

Area

Cleanup, cancellation, or lifecycle (native analysis/provider failure projection)

Observed behavior

A direct compiled Kuna caller-remapping probe retains cleanupIncomplete: true and the original resource after the producing error's cleanup marker resolves. The mapped error keeps the producer as its cause but does not follow its cleanup state. This is a controlled typed-error boundary reproduction, not a real file/process cleanup or public CLI/MCP reproduction.

Reproduction

After building, invoke:

import { ProviderCleanupError } from './dist/domain/providerCleanupError.js';
import { kunaQueryFailureForCaller } from './dist/kuna/KunaQueryErrors.js';
const source = new ProviderCleanupError('kuna', ['controlled-owner'], {reason:'controlled close refusal'}, {operation:'kuna:strings'});
const caller = kunaQueryFailureForCaller(source, 'search_strings');
source.resolveCleanup();
console.log(source.cleanupIncomplete, caller.cleanupIncomplete, caller.cleanupResources);

Observed direct-probe result: producer false, caller true, resources ["controlled-owner"]. An equivalent probe with list_procedures/search_procedures was executed first and produced the same retained-marker result. Neither probe opens files or launches Kuna.

Expected behavior

The caller-specific diagnostic should follow resolution of the exact producer's owned resources. AGENTS.md and docs/tool-design.md require cleanup ownership to remain live and retryable; per-caller context must not turn owner state into a stale independent claim.

Impact and scope

Confirmed at the remapping helper used by KunaStringQueries. Public occurrence, real-owner retry and downstream effects are NOT_ENOUGH_INFO: only controlled producer marker resolution was exercised. No severity or device/process impact is asserted.

REA version

Source main 5717ad24aa; compiled local runtime, unchanged KunaQueryErrors implementation.

Runtime and platform

Node24.18.0, Darwin arm64. No real Kuna engine used.

Target and artifact context

No target; controlled-owner is synthetic error metadata, not a filesystem path or authorization to delete anything.

Interface

Other: failure projection consumed by shared provider workflows; CLI/MCP delivery unverified.

Earliest failure stage

Cleanup, cancellation, or lifecycle

Relevant output or evidence

src/kuna/KunaQueryErrors.ts constructs a new ProviderCleanupError from resource names, diagnostics and cause, then returns without binding cleanup dependencies. src/kuna/KunaStringQueries.ts applies the helper to inventory failures. The source producer's marker was explicitly resolved by the probe; the mapped marker remained true. No runtime cleanup report is fabricated.

Typed outcome or recovery expected

A caller-remapped failure must retain unresolved ownership until the producer resolves it, then cease reporting that owner as incomplete. Preserve typed primary outcomes, request identity and diagnostics. Proposed stronger check: inject a real owned descriptor close failure, remap for multiple waiters, restore close permission, retry the exact owner and verify all projections update together.

Additional context

Related #4689's inventory attribution repair should preserve this invariant before applying caller remapping more broadly. #4631 now uses the shared authored-failure normalizer for installation failures and has exact-owner retry controls; that separate helper already binds producer dependencies. This report concerns the existing Kuna query helper.

Originally created by @morluto on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4693 ### Before submitting - [x] Searched open/closed issues for Kuna cleanup remapping and KunaQueryErrors; #4689 addresses operation identity, not this resolved-owner state. - [x] The fixture contains no credentials or private data. ### Area Cleanup, cancellation, or lifecycle (native analysis/provider failure projection) ### Observed behavior A direct compiled Kuna caller-remapping probe retains `cleanupIncomplete: true` and the original resource after the producing error's cleanup marker resolves. The mapped error keeps the producer as its cause but does not follow its cleanup state. This is a controlled typed-error boundary reproduction, not a real file/process cleanup or public CLI/MCP reproduction. ### Reproduction After building, invoke: ```js import { ProviderCleanupError } from './dist/domain/providerCleanupError.js'; import { kunaQueryFailureForCaller } from './dist/kuna/KunaQueryErrors.js'; const source = new ProviderCleanupError('kuna', ['controlled-owner'], {reason:'controlled close refusal'}, {operation:'kuna:strings'}); const caller = kunaQueryFailureForCaller(source, 'search_strings'); source.resolveCleanup(); console.log(source.cleanupIncomplete, caller.cleanupIncomplete, caller.cleanupResources); ``` Observed direct-probe result: producer false, caller true, resources `["controlled-owner"]`. An equivalent probe with list_procedures/search_procedures was executed first and produced the same retained-marker result. Neither probe opens files or launches Kuna. ### Expected behavior The caller-specific diagnostic should follow resolution of the exact producer's owned resources. `AGENTS.md` and `docs/tool-design.md` require cleanup ownership to remain live and retryable; per-caller context must not turn owner state into a stale independent claim. ### Impact and scope Confirmed at the remapping helper used by `KunaStringQueries`. Public occurrence, real-owner retry and downstream effects are NOT_ENOUGH_INFO: only controlled producer marker resolution was exercised. No severity or device/process impact is asserted. ### REA version Source main 5717ad24aa6471aa4207c370e26274866fb8aee5; compiled local runtime, unchanged KunaQueryErrors implementation. ### Runtime and platform Node24.18.0, Darwin arm64. No real Kuna engine used. ### Target and artifact context No target; `controlled-owner` is synthetic error metadata, not a filesystem path or authorization to delete anything. ### Interface Other: failure projection consumed by shared provider workflows; CLI/MCP delivery unverified. ### Earliest failure stage Cleanup, cancellation, or lifecycle ### Relevant output or evidence `src/kuna/KunaQueryErrors.ts` constructs a new ProviderCleanupError from resource names, diagnostics and cause, then returns without binding cleanup dependencies. `src/kuna/KunaStringQueries.ts` applies the helper to inventory failures. The source producer's marker was explicitly resolved by the probe; the mapped marker remained true. No runtime cleanup report is fabricated. ### Typed outcome or recovery expected A caller-remapped failure must retain unresolved ownership until the producer resolves it, then cease reporting that owner as incomplete. Preserve typed primary outcomes, request identity and diagnostics. Proposed stronger check: inject a real owned descriptor close failure, remap for multiple waiters, restore close permission, retry the exact owner and verify all projections update together. ### Additional context Related #4689's inventory attribution repair should preserve this invariant before applying caller remapping more broadly. #4631 now uses the shared authored-failure normalizer for installation failures and has exact-owner retry controls; that separate helper already binds producer dependencies. This report concerns the existing Kuna query helper.
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Fixed in 6eb55be4e, pushed to main (with the caller boundary follow-up in 54c71313a).

Root cause: Kuna reconstructed typed failures using an independent cleanup snapshot and incomplete outcome fields. It now uses the shared canonical attribution owner, preserves typed primary outcomes/captured output/partial facts, and binds projections to the exact producer cleanup dependency. Cleanup retry updates all projections; an already resolved failure does not resurrect cleanup. Cancellation reasons remain opaque and do not grant foreign cleanup authority.

Validation: ten new boundary controls failed 9/10 before the fix and passed after it. A focused six-file run passed 108 checks, including domain error projection, real descriptor cleanup fault/retry controls and Hopper regression controls. Final inventory controls passed 7/7; cached typecheck/lint, documentation checks and commit/push hooks passed. No real Kuna or Windows qualification.

Bounded completed CLI measurements cover both commits together using the same tiny ELF and fake Kuna malformed-inventory refusal: separate first processes and two alternating warm repeats. Baseline/candidate warm medians: elapsed 1.298/1.303 s, CPU including reaped children 1.317/1.314 s, sampled process-family RSS 529.3/529.0 MB, raw cl100k reply tokens 75/86. First-process elapsed 1.427/1.284 s, CPU 1.323/1.320 s, sampled family RSS 536.3/527.2 MB. No efficiency claim; added producer metadata intentionally changes the reply. True cold, whole-agent/MCP/catalog/retry costs, real engine, large outputs and actual cleanup-fault task costs remain unmeasured. No heavy profiling or stress was run.

Remaining Kuna installation-wait and post-success cancellation paths are separate audit candidates; this fix does not establish complete lifecycle coverage.

<!-- gh-comment-id:6230566638 --> @morluto commented on GitHub (Oct 17, 2026): Fixed in 6eb55be4e, pushed to main (with the caller boundary follow-up in 54c71313a). Root cause: Kuna reconstructed typed failures using an independent cleanup snapshot and incomplete outcome fields. It now uses the shared canonical attribution owner, preserves typed primary outcomes/captured output/partial facts, and binds projections to the exact producer cleanup dependency. Cleanup retry updates all projections; an already resolved failure does not resurrect cleanup. Cancellation reasons remain opaque and do not grant foreign cleanup authority. Validation: ten new boundary controls failed 9/10 before the fix and passed after it. A focused six-file run passed 108 checks, including domain error projection, real descriptor cleanup fault/retry controls and Hopper regression controls. Final inventory controls passed 7/7; cached typecheck/lint, documentation checks and commit/push hooks passed. No real Kuna or Windows qualification. Bounded completed CLI measurements cover both commits together using the same tiny ELF and fake Kuna malformed-inventory refusal: separate first processes and two alternating warm repeats. Baseline/candidate warm medians: elapsed 1.298/1.303 s, CPU including reaped children 1.317/1.314 s, sampled process-family RSS 529.3/529.0 MB, raw cl100k reply tokens 75/86. First-process elapsed 1.427/1.284 s, CPU 1.323/1.320 s, sampled family RSS 536.3/527.2 MB. No efficiency claim; added producer metadata intentionally changes the reply. True cold, whole-agent/MCP/catalog/retry costs, real engine, large outputs and actual cleanup-fault task costs remain unmeasured. No heavy profiling or stress was run. Remaining Kuna installation-wait and post-success cancellation paths are separate audit candidates; this fix does not establish complete lifecycle coverage.
Author
Owner

@skyzhao1223 commented on GitHub (Oct 18, 2026):

Verified on current main (7c458f04b, compiled runtime) that this no longer reproduces.

The probe from the report now prints:

{"producer":false,"caller":false,"resources":[],"sameCause":true}

The caller follows the producer's cleanup resolution instead of keeping a stale owner. 6eb55be4e (fix(kuna): preserve live cleanup in caller failures) added that cleanup-dependency binding in analysisClientFailureForOperation, and tests/boundary/providers/kuna/kunaQueryErrors.test.ts passes.

This fix is in the rea-agents-6.6.0 release (npm latest was still 6.5.0 when I checked). Verification only; no action requested.

<!-- gh-comment-id:6247505871 --> @skyzhao1223 commented on GitHub (Oct 18, 2026): Verified on current `main` (`7c458f04b`, compiled runtime) that this no longer reproduces. The probe from the report now prints: ```json {"producer":false,"caller":false,"resources":[],"sameCause":true} ``` The caller follows the producer's cleanup resolution instead of keeping a stale owner. `6eb55be4e` (`fix(kuna): preserve live cleanup in caller failures`) added that cleanup-dependency binding in `analysisClientFailureForOperation`, and `tests/boundary/providers/kuna/kunaQueryErrors.test.ts` passes. This fix is in the `rea-agents-6.6.0` release (npm `latest` was still 6.5.0 when I checked). Verification only; no action requested.
Author
Owner

@XinwangTao commented on GitHub (Oct 18, 2026):

Good minimal reproduction: the mapped caller error keeps cleanupIncomplete: true even after the producer's cleanup marker resolves, so any consumer holding the remapped error will keep reporting a stale live resource long after the owner is released. The fix direction in 6eb55be/34b6c73 — reusing the canonical typed failure so cleanup state propagates from the producer — is correct; deriving state from the producer instead of copying it at remap time avoids the drift entirely. Two suggestions: (1) add a regression test that resolves the producer cleanup between remap and consumption, asserting caller.cleanupResources mirrors the resolved state; (2) consider whether other remapping sites (e.g. list_procedures / search paths mentioned in #4689) copy cleanup state the same way, since they may share the same stale-owner pattern.

<!-- gh-comment-id:6248325772 --> @XinwangTao commented on GitHub (Oct 18, 2026): Good minimal reproduction: the mapped caller error keeps cleanupIncomplete: true even after the producer's cleanup marker resolves, so any consumer holding the remapped error will keep reporting a stale live resource long after the owner is released. The fix direction in 6eb55be/34b6c73 — reusing the canonical typed failure so cleanup state propagates from the producer — is correct; deriving state from the producer instead of copying it at remap time avoids the drift entirely. Two suggestions: (1) add a regression test that resolves the producer cleanup between remap and consumption, asserting caller.cleanupResources mirrors the resolved state; (2) consider whether other remapping sites (e.g. list_procedures / search paths mentioned in #4689) copy cleanup state the same way, since they may share the same stale-owner pattern.
Author
Owner

@morluto commented on GitHub (Oct 18, 2026):

Closing as fixed on main after reconciling this report with the landed owner/consumer changes.

  • 6eb55be4e: fix(kuna): preserve live cleanup in caller failures.

Evidence scope: this closure uses the landed source, regression coverage and validation already recorded in the linked commits/thread. No new local tests or native-provider reproduction were run during this backlog pass; previously documented platform and real-provider gaps still apply.

<!-- gh-comment-id:6255992157 --> @morluto commented on GitHub (Oct 18, 2026): <!-- rea-backlog-reconciliation-2026-10-19-4693 --> Closing as fixed on `main` after reconciling this report with the landed owner/consumer changes. - [6eb55be4e](https://github.com/morluto/rea/commit/6eb55be4e8e685d4eacfe9ccf5d3e0308a9cd617): fix(kuna): preserve live cleanup in caller failures. Evidence scope: this closure uses the landed source, regression coverage and validation already recorded in the linked commits/thread. No new local tests or native-provider reproduction were run during this backlog pass; previously documented platform and real-provider gaps still apply.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2450
No description provided.