Repository navigation
Description
Parent: #4045
Purpose
Gateway shutdown ignores Promise.allSettled rejections, clears owners, and resolves. Daemon then reports platform owners closed and can release registration. At audit HEAD a throwing owner was invoked once while two gateway shutdown calls both resolved.
Owner and scope
src/platform-runtime-gateway.ts, packages/daemon/src/server/http/daemon-runtime.ts, server-shutdown.ts, adjacent focused tests, and owning SDK shutdown documentation/type consumers. Do not change DeviceRuntimeGateway.shutdown(): Promise<void> or the persisted daemon shutdown wire report.
Required behavior
Settle every loaded owner, then clear owner/load caches and reject with an AggregateError identifying failed owners if any rejected. Shutdown is terminal and disposes each owner at most once; a repeated gateway close does not retry disposal. In daemon close, record owner rejection, retain registration as unfinished, emit daemon_shutdown_platform_owner_failed, and continue plugin reporting and final runner cleanup. Distinguish failed from deadline-pending in the SDK-visible ShutdownReport and operator description. Do not relabel failure as a budget timeout.
API or evidence example
gateway.shutdown(): Promise<void> retains its signature and rejects AggregateError after settling owners. SDK close report may return { platformOwners: 'failed', ... }; persisted DaemonShutdownReport wire shape is unchanged.
Observable completion
- A regression fails without the fix and passes with it through composed gateway and daemon reporting/registration retention.
- Successful, rejected, deadline-pending and repeated-close cases have distinct truthful results; later cleanup still runs after rejection.
- Gateway shutdown signature and persisted daemon wire report remain unchanged; every owner is disposed at most once.
- SDK type widening platformOwners: 'closed' | 'pending' | 'failed' and matching describeUnfinishedShutdownWork behavior are explicitly documented and validated.
Dependencies and sequencing
Blocked by: none.
Validation
Focused gateway/shutdown tests; regression base/head comparison in disposable experiment; assess device-facing status from final diff. pnpm format, commit, then serialized exact-head affected gate. Independent review before publication.
Base audit SHA: 144bd59890277fd4717995588ad817597c9d6552. Re-read the issue and all Decision: comments before work. Read applicable AGENTS.md routes. Keep one owner boundary per PR. Independent review and serialized exact-head validation are coordinated by the umbrella orchestrator.
Activity
thymikee commentedon Oct 29, 2026
Implementation committed at ca6e0af (base 144bd59). The isolated worktree is clean. Frozen install/build, OXC format, typecheck and 35 focused gateway/daemon shutdown tests passed. Independent review is next. Unchanged-base regression proof, serialized exact-head affected gate and device-facing evidence assessment remain outstanding. No PR is published; this is not merge-ready evidence.
thymikee commentedon Oct 29, 2026
Decision: shutdown review corrections: Accept the hanging-load barrier and missing-cause findings. Close each resolved owner independently so an unresolved load cannot delay already-loaded owners, and include normalized per-owner cause/details in diagnostics. Scope also includes the existing owner-scoped claim-recovery consumer and its collocated tests. Apply ADR 0010 / ADR 0019 cleanup precedence: preserve a primary thrown error or retained-claim reason and record disposal failure as structured secondary evidence. If reconciliation succeeds but disposal alone fails, surface that failure and keep the claim file; do not swallow it or claim recovery success. Gateway closure remains terminal and at most once. Root composition tests may exercise gateway plus daemon; no production boundary exception is added.
thymikee commentedon Oct 29, 2026
Draft PR #4063 is published at c7931c8. Corrected focused verification: 58 tests in 5 files, typecheck and full OXC format passed. Regression proof copied the same two test files into three disposable checkouts and selected the same five cases: original base 144bd59 and first implementation ca6e0af each had 4 failed / 1 passed; corrected head had 5 passed. Failures covered false closed reporting, late-owner closure, and masking primary reconciliation outcomes. All comparison checkouts were removed and the reviewed source remained clean. Independent recheck had no required findings at a3c7159; the subsequent host-diagnostic sink type correction and user-doc sentence are covered by the corrected tests/typecheck. Exact-head affected validation and live native-owner teardown evidence remain pending; draft is not merge-ready.
thymikee commentedon Oct 29, 2026
Current state: CI at
c7931c8973found two defects in this change: OXC unsafe-finally and R11 relative imports from the root test into daemon internals. Both are corrected in local commit971d26b707. Cleanup uses an explicit outcome outside finally; the composed test uses the public daemon entrypoint and existing root composition. Lint, typecheck, 53 focused tests, all 442 layering tests and the real-tree layering scan passed. Exact-head affected validation must run before pushing this round.The same CI run also failed
remote-upload-lease-beat.test.ts:379, expectedcanceled, gotdrained. Cause remains unproven; this is not claimed as infrastructure or as the recording blocker #4060. No CI rerun requested. The draft remains incomplete, including live native-owner evidence.thymikee commentedon Oct 29, 2026
Current state: corrected head
28ae2b7cf080a308fc1f7161341a2fd838316aabhas a failed exact-commit affected receipt (exactCommit: true, run-RMbKy7). Format, lint, typecheck, layering, Fallow and build passed. Related tests: 364/365 files passed, 2534 passed /1 failed; onlyios-record-trace.test.ts:66simulator recording timed out at5000ms. The stale quiesce rejection assertion is corrected and the own focused lifecycle suites pass46 tests.Unchanged base
144bd59890277fd4717995588ad817597c9d6552, fresh frozen install/build and the same default-worker command (pnpm exec vitest related --run --passWithNoTestsfollowed by exactly the nine changed paths fromgit diff --name-only 144bd59890 28ae2b7cf0) reproduced the same simulator recording timeout. Base had2525 passed /2failed over364 files; the second failure was the existing IME bounded-batch timeout/slow budget. That extra failure is not attributed to this change. Full comparison records are retained locally under validation-round; disposable checkouts were removed and all reviewed SHAs/statuses verified unchanged.Disposition: base-blocked by recording #4060, not passed. Original CI remote-upload canceled/drained failure remains separate with unproven cause. Native-owner live evidence and CI at the corrected push remain outstanding; publish as draft only. No retries, deadline changes or reduced selection.
thymikee commentedon Oct 30, 2026
Decision: typed owner-shutdown failures: Accept the maintainer decision, superseding this PR's earlier AggregateError retain disposition. The gateway will reject with one COMMAND_FAILED AppError, reason platform-owner-shutdown-failed, containing typed per-owner normalized failures and a cleanup/claim-retention hint. The daemon consumes the normalizer once; no AggregateError-shape branch remains. Original exceptions remain JS causes (one direct cause, or an aggregate cause for several); consumers do not inspect that internal cause representation. Claim-recovery precedence, claim ownership fences, terminal shutdown and retry/release authority remain unchanged. One- and two-owner cases must preserve structured normalization and claim bytes, including secondary failure evidence under an earlier primary error or retained reason.
thymikee commentedon Oct 30, 2026
The requested review correction is complete at
7222a41f033921c25e2b5b7d992c34e755362fc9.Final exact validation:
All 41 runnable checks passed. Receipt
run-lcOqqw:exactCommit: true,checkoutChanged: false. Unit: 16,479 passed / one skipped; related: 1,247 passed; provider integration: 222 passed. Stages overlap and are not summed. The 25 CI-owned/parked checks remain skipped, not passed.The typed contract, original causes, claim retention/precedence, single daemon normalization and lazy loading are all retained. Independent source review/recheck found no findings. Final-head disposable proof is baseline/restored 50 passing tests, with nine intended failures/41 passes when the old outer shape is reintroduced; cleanup/source preservation verified.
This replaces the pending validation status in my previous reply. Earlier missing-export and eager-loading receipts remain failed; the new source fixes those defects without suppression or budget changes. The PR remains draft for source-pinned native cleanup evidence and CI obligations. No native device run or historical #4060 root-cause claim is added.