From 14cd7b74679417dbd995d40874614ebf6a764495 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Fri, 23 Oct 2026 22:57:28 -0400 Subject: [PATCH 1/6] docs: retain client-reliability-9 controlled browser results and Firefox blocker --- ...0-24_02-51-00_client-reliability-9-resume.md | 8 ++++++++ ...-00_client-reliability-9-chromium-blocked.md | 8 ++++++++ ...24_02-54-00_client-reliability-9-chromium.md | 9 +++++++++ ...0_client-reliability-9-browser-checkpoint.md | 17 +++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 test_logs/TEST_LOG_2026-10-24_02-51-00_client-reliability-9-resume.md create mode 100644 test_logs/TEST_LOG_2026-10-24_02-53-00_client-reliability-9-chromium-blocked.md create mode 100644 test_logs/TEST_LOG_2026-10-24_02-54-00_client-reliability-9-chromium.md create mode 100644 test_logs/TEST_LOG_2026-10-24_02-55-00_client-reliability-9-browser-checkpoint.md diff --git a/test_logs/TEST_LOG_2026-10-24_02-51-00_client-reliability-9-resume.md b/test_logs/TEST_LOG_2026-10-24_02-51-00_client-reliability-9-resume.md new file mode 100644 index 00000000..344b450c --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_02-51-00_client-reliability-9-resume.md @@ -0,0 +1,8 @@ +# Client9 source-only resume + +- HEAD `7b667e79`, clean before this evidence note; existing item9 reclaimed, no new item. Latest rules/PROGRAM/area TODO/mailbox and saved notes read. +- `node --check /tmp/client9-hls-native-smoke-prepared.mjs`: exit 0. No browser invocation. SHA256 `28cf3511c0ac154e59ac519c0f68dfe4099cb37e016bae31c3564ed58db9375e`. +- dist version `c95abe22`; script-pinned controller/observer/HLS-helper/cache hashes verified exactly. Source controller/helper equal dist. `git merge-base --is-ancestor 83fd2495 HEAD` and same against unstable both exit 0. Existing 437-file landing/build evidence read, not repeated. +- Original Chromium same-source replacement timeout failure retained in `/tmp/client9-hls-native-smoke-chromium-output.md`; no later run output found. Corrected method/path/occurrence-aware source remains unexecuted. +- Resource snapshots 02:50:44Z CPU82.1C/load2.95 and 02:51:02Z CPU85.1C/load3.60 fail required <75C start threshold. Swap82%, available memory65%. No expensive job launched. Dispatch received exact source readiness and blocker; fresh exclusive browser grant pending. +- Remaining: two fresh cooling snapshots <75C about30s apart/load<8, explicit dispatch grant, bounded Chromium then separately granted Firefox; preserve original failure. No real decoding, playback, segments, public IO, torrent, RangeGET or full Stage3 qualification. diff --git a/test_logs/TEST_LOG_2026-10-24_02-53-00_client-reliability-9-chromium-blocked.md b/test_logs/TEST_LOG_2026-10-24_02-53-00_client-reliability-9-chromium-blocked.md new file mode 100644 index 00000000..5d5d62aa --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_02-53-00_client-reliability-9-chromium-blocked.md @@ -0,0 +1,8 @@ +# Client9 Chromium invocation blocked before launch + +- Dispatch fresh exclusive grant at 02:52:46Z; two dispatch cooling snapshots reported 74.8C then69.1C/42s. Local fresh health02:52:57Z CPU68.1C/package67C/load2.50/RAM63.6%, swap82% advisory. START announced. +- Command: `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-hls-native-smoke-prepared.mjs chromium > /tmp/client9-hls-chromium-20261024T0253.log 2>&1`. +- Exact reviewed fixture SHA256 `28cf3511c0ac154e59ac519c0f68dfe4099cb37e016bae31c3564ed58db9375e`, dist `c95abe22`, HEAD `7b667e79`. +- Natural exit1 in0.27s: `Error: listen EPERM: operation not permitted 127.0.0.1`, before browser launch. This is a sandbox loopback restriction; no browser assertion or method timeline reached. +- No retry, escalation, Firefox, full suite, build or product change. Slot immediately RELEASED to dispatch; `.task` records blocker. Earlier Chromium replacement timeout evidence preserved unchanged. +- HLS browser qualification remains open; no real decoding/playback/segments/public IO/torrent/RangeGET/Stage3 qualification. diff --git a/test_logs/TEST_LOG_2026-10-24_02-54-00_client-reliability-9-chromium.md b/test_logs/TEST_LOG_2026-10-24_02-54-00_client-reliability-9-chromium.md new file mode 100644 index 00000000..aa6915f7 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_02-54-00_client-reliability-9-chromium.md @@ -0,0 +1,9 @@ +# Client9 controlled native Chromium HLS qualification + +- HEAD `7b667e79`; dist `c95abe22`; exact fixture SHA256 `28cf3511c0ac154e59ac519c0f68dfe4099cb37e016bae31c3564ed58db9375e`. Pinned controller/observer/helper/cache hashes matched. +- Dispatch02:53:39Z granted one normal host approval invocation after sandbox loopback EPERM. Fresh local health02:53:50Z CPU58.1C/load1.24; swap82% advisory. START announced; normal approval mechanism accepted host invocation. +- Command: `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-hls-native-smoke-prepared.mjs chromium > /tmp/client9-hls-chromium-host-20261024T0254.log 2>&1`. Natural exit0 in0.57s; finally browser/server cleanup completed; slot immediately released. +- Three cases passed: fetch cancellation followed by exact same-source sequential rejoin; body-read cancellation; shared live owner. Both cancellations settle null and abort GET without aborting completed HEAD; cancelled fetch writes0/stale badge checking, body cancellation writes unchanged1. Replacement healthy/badge healthy/write1. Shared owner1HEAD/1GET/no abort, remaining badge healthy/totalwrites2. +- Method/path/occurrence timeline:0HEAD cancel,1GET cancel,2HEAD same-source replacement,3GET replacement,4HEAD body,5GET body,6HEAD shared,7GET shared. All8 responses closed. Four nonlocal requests denied; page errors0. Full exact JSON retained in unique host output. +- Original13:16UTC Chromium replacement timeout failure and sandbox EPERM output preserved unchanged; corrected method-aware fixture now passes once. No product/assertion edits, Firefox/repeated host invocation/full/build/submission. +- Evidence uses native observer/fetch/AbortController/Response.text against controlled loopback responses. No same-turn browser identity, decoder, segments, actual playback, live network/peers, torrent, RangeGET, CPU improvement or wholeStage3 claim. Firefox awaits separate grant. diff --git a/test_logs/TEST_LOG_2026-10-24_02-55-00_client-reliability-9-browser-checkpoint.md b/test_logs/TEST_LOG_2026-10-24_02-55-00_client-reliability-9-browser-checkpoint.md new file mode 100644 index 00000000..e6713ebf --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_02-55-00_client-reliability-9-browser-checkpoint.md @@ -0,0 +1,17 @@ +# Client9 controlled HLS browser checkpoint + +- HEAD `7b667e79`; existing landed product `83fd2495`; dist `c95abe22`. No product/test/assertion edits, rebuild, full gate or new submission. Exact fixture SHA256 `28cf3511c0ac154e59ac519c0f68dfe4099cb37e016bae31c3564ed58db9375e` retained unchanged for both browsers. +- Original Chromium13:16UTC replacement timeout remains preserved in `/tmp/client9-hls-native-smoke-chromium-output.md`. Sandbox loopback EPERM attempt remains `/tmp/client9-hls-chromium-20261024T0253.log`; it reached no browser. Neither failure erased by later results. +- Host Chromium: separate normal host approval under dispatch02:53:39Z grant; natural exit0/0.57s, three cases passed. Fetch cancellation+sequential exact-source replacement, body-read cancellation, shared live owner. Final JSON8requests=4HEAD+4GET/allresponsesclosed/pageErrors0/publicdenied4. Cancelled GETs abort/null/no obsolete cache; completed HEADs not aborted; replacement/shared owner healthy. Unique output `/tmp/client9-hls-chromium-host-20261024T0254.log`; detail in TEST_LOG_2026-10-24_02-54-00_client-reliability-9-chromium.md. +- Host Firefox: separate dispatch02:54:44Z grant; fresh02:54:56Z CPU64.1C/package63C/load0.89. START announced. Command `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-hls-native-smoke-prepared.mjs firefox > /tmp/client9-hls-firefox-host-20261024T0255.log 2>&1` via normal host approval. Natural exit1 after approximately5s; finally cleanup returned and slot immediately RELEASED. +- Firefox error: `page.evaluate: Timed out waiting for native body-read entry /hls/body/pending.m3u8 after 5000ms`, fixture line294. Source execution reaches this after first-case fetch cancellation/transport close/exact-source replacement assertions pass. Body-read cancellation and shared-owner cases did not complete. No final JSON/method timeline emitted; do not infer GET-arrival counts or transport state from absent output. +- Firefox result is failed/incomplete browser qualification. Cause remains unclassified: native response-body entry prerequisite was not observed within existing bound. No timeout extension, sleep, retry, assertion relaxation, fixture change or speculative product fix. Dispatch notified outcome/release. +- Browser scope: actual native IntersectionObserver/fetch/AbortController/Response.text against controlled loopback endpoints and pinned built modules; nonlocal requests denied. No real decoding, segments, playback, public-network/peers, same-turn browser identity, torrent, RangeGET, CPU improvement or wholeStage3 qualification. Chromium pass does not establish Firefox pass. +- Next gate: dispatch scope review for source-only diagnosis of Firefox prerequisite; no further browser invocation or submission authorized by these consumed grants. Existing item9 remains open. + +## Source-only prerequisite inspection + +- Fixture body endpoint writes HTTP200 headers and calls `res.flushHeaders()` but writes no body bytes before disposal (lines72-78). Its comment that native GET resolves is an assumption, not measured Firefox evidence. +- Product helper awaits native fetch before invoking `response.text()` (`js/services/hlsPlayback.js:419`, `:427`). The fixture records only fetch invocation/signal and Response.text entry, not fetch resolution/rejection or response status. +- Body-read watchdog starts before observer registration (fixture294-295), so its5000ms budget includes observer activation, HEAD and GET delivery. Failure output provides no final per-stage timeline. Header-only delivery/buffering, pre-body request outcome, and prerequisite ordering remain hypotheses; current evidence cannot distinguish them. +- First-case preceding assertions are source-order evidence only, not a separately emitted Firefox case report. No source edits or rerun performed. A future separately reviewed diagnostic would need stage-specific timestamps/status and method/path/occurrence output preserved on failure before changing fixture behavior. From e9af76dfd23c6ebdde355d376af05261bdb89f00 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Mon, 26 Oct 2026 09:44:04 -0400 Subject: [PATCH 2/6] docs: reconcile client-reliability-9 HLS controls and remaining lifecycle scope --- ...10-24_19-46-17_client-reliability-9-resume.md | 1 + ..._13-45-00_client-reliability-9-source-only.md | 4 ++++ ..._13-45-00_client-reliability-9-source-only.md | 5 +++++ ...10-24_19-46-17_client-reliability-9-resume.md | 7 +++++++ ...55-20_client-reliability-9-diagnostic-hold.md | 7 +++++++ ...00_client-reliability-9-firefox-diagnostic.md | 10 ++++++++++ ...07-00_client-reliability-9-prefix-proposal.md | 9 +++++++++ ...3-27-00_client-reliability-9-prefix-result.md | 10 ++++++++++ ...6_13-45-00_client-reliability-9-reconciled.md | 16 ++++++++++++++++ ...10-24_19-46-17_client-reliability-9-resume.md | 5 +++++ ..._13-45-00_client-reliability-9-source-only.md | 6 ++++++ 11 files changed, 80 insertions(+) create mode 100644 context/CONTEXT_2026-10-24_19-46-17_client-reliability-9-resume.md create mode 100644 context/CONTEXT_2026-10-26_13-45-00_client-reliability-9-source-only.md create mode 100644 decisions/DECISIONS_2026-10-26_13-45-00_client-reliability-9-source-only.md create mode 100644 test_logs/TEST_LOG_2026-10-24_19-46-17_client-reliability-9-resume.md create mode 100644 test_logs/TEST_LOG_2026-10-24_19-55-20_client-reliability-9-diagnostic-hold.md create mode 100644 test_logs/TEST_LOG_2026-10-24_22-05-00_client-reliability-9-firefox-diagnostic.md create mode 100644 test_logs/TEST_LOG_2026-10-24_22-07-00_client-reliability-9-prefix-proposal.md create mode 100644 test_logs/TEST_LOG_2026-10-25_03-27-00_client-reliability-9-prefix-result.md create mode 100644 test_logs/TEST_LOG_2026-10-26_13-45-00_client-reliability-9-reconciled.md create mode 100644 todo/TODO_2026-10-24_19-46-17_client-reliability-9-resume.md create mode 100644 todo/TODO_2026-10-26_13-45-00_client-reliability-9-source-only.md diff --git a/context/CONTEXT_2026-10-24_19-46-17_client-reliability-9-resume.md b/context/CONTEXT_2026-10-24_19-46-17_client-reliability-9-resume.md new file mode 100644 index 00000000..3c498ed7 --- /dev/null +++ b/context/CONTEXT_2026-10-24_19-46-17_client-reliability-9-resume.md @@ -0,0 +1 @@ +Client9 resumed at5f8e58be, existing item reclaimed. Runtime identical unstable and prior146076dd handoff;4 browser evidence docs retained. Current narrow goal: diagnose original Firefox HLS body-entry prerequisite using preserved unexecuted d0100521 instrumented scratch, only after fresh dispatch slot+cooling clearance. No product/test edits or broader cancellation work. Preserve all failures and strict5000ms bound; no repeat full/build needed for unchanged runtime. See matching test log; dispatch blocker sent. diff --git a/context/CONTEXT_2026-10-26_13-45-00_client-reliability-9-source-only.md b/context/CONTEXT_2026-10-26_13-45-00_client-reliability-9-source-only.md new file mode 100644 index 00000000..5b2f702d --- /dev/null +++ b/context/CONTEXT_2026-10-26_13-45-00_client-reliability-9-source-only.md @@ -0,0 +1,4 @@ +Goal: reconcile existing HLS evidence and recommend remaining lifecycle boundary under interpreter13:41 routing. +Success: preserve prior failure/control results, verify current source ancestry/equality and raw evidence hash, commit existing dirty notes, send scoped recommendation. +Non-goals: no product/tests/browser/full/build/submission, no live or wholeStage3 claim; QA owns sole browser. +See matching reconciled test log. Next: await explicit offline active-torrent investigation routing. diff --git a/decisions/DECISIONS_2026-10-26_13-45-00_client-reliability-9-source-only.md b/decisions/DECISIONS_2026-10-26_13-45-00_client-reliability-9-source-only.md new file mode 100644 index 00000000..5fc1d4e0 --- /dev/null +++ b/decisions/DECISIONS_2026-10-26_13-45-00_client-reliability-9-source-only.md @@ -0,0 +1,5 @@ +- Preserve seven existing dirty notes verbatim alongside a new reconciliation, rather than rewriting old failed/incomplete results. +- Treat separate Firefox prefix3/3 as controlled qualification; original header-onlyFAIL remains separate. No speculative product fix or repeated browser. +- Use actual product SHA83fd2495 for ancestry; c95abe22 is a build identifier. +- Next recommended investigation is active torrent final-owner disposal under item9/priority2, with real production chain and controlled IO; source hints alone are not reproduced defect or implementation authority. +- Notes-only changes need source/hash/whitespace verification, no redundant full/lint/build. Commit evidence locally; no queue submission while source-only routing holds. diff --git a/test_logs/TEST_LOG_2026-10-24_19-46-17_client-reliability-9-resume.md b/test_logs/TEST_LOG_2026-10-24_19-46-17_client-reliability-9-resume.md new file mode 100644 index 00000000..47c4d614 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_19-46-17_client-reliability-9-resume.md @@ -0,0 +1,7 @@ +# Client reliability resume at 5f8e58be + +- Read disk fleet prompt/skill, newest RULE-CHANGES, PROGRAM, RESUME-BRIEF, area TODO, .task, repo memory, KNOWN_ISSUES and preserved HLS context/todo/decisions/browser evidence. Mailbox empty; reclaimed existing client-reliability-9. No new item. +- HEAD `5f8e58bec0ff83383b35bf0968f1cf0f66edc9cb`; unstable `0ffd92a8d2072a19fe61ac6edcf5097a9538fddd`. Tree initially clean. `git diff --name-only unstable HEAD`: four retained browser evidence docs only. `git diff --exit-code unstable HEAD -- js tests config package.json package-lock.json`: exit0. Controller/helper diff against prior handoff146076dd: exit0. Existing product evidence therefore remains applicable; no duplicate suite/build run. +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node --check /tmp/client9-hls-native-diagnostic-20261024T0259.mjs`: exit0. Diagnostic SHA256 `d0100521a1aeaaecd58e9ad08d3c42d8365c37e286c66f6e157071efb6316870`; original prepared script `28cf3511c0ac154e59ac519c0f68dfe4099cb37e016bae31c3564ed58db9375e` preserved. All four dist module SHA256 values match diagnostic pins. Source-only inspection confirms failure timeline and finally cleanup instrumentation; diagnostic remains UNEXECUTED. +- Fleet health19:45:39Z: max76C/load1.99/available67.4%/swap98%. Does not meet cooling start threshold. No browser, full gate, build, submission or product/test edit launched. +- BLOCKED message delivered to dispatch19:45:57Z requesting fresh exclusive bounded diagnostic/browser routing and cooling clearance; previous grants expired. .task records WAITING. Remaining Firefox body-entry prerequisite unclassified; prior Chromium3/3 does not qualify Firefox, real playback, segments, live IO, torrent, RangeGET or whole Stage3. diff --git a/test_logs/TEST_LOG_2026-10-24_19-55-20_client-reliability-9-diagnostic-hold.md b/test_logs/TEST_LOG_2026-10-24_19-55-20_client-reliability-9-diagnostic-hold.md new file mode 100644 index 00000000..4f5319d8 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_19-55-20_client-reliability-9-diagnostic-hold.md @@ -0,0 +1,7 @@ +# Reserved diagnostic preparation and resource HOLD + +- Read interpreter mailbox19:53:30: one unchanged d0100521 Firefox diagnostic conditionally granted after two fresh health snapshots below75C about30seconds apart, reasonableload/ampleRAM. Dispatch.task independently reserves sole slot and parks competing heavy work. No outgoing acknowledgement requested when blocked; interpreter reads.task. +- HEAD5f8e58be. Script SHA256 d0100521a1aeaaecd58e9ad08d3c42d8365c37e286c66f6e157071efb6316870 unchanged; node --check exit0. Four module hashes match saved pins; dist data-site-version c95abe22. Prior strict Chromium failure, Chromium3/3 and Firefox body-entry5000ms failure retained. +- Source diff against original28cf3511: diagnostic adds method/path/occurrence/stage timestamps, native fetch/text/probe settlement tracing and failure/cleanup output. Existing network behavior, assertions and5000ms deadlines unchanged. diff exit1 means expected instrumentation differences, not test failure. No script edits. +- Health19:53:43.729Z max74.1C/load4.08/RAMavailable62.7%;19:54:26.104Z max78.1C/load4.9/RAM59.5%;19:55:09.881Z max78C/load9.8/RAM60%. Swap98% throughout. No qualifying two-snapshot pair; latest load also exceeds8. Browser NOTSTARTED; conditional one-run grant unconsumed. +- HOLD in.task with concrete readings and next check on interpreter cooling/resume signal; require two new qualifying samples before execution. No background watcher/scheduler/process stops, no gates/build/productwrites/submission, no rerun or timeout/assertion change. Firefox prerequisite cause remains unclassified; no live playback/segments/torrent/RangeGET qualification. diff --git a/test_logs/TEST_LOG_2026-10-24_22-05-00_client-reliability-9-firefox-diagnostic.md b/test_logs/TEST_LOG_2026-10-24_22-05-00_client-reliability-9-firefox-diagnostic.md new file mode 100644 index 00000000..66cd2eba --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_22-05-00_client-reliability-9-firefox-diagnostic.md @@ -0,0 +1,10 @@ +# One reserved Firefox HLS diagnostic — prerequisite failure isolated + +- Interpreter22:03:18 post-outage conditional ONE unchanged diagnostic grant; exclusive brief browser slot, other heavy work parked. ACK and START recorded.task. HEAD5f8e58bec0ff83383b35bf0968f1cf0f66edc9cb. All existing dirty notes preserved. +- Fresh health22:03:29.023Z max64.1C/load6.02/availableRAM68.8%/battery56%38min;22:04:09.921Z max63.8C/load3.55/RAM68.9%/battery55%39min. Both qualify. Saved d0100521a1aeaaecd58e9ad08d3c42d8365c37e286c66f6e157071efb6316870 script unchanged, node --check exit0, four module hashes match pinned c95abe22 dist. Prior failed results retained. +- Normal host approval granted. Command: `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-hls-native-diagnostic-20261024T0259.mjs firefox > /tmp/client9-hls-firefox-diagnostic-20261024T2204.log 2>&1`. Natural exit1; diagnostic cleanup-finished at7831.007ms. No retry, timeout extension or assertion/script/product edits. +- Actual native observer/head/GET cancellation case: first GET arrives2148.415ms, abort2152.706ms, transport close2154.187ms, probe null settlement2154.754ms. All strict firstState assertions and close check passed before next case. Replacement same event/URL performs fresh HEAD+GET,200 response/text25chars,healthy settlement2223.815ms; strict healthy badge/cache-write assertions passed before body case. +- Body case: observer2235.746ms; HEAD arrives2246.768ms/completes200; native GET invoked2248.613ms/arrives2253.099ms; server flushes200headers with0bodybytes2253.578ms. No fetch-resolve, fetch-reject or text-entry event for this body GET before prerequisite timeout at7238.467ms. At failure GET still open; body-owner disposal has not run. Case3 shared-owner scenario never reached. +- Failure is `page.evaluate: Timed out waiting for native body-read entry /hls/body/pending.m3u8 after 5000ms`, script338. Browser/server finally cleanup closes body GET7651.709ms and completes7831.007ms; all6request responses closed. Slot RELEASED immediately on terminal process result. No final success JSON; no unsupported page-error/public-denial totals inferred. +- Observation narrows original failure to the native fetch/body-entry prerequisite after header-only delivery. It does not demonstrate a defect in cancellation during Response.text: that scenario never starts. Header-only native delivery/buffering is a hypothesis, not independently proven browser behavior. No speculative product patch. Any new fixture experiment requires separately scoped routing; grant consumed. +- Exact raw output preserved at /tmp/client9-hls-firefox-diagnostic-20261024T2204.log and state/evidence/client-reliability-9/firefox-diagnostic-20261024T2204.log. No gate/build/submission. Firefox overall qualification remains incomplete; real playback,segments,publicIO,torrent,RangeGET and wholeStage3 unverified. diff --git a/test_logs/TEST_LOG_2026-10-24_22-07-00_client-reliability-9-prefix-proposal.md b/test_logs/TEST_LOG_2026-10-24_22-07-00_client-reliability-9-prefix-proposal.md new file mode 100644 index 00000000..452836fc --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-24_22-07-00_client-reliability-9-prefix-proposal.md @@ -0,0 +1,9 @@ +# Source-only Firefox HLS fixture control proposal + +- Interpreter22:05:40 requests separately named source-only control; no new network/browser, product patch or repeated diagnostic. QA owns next sole browser. Original d0100521 and exact failed output00390c96 remain preserved. First fetch cancellation and exact-source replacement PASS; body-entry prerequisite FAIL; shared UNRUN. +- Proposed file `/tmp/client9-hls-native-prefix-control-20261024T2207.mjs`, SHA256 `2988ddf749762b09cec37cc5b49558e9f1ae8cd710fec43365b10dce8cc912bc`. Copy retained in state/evidence/client-reliability-9. `node --check` exit0. UNEXECUTED; no network or browser invoked. +- Exact behavioral delta within GET `/hls/body/` response only: after existing HTTP200+flushHeaders, call `res.write(' ')`, one pinned ASCIIspace/hex20; emit `prefix-written` with bodyBytes1/prefixHex20. Leave stream open without end. Original headers-flushed/bodyBytes0 event remains. Comments explain hypothesis; no other code altered. `diff -u` exit1 is expected differences, not validation failure. +- Rationale from source: product waits for fetch before calling response.text, and trimStart removes this harmless leading space if a complete manifest is ever delivered. The held stream ensures the body remains incomplete; cancellation must still settle null/abort/no cache after native text-entry. Original observed trace proves header-only delivery did not reach native fetch resolution before deadline in this fixture. It does NOT establish that Firefox universally requires a body byte; buffering, browser/network stack or fixture behavior remain possible. Proposed byte writes to server socket but does not itself prove native delivery. +- All original assertions remain: HEAD200 before GET; correct native GET body reader; final-owner cancellation null, GET abort and HEAD not aborted, unchanged cache writes1, transport closes; fresh same-source healthy replacement; shared-owner behavior. All5000ms deadlines, real observer/fetch/Response.text, publicdeny, module/buildpins, cancellation ownership, cleanup and case ordering unchanged. No retries/sleeps/timeouts/assertion relaxation. +- Proposed interpretation for a separately authorized single control: original header-only failure is comparison baseline. If prefix-written is followed by fetch-resolve200 and text-entry before disposal, then null/no-write/abort/close passes, it establishes the intended native body-read prerequisite for this control. Preserve shared result separately. If no fetch-resolve/text-entry or new failure, retain failure as inconclusive and stop; do not add bytes/delays/retries automatically. A pass supports fixture sensitivity to first-byte delivery in this controlled run, not a universal protocol claim or a product fix. No run authorized by this proposal. +- Original diagnostic SHA remains d0100521a1aeaaecd58e9ad08d3c42d8365c37e286c66f6e157071efb6316870. HEAD5f8e58be. Product/tests/config/build untouched; no gate, submission or release qualification. Review/routing required before any execution. diff --git a/test_logs/TEST_LOG_2026-10-25_03-27-00_client-reliability-9-prefix-result.md b/test_logs/TEST_LOG_2026-10-25_03-27-00_client-reliability-9-prefix-result.md new file mode 100644 index 00000000..492b65fa --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-25_03-27-00_client-reliability-9-prefix-result.md @@ -0,0 +1,10 @@ +# Firefox prefix control — three cases pass + +- Interpreter03:25:37 explicitly reviewed proposal and granted ONE unchanged prefix control after fresh safe health; QA explicit release verified by interpreter. Health03:25:50.976Z max71.8C/load1.63/RAMavailable69.7%/battery96%charging. No long job launched; swap nearfull constraint retained. +- HEAD5f8e58bec0ff83383b35bf0968f1cf0f66edc9cb. Exact script2988ddf749762b09cec37cc5b49558e9f1ae8cd710fec43365b10dce8cc912bc unchanged; node --check exit0 and four dist modulepins verified/c95abe22. Original d0100521 baseline and failure00390c96 preserved. +- START recorded.task. Normal host approval granted. Command: `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-hls-native-prefix-control-20261024T2207.mjs firefox > /tmp/client9-hls-firefox-prefix-20261025T0326.log 2>&1`. Natural exit0; cleanup-finished2849.213ms. RELEASE recorded immediately after result. No retry, sleeps, changed deadlines/assertions or product/test/config edits. +- PASS3/3: (1) final-owner native fetch GET abort/null/no cache/stale badge and fresh exact-event/source replacement healthy; (2) native Response.text cancellation after real body entry: GET aborted/null/no extra cache write, HEAD remains unaborted; (3) two owners share1HEAD/1GET, first release does not abort live GET, remaining owner becomes healthy/cachewrites2. +- Body trace hostmonotonicms: GET arrives2078.402, headersflushed2078.682, pinned ASCIIspace0x20 written2078.861, native fetch resolves200 at2083.682, native text-entry2084.018, final-owner dispose/abort2089.382, responseclose2089.557, textrejectAbortError2090.271, probenull2090.355. No body completion before disposal; actual native streaming body path exercised. +- Final JSON pass=true,8requests=4HEAD+4GET,all8responsesclosed,pageErrors0,publicDeniedCount4. Controlled loopback endpoints, real native observer/fetch/AbortController/Response.text; module hash pins unchanged. No live public IO, segments, decoding, actual playback, torrent/RangeGET/same-turn browser identity or wholeStage3 qualification. +- Comparison: original header-only body GET did not reach fetch resolution/text-entry within5000ms; separately named one-byte held-open stream did, and unchanged cancellation assertions passed. Supports first-byte-sensitive fixture prerequisite for these controlled runs, not universal Firefox protocol behavior or new product defect/fix. Original FAIL remains a separate result. +- Exact raw log preserved /tmp/client9-hls-firefox-prefix-20261025T0326.log and state/evidence/client-reliability-9/client9-hls-firefox-prefix-20261025T0326.log. Raw SHA256 6d6ec7e58373fc12580df851dd9321283334a1d969d0d644bba906ce427d25e8. No gate/build/submission; existing dirty evidence preserved. Next action await bounded routing; item9 remains open for separately scoped remaining work. diff --git a/test_logs/TEST_LOG_2026-10-26_13-45-00_client-reliability-9-reconciled.md b/test_logs/TEST_LOG_2026-10-26_13-45-00_client-reliability-9-reconciled.md new file mode 100644 index 00000000..a79803d7 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_13-45-00_client-reliability-9-reconciled.md @@ -0,0 +1,16 @@ +# Client9 source-only evidence reconciliation + +- Routing: interpreter mail 2026-10-26T13:41:14Z requests reconciliation and next bounded lifecycle recommendation; QA owns next sole browser. No client browser/full/build/product changes authorized by this step. +- Inspected HEAD 5f8e58bec0ff83383b35bf0968f1cf0f66edc9cb, branch area/client-reliability. Item9 reclaimed, only open area item, filedAt fb54cea3a2ba99b4860421724a5050af6b97c293. Seven pre-existing untracked handoff/evidence files preserved verbatim and included in this reconciliation. +- Current verification: git diff --exit-code unstable HEAD -- js tests config package.json package-lock.json => 0; git merge-base --is-ancestor 83fd2495 HEAD => 0; same for f41ac656 => 0; git diff --exit-code 83fd2495 HEAD -- js/ui/urlHealthController.js js/services/hlsPlayback.js => 0. Landed HEAD/HLS source remains present unchanged. No duplicate product tests needed for notes-only work. +- Historical full/build evidence: HLS landed 83fd2495 after unchanged normal gate exit0, 437 unique starts; focused129/6files,19 failing mutants,lint11 and build/artifact recorded in TEST_LOG_2026-10-23_13-00-00_client-reliability-9-hls-landed.md. These are prior results, not rerun today. Earlier divergence and thermal interruption remain recorded. +- c95abe22 is the recorded dist build version, not an available Git object (git merge-base check rejected it as invalid). Use 83fd2495 for product ancestry. This does not invalidate recorded module hash pins or establish current preview state. +- Original Chromium replacement failure and original Firefox header-only body-entry failure remain separate failures (TEST_LOG_2026-10-24_02-55-00_client-reliability-9-browser-checkpoint.md). Diagnostic d0100521 naturally exits1: GET arrives/headers flush, but native fetch does not resolve or enter Response.text within unchanged5000ms; body disposal case never begins, shared case unrun. No cancellation defect demonstrated by that prerequisite failure. +- Separately authorized prefix control2988ddf7 naturally exits0,3/3 with cleanup2849ms;8requests/8closed/pageErrors0/publicDenied4. One ASCIIspace held-open stream reaches native fetch/text entry; final-owner GET abort/null/no obsolete cache, replacement healthy and shared live owner controls pass. Existing log TEST_LOG_2026-10-25_03-27-00_client-reliability-9-prefix-result.md records scope/timeline. Current sha256sum of saved raw evidence => 6d6ec7e58373fc12580df851dd9321283334a1d969d0d644bba906ce427d25e8, matches recorded hash. +- Qualification: controlled native Chromium original fixture3/3 and Firefox separate prefix control3/3. Original Firefox fixture remains failed; this is evidence of fixture sensitivity in those runs, not universal Firefox behavior or real playback qualification. No live public IO, media segments/decoder, torrent, RangeGET, CPU benefit, same-turn browser replacement or wholeStage3 claim. + +## Recommended next bounded lifecycle item + +- Remain under campaign priority2/item9: actual grid observer -> queue -> TorrentClient.probePeers active final-owner disposal. Source only: js/gridHealth.js releaseProbe cancels queued jobs only; started jobs keep prior cache/lifecycle. Queue cancel returns false once job leaves queue. probePeers in js/webtorrent.js owns timeout/poll and temporary torrent, resolves after deferred destruction, and currently exposes no owner cancellation input. Source suggests an investigation boundary; no current runtime defect has been reproduced in this turn. +- Request dispatch routing for offline scratch measurements only, using real observer/grid queue/probePeers with controlled fake WebTorrent IO and clock, public traffic denied. Count final-owner torrent/listeners/timers/settlement/slot/cache/inflight before/after disposal; compare shared live owner, same-turn/later rejoin, late callbacks/replacement, queued competition/FIFO, live wire/error/timeout and delayed teardown. Preserve existing four-slot cap and teardown-before-release safety. Inspect existing integrity/spec before tests; no product/test change until measured defect plus routing. +- Keep playback/RangeGET and Amber staged separately per PROGRAM. No new browser/full/build/submission in this checkpoint; no target branch change or preview refresh. Commit is local evidence preservation, not landing proof. Item9 stays open pending separately routed remaining slice. diff --git a/todo/TODO_2026-10-24_19-46-17_client-reliability-9-resume.md b/todo/TODO_2026-10-24_19-46-17_client-reliability-9-resume.md new file mode 100644 index 00000000..ec1bb173 --- /dev/null +++ b/todo/TODO_2026-10-24_19-46-17_client-reliability-9-resume.md @@ -0,0 +1,5 @@ +- [x] Current rules/mailbox/HEAD applicability and existing item claim. +- [x] Verify runtime equality, diagnostic syntax and four dist pins without executing browser. +- [ ] Fresh dispatch scope/slot grant and cooling clearance. +- [ ] Authorized bounded Firefox stage diagnostic; preserve exact failure/timeline/cleanup and release slot. +- [ ] Classify prerequisite before any fixture or product changes; item9 stays open. diff --git a/todo/TODO_2026-10-26_13-45-00_client-reliability-9-source-only.md b/todo/TODO_2026-10-26_13-45-00_client-reliability-9-source-only.md new file mode 100644 index 00000000..83482ac2 --- /dev/null +++ b/todo/TODO_2026-10-26_13-45-00_client-reliability-9-source-only.md @@ -0,0 +1,6 @@ +- [x] Read current rules/PROGRAM/brief/area TODO/task/mail and reclaim item9. +- [x] Verify current source equals landed HLS boundary and prior raw prefix evidence hash. +- [x] Reconcile original failures and separate controlled browser results without rerun. +- [x] Recommend bounded active torrent owner lifecycle measurements; no defect asserted from source. +- [ ] Dispatch route next offline investigation; product changes require demonstrated defect and explicit routing. +- [ ] Remaining item9 torrent qualification; real playback/segments/RangeGET/live scope unverified. From ab1ea6dee1da7eebd2b5c08f3d5935dfbfb045d0 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Mon, 26 Oct 2026 11:26:24 -0400 Subject: [PATCH 3/6] docs: record client-reliability-9 active torrent cancellation baseline --- ...6_15-25-00_client-reliability-9-torrent.md | 4 ++ ...6_15-25-00_client-reliability-9-torrent.md | 5 +++ docs/agents/backlog/client-reliability-9.json | 2 +- ...ent-reliability-9-torrent-investigation.md | 39 +++++++++++++++++++ ...6_15-25-00_client-reliability-9-torrent.md | 8 ++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 context/CONTEXT_2026-10-26_15-25-00_client-reliability-9-torrent.md create mode 100644 decisions/DECISIONS_2026-10-26_15-25-00_client-reliability-9-torrent.md create mode 100644 test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md create mode 100644 todo/TODO_2026-10-26_15-25-00_client-reliability-9-torrent.md diff --git a/context/CONTEXT_2026-10-26_15-25-00_client-reliability-9-torrent.md b/context/CONTEXT_2026-10-26_15-25-00_client-reliability-9-torrent.md new file mode 100644 index 00000000..247ad3bd --- /dev/null +++ b/context/CONTEXT_2026-10-26_15-25-00_client-reliability-9-torrent.md @@ -0,0 +1,4 @@ +Goal: interpreter-authorized current-HEAD offline active torrent lifecycle investigation, no implementation. +Baseline HEAD e9af76df, real observer/grid/queue/probePeers, fake WebTorrent IO+clock. +Result: corrected12cases7pass5fail/naturalexit1; cleanup0remaining resources; existing lifecycle11/11 naturalexit0. See matching TEST_LOG. +Next: dispatch independent reproduction and explicit gridHealth/probePeers-only ownership plus spec correction before fixes/tests. QA owns browser; no full/build/submission. diff --git a/decisions/DECISIONS_2026-10-26_15-25-00_client-reliability-9-torrent.md b/decisions/DECISIONS_2026-10-26_15-25-00_client-reliability-9-torrent.md new file mode 100644 index 00000000..4047f7cd --- /dev/null +++ b/decisions/DECISIONS_2026-10-26_15-25-00_client-reliability-9-torrent.md @@ -0,0 +1,5 @@ +- Investigation uses actual production chain, fake only observer delivery/WebTorrent IO/timers/persistence; no implementation or committed tests. +- Preserve first12=5pass/7fail fixture: two control failures are JSDOM storage-event timers; separate memoryStorage IO fixture12=7pass/5fail retains identical assertions and original evidence. +- Treat five failures as planned Stage3 active-cancellation gap, not regression against existing intentional active-sharing/cache contracts. Need explicit routed spec correction before changing those tests. +- Smallest fix boundary gridHealth ownership/identity/cache plus probePeers lifecycle only. Preserve deferred temporary-torrent destruction after callback unwinds and release queue slot after teardown; retain shared probe client/other owners. +- No live browser/WebTorrent/network/CPU/RangeGET claim; no product edits until independent routing. diff --git a/docs/agents/backlog/client-reliability-9.json b/docs/agents/backlog/client-reliability-9.json index 5b8f7972..82ea5053 100644 --- a/docs/agents/backlog/client-reliability-9.json +++ b/docs/agents/backlog/client-reliability-9.json @@ -7,5 +7,5 @@ "addedOn": "2026-10-22", "filedAt": "fb54cea3a2ba99b4860421724a5050af6b97c293", "brief": "docs/agents/CAMPAIGN-2026-10-22.md", - "evidence": "HEAD-only fix e9c960ed/merged09f52bdd durably landed f41ac656 normalgateexit0,435discovered/435unique starts missingextra0,ancestry0;build/artifactexit0;controlled native Chromium+Firefox lifecycle PASS with synthetic loadeddata/publicdeny. Prior60focused/16mutants/lint11. Resources released. HLS/torrent/RangeGET separately OPEN; no wholeStage3 claim. test_logs/TEST_LOG_2026-10-22_20-52-00_client-reliability-9-browser.md HLS read-only atd04d501e:12modes/7controls pass/5cancellationfail/0cancelled/naturalexit1; GET/body finalowner retains timer/unsettled,rejoin old,latecache. Await explicit controller+HLShelper routing. test_logs/TEST_LOG_2026-10-22_20-54-00_client-reliability-9-hls-investigation.md HLS explicitlyrouted20:55:13Z;minimal controllerhandoff+helperfetch/bodycancel implemented;new35+existing94=129pass/6files,19isolatedmutantsnaturallyfail/cancelled0,lint11exit0;noexistingtestsmodified. READY for serialized full/build/browser/normal slot after candidatecommit/merge; notsubmitted. test_logs/TEST_LOG_2026-10-22_21-03-00_client-reliability-9-hls-ready.md" + "evidence": "HEAD-only fix e9c960ed/merged09f52bdd durably landed f41ac656 normalgateexit0,435discovered/435unique starts missingextra0,ancestry0;build/artifactexit0;controlled native Chromium+Firefox lifecycle PASS with synthetic loadeddata/publicdeny. Prior60focused/16mutants/lint11. Resources released. HLS/torrent/RangeGET separately OPEN; no wholeStage3 claim. test_logs/TEST_LOG_2026-10-22_20-52-00_client-reliability-9-browser.md HLS read-only atd04d501e:12modes/7controls pass/5cancellationfail/0cancelled/naturalexit1; GET/body finalowner retains timer/unsettled,rejoin old,latecache. Await explicit controller+HLShelper routing. test_logs/TEST_LOG_2026-10-22_20-54-00_client-reliability-9-hls-investigation.md HLS explicitlyrouted20:55:13Z;minimal controllerhandoff+helperfetch/bodycancel implemented;new35+existing94=129pass/6files,19isolatedmutantsnaturallyfail/cancelled0,lint11exit0;noexistingtestsmodified. READY for serialized full/build/browser/normal slot after candidatecommit/merge; notsubmitted. test_logs/TEST_LOG_2026-10-22_21-03-00_client-reliability-9-hls-ready.md 2026-10-26 active-torrent investigation at e9af76df: actual grid observer/queue/probePeers fake WebTorrent IO+clock; corrected scratch12=7pass/5fail/naturalexit1/allcleanup0/network0. Final-owner retains1torrent/2listeners/timeout+poll/unsettled, same-turn+later joins obsolete probe, latecache and occupied FIFO capacity; shared/live-wire/error/timeout/queued-priority/deferred-teardown/staleobserver controls pass. Existing lifecycle11/11 unchanged naturalexit0. First JSDOM timer-confounded12=5pass/7fail preserved; IO-isolated correction documented. Proposed gridHealth+probePeers optional lifecycle ONLY, needs explicit routing/spec correction for prior active-sharing/cache assertions; no product/test edits/full/build/browser/submission. test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md" } diff --git a/test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md b/test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md new file mode 100644 index 00000000..5dab06a9 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md @@ -0,0 +1,39 @@ +# Client9 active torrent investigation — no product changes + +- Authority: interpreter mail2026-10-26T15:19:48Z, INVESTIGATION only after source plan; actual gridHealth/queue/probePeers with fake IO/clock, no real peer traffic. QA sole browser; no client browser/full/build/product/test edits or submission. Read newest RULE-CHANGES/test-integrity and Stage3 source before scratch. +- HEAD e9af76dfd23c6ebdde355d376af05261bdb89f00, own area/client-reliability branch; clean initial tree. Runtime still unchanged at final inspection (`git diff --exit-code e9af76df -- js tests` =>0). filedAt fb54cea3 precedes already landed HEAD/HLS fixes; remaining torrent boundary still applies at current HEAD. +- Source plan: import actual js/gridHealth.js/createCardObserver/queue and actual TorrentClient.probePeers. Substitute WebTorrent class at constructor IO boundary with EventEmitter-based temporary torrents; transparent wrapper records actual method settlement. Controlled setTimeout/setInterval clock, synthetic observer delivery/JSDOM cards, fake persistence IO. No copied/rewritten product modules. No live tracker/WebRTC/swarm/decoder/browser. fetch/WebSocket guards record0 attempted calls; fake WebTorrent means no real peer IO. setImmediate only drains task/promise turns; no wall-clock sleeps/retries/timeouts increased/force exit. + +## Commands and retained results + +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-torrent-investigation-20261026.mjs > /tmp/client9-torrent-investigation-20261026.log 2>&1`: natural exit1,12cases/5pass/7fail. Five intended Stage3 cancellation assertions fail; two extra controls fail counting1 remaining zero-delay JSDOM StorageImpl event as torrent timer. Source node_modules/jsdom/lib/jsdom/living/webstorage/Storage-impl.js:74 schedules setTimeout on setItem. First script/log preserved unchanged; this is not a product error/timeout resource failure. +- Separate storage-isolated fixture keeps actual storage serialization/read functions, substitutes memory map at localStorage IO instead of JSDOM's asynchronous storage-event dispatch. All scenario assertions unchanged. `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node /tmp/client9-torrent-investigation-storage-isolated-20261026.mjs > /tmp/client9-torrent-investigation-storage-isolated-20261026.log 2>&1`: natural exit1,12cases/7pass/5fail. All12 finally-cleanups activeTorrents0/listeners0/unsettled0/timers0; each created torrent destroyed exactly once, max actual fake torrent resources4. This correction isolates fixture IO and does not change product code or rerun unchanged flakiness. +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node --test tests/grid-health-lifecycle.test.mjs > /tmp/client9-grid-existing-contract-20261026.log 2>&1`: natural exit0, runner reports file-level1pass/0fail/0cancelled (~2028ms); no individual scenario count in that output, not called11 from that run. +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node tests/grid-health-lifecycle.test.mjs > /tmp/client9-grid-existing-contract-direct-20261026.log 2>&1`: natural exit0, actual11scenarios/11pass/0fail/0cancelled/0skip (~332ms). Direct invocation exposes subtest counts, including prior active-sharing and disposed-active-cache contracts. Existing suite unchanged. +- Raw scripts/logs and SHA256 manifest retained under /home/user/.local/state/agent-fleet/bitvid/evidence/client-reliability-9/client9-torrent-investigation-20261026.sha256. Corrected script SHA25696eec664a054ba0d63c903c3f9bb086f57526e17b3df8951056898af162cfbe4; corrected log882780bf806cade580ffe0287709a5cf0f879acc7ea21842561bece63c522832. Original script86b5d189733cdcbc7fab716d3fb48136590f0be6a52955d46586d276aa255ef0/log42ffd9a486f930ef0bd308373c26e15894df71785c48d8672edd480ecadfb792. + +## Corrected fixture observations + +| Case | Result | Boundary evidence | +| --- | --- | --- | +| Final owner dispose | FAIL | Before and after dispose plus task/zero-delay drain:1torrent,2listeners,1timeout+1poll,1unsettled;0destroy. Expected prompt release without original20s deadline. | +| Disposed late wire | FAIL | Controlled late success destroys torrent/cleans timers but populates persistent healthy cache; disposed card remains checking. No stale badge defect. | +| Same-turn fresh owner | FAIL | Still1probe/1torrent, expected fresh second probe after prior final-owner disposal; new owner joins old work. | +| Later fresh owner | FAIL | Same1probe after task drain; retained obsolete work remains deduplicated. | +| Queue capacity after disposal | FAIL | Four active; fifth live source queued. Dispose one active final owner => still4starts/4resources/8listeners/4timeouts+4polls; expected fifth start after obsolete teardown. This is retained occupied capacity, not exceeding cap. | +| Shared live owner | PASS | Two feeds share1probe; first dispose retains live work/timer; wire yields healthy live card/cache, disposed card checking. | +| Live wire/cache | PASS | Healthy result and cache reuse; no extra add. | +| Live error | PASS | Unhealthy/error, temp torrent destruction, timers cleaned, negative cache retained. | +| Live20s timeout | PASS | Unsettled at19999 fake ms; timeout settles/unhealthy/cache/cleanup at20000. | +| Queued prune/priority/FIFO | PASS | Cancelled queued source never adds/caches; equal priority insertion then lower priority, peak4. | +| Deferred teardown/slot | PASS | Wire settles internally but next add waits for zero-delay destroy; destroy precedes fifth add, peak4. | +| Late disposed observer | PASS | No old-card updates/new add; late observer guarded. | + +## Contract and smallest proposed routing + +- Source-backed gap from planned Stage3 active cancellation, not a regression against existing queued-only tests. docs/performance-efficiency-plan.md Stage3 says pass abort/cancellation into active torrent probes and removed cards do not retain probes. Current gridHealth releaseProbe intentionally preserves running jobs; job.cancel only removes still-queued entries; webtorrent.probePeers accepts no cancellation owner and retains timeout/poll/temp torrent until wire/error/timeout. Missing signal alone is not proof: actual disposal retains measured resources and delays live queued progress. +- Proposed product boundary ONLY js/gridHealth.js ownership/cancelled record/inflight/cache guards and js/webtorrent.js probePeers optional lifecycle plumbing, plus unique focused tests/spec/integrity notes AFTER explicit dispatch routing. Do not change limits/TTLs/magnet hints/tracker policy, shared probe client or playback/service-worker/engine/app behavior. +- Mark final-owner cancelled/unavailable synchronously, detach active probe hooks/timers and schedule safe temporary-torrent destruction; settle cancelled work and advance queue exactly once AFTER destruction, preserving existing event-unwind/teardown-before-slot-release safety. Do not destroy the shared probeClient or other owners' torrents. Same-source replacement cannot share cancelled record or be deleted/cached/painted by old continuations. Preserve ownerless standalone helper callers and live/shared wire/error/timeout/cache behavior. +- Spec correction needed before altering tests/grid-health-lifecycle.test.mjs scenarios at367(active probe retained across last-owner gap/rejoin) and417(disposed active success caches). Old contract permits these; proposed new contract requires fresh request after final-owner cancellation/no obsolete cache. Preserve separate shared-with-live-owner/live-completion/cache/TTL controls and replace only with equally strict lifecycle/resource assertions under routed Test Integrity Note. No test changes made now. +- Future acceptance must include pre-start/at-add cancellation, synchronous/late wire/error callbacks, missing/ignored abort cooperation, same-turn/later replacement identity, cross-feed ownership, repeated release, queue error/cancellation cleanup, live timeout and deferred teardown exception/event-unwind safety. Current scratch does NOT establish these future cases, real WebTorrent network byte/resource behavior, browser/peer playback, CPU improvement, HLS/RangeGET or wholeStage3. +- DONE for this investigation: current-HEAD measured gap, preserved failed baseline+controls, smallest boundary/contract proposal. WAITING for dispatch routing/independent reproduction before any implementation or retained tests. Item9 remains open; evidence commit is local, not landed/qualified product. diff --git a/todo/TODO_2026-10-26_15-25-00_client-reliability-9-torrent.md b/todo/TODO_2026-10-26_15-25-00_client-reliability-9-torrent.md new file mode 100644 index 00000000..146f0d6e --- /dev/null +++ b/todo/TODO_2026-10-26_15-25-00_client-reliability-9-torrent.md @@ -0,0 +1,8 @@ +- [x] Read mailbox/current rules and write source plan. +- [x] Measure actual current-HEAD grid/probe lifecycle offline. +- [x] Preserve first fixture result; classify JSDOM storage timer confound; corrected IO-isolated fixture12=7pass/5fail. +- [x] Preserve old-contract suite11/11 and enumerate required spec correction. +- [x] Save scripts/rawlogs/hashes and narrow fix proposal. +- [ ] Independent dispatch reproduction/explicit implementation routing. +- [ ] Product fix, strict regressions+mutants+lint, later resource-routed full/build/browser/normal landing. +- [ ] Remaining live/network/wholeStage3 qualification. From 1b2362d2341414e69f67352e17529ed5dfedd45e Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Mon, 26 Oct 2026 15:08:05 -0400 Subject: [PATCH 4/6] fix: cancel final-owner active torrent probes (client-reliability-9) Preserve shared owners and standalone probe callers. Clear obsolete timers and defer temporary torrent destruction until event unwind, holding the queue slot through teardown. Guard cache and replacement inflight identity. Spec correction: previous queued-only active reuse/cache expectations are replaced by equally strict final-owner cleanup and fresh-request assertions, with independent live/shared/cache controls retained. See unique spec and Test Integrity Note. Saved focused checks: six files, 60 scenarios, zero failures/cancelled; 19 distinct mutants killed. Remaining full lint/full/build/browser and normal landing require a resource slot. No submission. --- ...nt-reliability-9-torrent-implementation.md | 1 + ...6_19-15-00_client-reliability-9-torrent.md | 6 + ...-26-client-reliability-9-active-torrent.md | 11 + js/gridHealth.js | 75 +-- js/webtorrent.js | 87 ++-- ...-26_client-reliability-9-active-torrent.md | 40 ++ ...00_client-reliability-9-torrent-focused.md | 16 + ...7-50_client-reliability-9-resumed-ready.md | 8 + tests/grid-health-active-torrent.test.mjs | 435 ++++++++++++++++++ tests/grid-health-lifecycle.test.mjs | 15 +- ...nt-reliability-9-torrent-implementation.md | 7 + ...-26_19-07-50_client-reliability-9-ready.md | 6 + ...6_19-15-00_client-reliability-9-restart.md | 8 + 13 files changed, 644 insertions(+), 71 deletions(-) create mode 100644 context/CONTEXT_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md create mode 100644 decisions/DECISIONS_2026-10-26_19-15-00_client-reliability-9-torrent.md create mode 100644 docs/spec_changes/2026-10-26-client-reliability-9-active-torrent.md create mode 100644 test_logs/TEST_INTEGRITY_2026-10-26_client-reliability-9-active-torrent.md create mode 100644 test_logs/TEST_LOG_2026-10-26_19-05-00_client-reliability-9-torrent-focused.md create mode 100644 test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md create mode 100644 tests/grid-health-active-torrent.test.mjs create mode 100644 todo/TODO_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md create mode 100644 todo/TODO_2026-10-26_19-07-50_client-reliability-9-ready.md create mode 100644 todo/TODO_2026-10-26_19-15-00_client-reliability-9-restart.md diff --git a/context/CONTEXT_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md b/context/CONTEXT_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md new file mode 100644 index 00000000..d32ab81d --- /dev/null +++ b/context/CONTEXT_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md @@ -0,0 +1 @@ +Approved dispatch routing read locally: actual baseline independently reproduced12=7pass5fail, no repeat needed. Scope gridHealth+optional probePeers lifecycle only. Goal final-owner null settlement/resource cleanup/fresh identity; preserve shared/standalone/live/cap4/FIFO/TTL/deferred destroy safety. Spec and integrity written first. Focused offline/mutants/targeted lint allowed; no full/build/browser/submission until resource grant. diff --git a/decisions/DECISIONS_2026-10-26_19-15-00_client-reliability-9-torrent.md b/decisions/DECISIONS_2026-10-26_19-15-00_client-reliability-9-torrent.md new file mode 100644 index 00000000..6f2974eb --- /dev/null +++ b/decisions/DECISIONS_2026-10-26_19-15-00_client-reliability-9-torrent.md @@ -0,0 +1,6 @@ +- Grid publishes owner/release/inflight promise before synchronous client IO so disposal or same-source registration inside constructor/add is safe; cancelled identity removed synchronously and cache guarded. +- Optional third probePeers lifecycle follows existing owner-record convention; standalone behavior unchanged. Cancel settlesnull after deferred temporary-torrent destroy call returns/throws; timers clear immediately, cancel hook/owned listeners removed at final teardown. +- Retain inert error handler through deferred teardown, even cancellation insideadd; repeated/late callbacks are settled guards. Shared probeClient remains alive; queue slot only releases after destroy, preserving event unwind/cap4/FIFO. +- Original tests367/417 contract corrected only after routed spec+integrity note; preserve separate shared-live/cache/TTL/timeout controls and strict noobsoletecache/freshrequest/resource assertions. +- No live WebTorrent transport/byte teardown qualification from fake IO. Async low-level network shutdown not measured; existing teardown call ordering preserved. +- Stop at completedfocused boundary for requested kit restart; no commit/merge/submission before restart, all snapshots saved. diff --git a/docs/spec_changes/2026-10-26-client-reliability-9-active-torrent.md b/docs/spec_changes/2026-10-26-client-reliability-9-active-torrent.md new file mode 100644 index 00000000..21f59cfa --- /dev/null +++ b/docs/spec_changes/2026-10-26-client-reliability-9-active-torrent.md @@ -0,0 +1,11 @@ +# Client9 active torrent ownership contract correction + +Authority: dispatch docs/agents/ROUTING-2026-10-26-client9-torrent.md (17:38UTC), read locally by client after interpreter18:53 relay. Independent exact12cases=7pass/5fail/naturalexit1/network0/cleanup0 confirms client baseline. This note precedes any prior expectation edits. + +Source: docs/performance-efficiency-plan.md Stage3 explicitly extends owner cancellation to active torrent probes and says removed cards do not retain probes. Earlier queued-only implementation intentionally left running probes eligible across final-owner disposal, a new same-source owner and cache completion. + +Old tests/grid-health-lifecycle.test.mjs scenarios originally at367 and417 permit last-owner active work to be rejoined and ownerless success cached. New contract: final-owner disposal synchronously marks old work cancelled/unavailable; it cannot be rejoined, cache, or paint. Timer/cancel hooks are cleaned, cancelled promise settles null, and safe temporary-torrent destruction happens after event unwind before queue slot release exactly once. A fresh same-source owner requests fresh work; old callbacks/finalizer cannot delete/cache/paint over it. Cancellation does not depend on an AbortController or cooperative transport. + +Retain strict independent controls: one leaving owner cannot cancel another live owner, active healthy/error/timeout caches retain existing TTL behavior, standalone helper callers preserve results, queue cap4/priority/FIFO and destroy-before-slot safety remain. The shared probe client and unrelated torrents must survive. Replace the two superseded scenarios with equally strict sharing-with-live-owner and obsolete-cache/fresh-request assertions, and add real grid+probe resource/settlement/identity tests. No silent deletion or relaxed assertions. + +Scope only js/gridHealth.js ownership/inflight/cache and js/webtorrent.js probePeers optional lifecycle, plus focused tests/notes. No app, playback/service-worker engine, URL/HLS, magnet/tracker policy, concurrency/TTL/config changes. Current offline source defect does not qualify real peers/network byte release, browser decoding/playback, CPU, RangeGET or all Stage3. Full/build/browser/queue still need separate resource grant. diff --git a/js/gridHealth.js b/js/gridHealth.js index 8d59c06c..e4b4e707 100644 --- a/js/gridHealth.js +++ b/js/gridHealth.js @@ -195,20 +195,48 @@ function queueProbe(magnet, cacheKey, priority = 0, webSeeds = [], owner) { if (probeInflight.has(cacheKey)) { const record = probeInflight.get(cacheKey); - record.owners.add(owner); - return record; + if (!record.cancelled) { + record.owners.add(owner); + owner.release = () => releaseProbe(record, owner, cacheKey); + return record; + } } const record = { owners: new Set([owner]), cancelled: false }; + owner.release = () => releaseProbe(record, owner, cacheKey); + // Publish ownership and the result before starting IO: client.add() can + // synchronously unregister a card or register another owner of this source. + let resolveJob; + let rejectJob; + record.promise = new Promise((resolve, reject) => { + resolveJob = resolve; + rejectJob = reject; + }) + .then((result) => { + if (record.cancelled) return null; + const normalized = normalizeResult(result); + if (cacheKey) setCacheEntry(cacheKey, normalized); + return normalized; + }) + .finally(() => { + if (cacheKey && probeInflight.get(cacheKey) === record) { + probeInflight.delete(cacheKey); + } + }); + if (cacheKey) probeInflight.set(cacheKey, record); record.job = probeQueue.run( () => torrentClient - .probePeers(magnet, { - timeoutMs: PROBE_TIMEOUT_MS, - maxWebConns: 2, - polls: PROBE_POLL_COUNT, - urlList: webSeeds, - }) + .probePeers( + magnet, + { + timeoutMs: PROBE_TIMEOUT_MS, + maxWebConns: 2, + polls: PROBE_POLL_COUNT, + urlList: webSeeds, + }, + record + ) .catch((err) => ({ healthy: false, peers: 0, @@ -219,26 +247,7 @@ function queueProbe(magnet, cacheKey, priority = 0, webSeeds = [], owner) { })), priority ); - record.promise = record.job.promise - .then((result) => { - if (record.cancelled) { - return null; - } - const normalized = normalizeResult(result); - if (cacheKey) { - setCacheEntry(cacheKey, normalized); - } - return normalized; - }) - .finally(() => { - if (cacheKey && probeInflight.get(cacheKey) === record) { - probeInflight.delete(cacheKey); - } - }); - - if (cacheKey) { - probeInflight.set(cacheKey, record); - } + record.job.promise.then(resolveJob, rejectJob); return record; } @@ -246,13 +255,13 @@ function queueProbe(magnet, cacheKey, priority = 0, webSeeds = [], owner) { function releaseProbe(record, owner, cacheKey) { owner.active = false; record.owners.delete(owner); - // A running probe keeps its existing lifecycle and cache behavior. Only work - // still waiting for a slot can be cancelled when its last card unregisters. - if (!record.owners.size && record.job?.cancel()) { + if (!record.owners.size && !record.cancelled) { record.cancelled = true; if (probeInflight.get(cacheKey) === record) { probeInflight.delete(cacheKey); } + record.job?.cancel(); + record.cancelActive?.(); } } @@ -524,10 +533,8 @@ function handleCardVisible({ card, pendingByCard, liveCards, priority = 0 }) { const webSeeds = webSeed ? [webSeed] : []; const owner = { active: true }; - const record = queueProbe(magnet, infoHash, priority, webSeeds, owner); - owner.release = () => releaseProbe(record, owner, infoHash); - pendingByCard.set(card, owner); + const record = queueProbe(magnet, infoHash, priority, webSeeds, owner); record.promise .then((result) => { diff --git a/js/webtorrent.js b/js/webtorrent.js index 6edb580d..3eb1be7a 100644 --- a/js/webtorrent.js +++ b/js/webtorrent.js @@ -77,12 +77,15 @@ export class TorrentClient { /** * Helper to check if a magnet link has active peers without starting a full - * download. Used for "Stream Health" badges/indicators in the UI. + * download. Optional lifecycle belongs to grid cards; standalone callers + * retain their normal wire/error/timeout results. */ async probePeers( magnetURI, - { timeoutMs = 8000, maxWebConns = 2, polls = 3, urlList = [] } = {} + { timeoutMs = 8000, maxWebConns = 2, polls = 3, urlList = [] } = {}, + lifecycle ) { + if (lifecycle?.cancelled || lifecycle?.owners?.size === 0) return null; const magnet = typeof magnetURI === "string" ? magnetURI.trim() : ""; if (!magnet) { return { @@ -137,6 +140,26 @@ export class TorrentClient { let torrent = null; let timeoutId = null; let pollId = null; + let adding = false; + let disposalStarted = false; + let result = null; + const cancelActive = () => { + lifecycle.cancelled = true; + finalize(null); + }; + const settleHealthy = () => { + const peers = Math.max(1, Math.floor(normalizeNumber(torrent?.numPeers, 1))); + finalize({ healthy: true, peers, reason: "peer" }); + }; + const settleError = (err) => { + const peers = Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0))); + finalize({ + reason: "error", + error: toError(err), + peers, + webseedOnly: peers === 0 && hasWebSeed, + }); + }; // A successful probe commonly settles from WebTorrent's `wire` event. // Do not destroy the temporary torrent while that event is still being @@ -144,21 +167,23 @@ export class TorrentClient { // listeners return, and synchronous destruction can leave its bitfield // null (`recalculate(...).fill` in the bundled client). The next task // guarantees the callback has fully unwound before cleanup. - const disposeProbeTorrent = (target, onDisposed = () => {}) => { - if (!target) { - onDisposed(); - return; - } + const disposeProbeTorrent = () => { + if (adding || disposalStarted) return; + disposalStarted = true; const dispose = () => { try { - target.destroy({ destroyStore: true }); + torrent?.destroy({ destroyStore: true }); } catch (err) { // A completed or already-destroyed probe is harmless. } finally { - onDisposed(); + torrent?.removeListener("wire", settleHealthy); + torrent?.removeListener("error", settleError); + if (lifecycle?.cancelActive === cancelActive) lifecycle.cancelActive = null; + resolve(lifecycle?.cancelled ? null : result); } }; - setTimeout(dispose, 0); + if (torrent) setTimeout(dispose, 0); + else dispose(); }; const finalize = (overrides = {}) => { @@ -179,10 +204,10 @@ export class TorrentClient { ? performance.now() : Date.now(); - const isHealthy = Boolean(overrides.healthy); - const peersCount = Number.isFinite(overrides.peers) ? overrides.peers : 0; + const isHealthy = Boolean(overrides?.healthy); + const peersCount = Number.isFinite(overrides?.peers) ? overrides.peers : 0; - const result = { + result = overrides === null ? null : { healthy: isHealthy, peers: peersCount, reason: isHealthy ? "peer" : "timeout", @@ -192,13 +217,18 @@ export class TorrentClient { durationMs: Math.max(0, endedAt - startedAt), ...overrides, }; - emit("torrent-probe-result", result); + if (result) emit("torrent-probe-result", result); // Keep the grid-health queue slot occupied until the delayed teardown // completes. Otherwise the next probe can begin before this probe has // detached its tracker listeners, briefly exceeding listener limits. - disposeProbeTorrent(torrent, () => resolve(result)); + disposeProbeTorrent(); }; + if (lifecycle) lifecycle.cancelActive = cancelActive; + if (lifecycle?.cancelled || lifecycle?.owners?.size === 0) { + cancelActive(); + return; + } try { const addOptions = { announce: trackers, @@ -225,6 +255,7 @@ export class TorrentClient { if (hasExplicitWebSeed) { addOptions.urlList = urlList; } + adding = true; torrent = client.add(augmentedMagnet, addOptions); } catch (err) { finalize({ @@ -233,26 +264,18 @@ export class TorrentClient { peers: 0, webseedOnly: hasWebSeed, }); + } finally { + adding = false; + } + // Even cancellation inside add() must absorb a late error until the + // returned torrent can be safely destroyed on the next task. + torrent?.on("error", settleError); + if (settled) { + disposeProbeTorrent(); return; } - - const settleHealthy = () => { - const peers = Math.max(1, Math.floor(normalizeNumber(torrent?.numPeers, 1))); - finalize({ healthy: true, peers, reason: "peer" }); - }; - torrent.once("wire", settleHealthy); - - torrent.once("error", (err) => { - const peers = Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0))); - finalize({ - healthy: false, - reason: "error", - error: toError(err), - peers, - webseedOnly: peers === 0 && hasWebSeed, - }); - }); + if (settled) return; if (safeTimeout > 0) { timeoutId = setTimeout(() => { diff --git a/test_logs/TEST_INTEGRITY_2026-10-26_client-reliability-9-active-torrent.md b/test_logs/TEST_INTEGRITY_2026-10-26_client-reliability-9-active-torrent.md new file mode 100644 index 00000000..188fad5d --- /dev/null +++ b/test_logs/TEST_INTEGRITY_2026-10-26_client-reliability-9-active-torrent.md @@ -0,0 +1,40 @@ +# Client9 active torrent test integrity + +Written before editing prior367/417 expectations. Exact authority and old/new contract: docs/spec_changes/2026-10-26-client-reliability-9-active-torrent.md. Prior failed baseline and original queued-only suite preserved in investigation evidence; production files and old assertions are in ab1ea6de parent history. + +```yaml +test_integrity_note: + change_type: [new_tests, spec_correction] + scenarios: + - id: SCN-active-torrent-last-owner + given: real grid observer and active probe with one card owner + when: the final owner unregisters + then: cancelled work settles null, clears timers/hooks and destroys temporary torrent after event unwind before slot release, without cache or stale badge writes + - id: SCN-active-torrent-shared-and-replacement + given: shared live owners or a same-source replacement after final-owner loss + when: one owner leaves or old callbacks and finalizer run + then: live shared work is preserved and cancelled identity cannot affect fresh work + - id: SCN-active-torrent-live-standalone + given: a live owner or standalone probe caller + when: wire, error or normal timeout occurs + then: existing results, cache TTL, shared probe client and bounded queue ordering remain + observable_outcomes: + - temporary torrent lifetime, destroy ordering/count, timers/listeners/hook, returned results + - actual card badge and persisted cache values, new work count, FIFO progress and resource cap + determinism_controls: + - fake WebTorrent IO, controlled clock and observer delivery, map-backed persistence IO + - isolated mutant copies, no public fetch/WebSocket, no sleeps or retries + anti_cheat_rationale: + prevents: + - cached obsolete results or stale identity mutation + - cancelling a still shared live owner + - immediate unsafe destroy or premature queue-slot release + - mocked probe implementation bypassing real resource cleanup + relaxation: + did_relax_any_assertion: false + if_true_explain_spec_basis: '' +``` + +Contract correction changes outcomes, not assertion strength: original last-owner-gap reuse/cache expectations become fresh-work/no-obsolete-cache/resource assertions, while separate live-owner/shared/cache/timeout controls remain. Mutant mappings and exact validation results will be recorded before handoff; no passing or mutant-kill counts claimed yet. + +Final focused27new+11corrected+22adjacent=60/60;19unique mutants all killed,20variant executions with added extended run; all27newscenarios covered. Full per-scenario mappings and failures: state/evidence/client9-torrent-impl-20261026/new-scenario-mutant-map.json and mutants/coverage.json. No mutants survived; all mutated suite runs cancelled0, natural failure exits. Restored state is automatic because only isolated copies were changed. Full/build/browser/landing pending separately. diff --git a/test_logs/TEST_LOG_2026-10-26_19-05-00_client-reliability-9-torrent-focused.md b/test_logs/TEST_LOG_2026-10-26_19-05-00_client-reliability-9-torrent-focused.md new file mode 100644 index 00000000..208d65bc --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_19-05-00_client-reliability-9-torrent-focused.md @@ -0,0 +1,16 @@ +# Client9 focused implementation validation (in progress) + +- Explicit dispatch17:38 routing read before implementation; baseline independently reproduced, no repeat. Spec change + integrity note written before old367/417 expectation edits. +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node tests/grid-health-active-torrent.test.mjs > /tmp/client9-torrent-focused-20261026-1.log 2>&1`: naturalexit0,24/24,0fail/0cancelled (~355ms). +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node tests/grid-health-lifecycle.test.mjs > /tmp/client9-grid-corrected-20261026-1.log 2>&1`: naturalexit0,11/11,0fail/0cancelled (~263ms); explicit active sharing/cache spec correction only, live/cache controls retained. +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node scripts/run-targeted-tests.mjs tests/grid-health-active-torrent.test.mjs tests/grid-health-lifecycle.test.mjs tests/grid-health.test.mjs tests/webtorrent-regression.test.mjs tests/webtorrent-handlers.test.mjs tests/minimal-webtorrent.test.mjs > /tmp/client9-torrent-targeted-20261026-2.log 2>&1`: naturalexit0,6files/58scenarios=25+11+6+3+12+1 pass,0fail/0cancelled. Includes added late error after cancellation inside add() and add-throw/shared-client reuse. No broad runner or browser involved. +- Later small test additions strengthen queued prune helper invocation and bound reentrant add callback in fixture; final focused rerun pending. Mutants and targeted lint pending. No full/build/browser/submission/landing or actual peers/network/CPU/wholeStage3 qualification. + +## Restart handoff after focused boundary + +- Final targeted command (same6files as above) output `/tmp/client9-torrent-targeted-20261026-final.log`: naturalexit0,60/60=27+11+6+3+12+1,0fail/0cancelled. Added strict queued-helper prune assertion, missing AbortController cancellation and error+throwing teardown queued progress. No tests weakened. Product delta remains2routed files, old suite only2explicit spec corrections. +- Mutants: `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD python3 /tmp/client9-torrent-mutants-20261026.py > /tmp/client9-torrent-mutants-20261026.log 2>&1`: naturalexit0 harness;19/19unique mutations killed by actual assertion failures, no survivors; each mutated new/old suite run exits naturally and reports cancelled0. Initial25new scenarios all covered. Additional isolated skip-destroy run with final27scenario file: naturalexit1,25assertion failures/0cancelled, including both added cases. Total19unique mutants/20variant executions; all27newscenarios have a recorded killing variant. No worktree mutation/restoration required: copies under/tmp only. Product formatting after initial mutation run changed no behavior; final focused60 covers current source. +- Targeted lint: `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD npm run lint:file-size`, `lint:innerhtml`, `lint:pool-access` each exit0 (separate logs). Same `lint:hex` first exits2 because spawnSync git EPERM; unchanged host-escalated command approved and exits0. Both results retained. No full npm run lint/all11 claim; remaining checks and unchanged full/build/browser/normal gate require later resource grant. +- Current upstream unstable04c8c7cf is4kit/setup commits ahead; read its newest2026-10-26 RULE-CHANGES via git show. Runtime js/tests/config/package inputs diff0 versus current committedHEAD; our workingtree changes remain local and uncommitted. No merge before this requested restart. Updated rules make swap occupancy advisory with ampleRAM/no swap-in; old blanket holds are superseded, but no heavy grant inferred. +- Durable copy: `/home/user/.local/state/agent-fleet/bitvid/evidence/client9-torrent-impl-20261026/` contains final4candidate files, original+finalfocused outputs, all targeted lint outputs incl EPERM+host pass, mutant runner/19variant copies+logs/summary, extended variant, per-new-scenario mutant map and manifest.sha256. Existing failure baselines and earlier evidence commits retained. No new commit/submission/landing; HEAD remainsab1ea6dee1da7eebd2b5c08f3d5935dfbfb045d0. +- STOP/SAFE TO RESTART per interpreter185753/190045 mails. Next resumed step: read live rules/mailbox/task and saved snapshots; inspect final2-file delta and tests, finish decision/integrity/READY notes, then commit named paths usingfleet tool and merge currentunstable (neverrebase). Focused60 need not repeat unless source changes; merged-tree/runtime equality determines remainingcheck need. Explicit resource grant still required before full/build/browser/submission. Real peers/browser/CPU/wholeStage3 unverified. No process stops, discard/stash/reset or kit work by client. diff --git a/test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md b/test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md new file mode 100644 index 00000000..9c62fbe4 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md @@ -0,0 +1,8 @@ +# Client9 resumed candidate review + +- Restart HEAD `ab1ea6dee1da7eebd2b5c08f3d5935dfbfb045d0`; unstable `04c8c7cf61eed29424f561297ef49c6cdfa91a0a`. Reclaimed existing item9; mailbox empty. Read local rules and newer unstable rules (2026-10-26) plus saved dispatch torrent routing. No repeated baseline or new scope. +- Review: final-owner synchronous cancellation/inflight removal, optional probePeers hook, prompt timer cleanup and deferred temporary-torrent destruction before slot release; shared client/owners and identity guards preserved. Product files only gridHealth.js and webtorrent.js; two explicitly authorized old expectations corrected. No product edits this turn. +- `sha256sum` of four candidate source/test files matches durable manifest exactly. Existing six-file focused evidence remains 60/60, fail0/cancelled0; 19 unique killed mutants, 20 variant executions/all27 new scenarios covered. This is preserved prior-run evidence, not a new test run. +- `git diff --check`: exit0. `git diff ab1ea6de unstable -- js tests config package.json package-lock.json`: exit0, empty. Upstream kit changes do not change those validation inputs. No duplicate focused run justified. +- Fresh MCP health19:07:29UTC: TCPU97.1C exceeds85C threshold; load11.58, availableRAM64.2%, swapInPages0. Heavy work held; no test/build/browser/submission launched. Hold owner dispatch; next allowed light work candidate commit/merge/runtime comparison. Need fresh resource clearance and explicit slot. +- Remaining full lint, merged-tree normal full gate, build/browser qualification and durable landing/ancestry. No live peer/network teardown, playback, CPU improvement or whole Stage3 qualification. diff --git a/tests/grid-health-active-torrent.test.mjs b/tests/grid-health-active-torrent.test.mjs new file mode 100644 index 00000000..9d5ef6a8 --- /dev/null +++ b/tests/grid-health-active-torrent.test.mjs @@ -0,0 +1,435 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { EventEmitter } from 'node:events'; +import { JSDOM } from 'jsdom'; +import './test-helpers/setup-localstorage.mjs'; +const root = new URL('../', import.meta.url).href; +const { torrentClient } = await import(`${root}js/webtorrent.js`); +const { attachHealthBadges } = await import(`${root}js/gridHealth.js`); +const { readTorrentProbeFromStorage } = await import(`${root}js/utils/storage.js`); +const { getCardLivenessPolicy, setCardLivenessPolicy } = await import(`${root}js/constants.js`); +const turn = () => new Promise(resolve => setImmediate(resolve)); +let nextHash = 100000; +const magnet = () => `magnet:?xt=urn:btih:${(nextHash++).toString(16).padStart(40, '0')}`; + +class Clock { + now = 0; next = 1; jobs = new Map(); + add(fn, ms, interval = false) { + const id = this.next++; + this.jobs.set(id, { fn, ms, at: this.now + ms, interval }); + return id; + } + tick(ms) { + const end = this.now + ms; + let steps = 0; + while (true) { + const entry = [...this.jobs].filter(([, job]) => job.at <= end) + .sort((a, b) => a[1].at - b[1].at || a[0] - b[0])[0]; + if (!entry) break; + assert.ok(++steps < 1000, 'fake clock must remain bounded'); + const [id, job] = entry; + this.now = job.at; + if (job.interval) job.at += job.ms; + else this.jobs.delete(id); + job.fn(); + } + this.now = end; + } + counts() { + const all = [...this.jobs.values()]; + return { timeout: all.filter(x => !x.interval && x.ms > 0).length, + poll: all.filter(x => x.interval).length, + teardown: all.filter(x => !x.interval && x.ms === 0).length }; + } +} + +function fixture(t) { + const dom = new JSDOM('', { url: 'https://example.invalid' }); + Object.defineProperty(dom.window, 'innerHeight', { value: 20 }); + const names = ['window', 'document', 'HTMLElement', 'localStorage', 'IntersectionObserver', + 'setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'fetch', 'WebSocket', 'AbortController']; + const saved = new Map(names.map(key => [key, Object.getOwnPropertyDescriptor(globalThis, key)])); + const previousPolicy = getCardLivenessPolicy(); + const clock = new Clock(); + const config = {}; + // Isolate persistence IO: JSDOM StorageImpl schedules unrelated storage-event timers. + // Production read/writeTorrentProbeToStorage still executes against this map. + const store = new Map(); + const writes = []; + const memoryStorage = { getItem: key => store.get(key) ?? null, + setItem: (key, value) => { writes.push([key, value]); store.set(String(key), String(value)); }, + removeItem: key => store.delete(key), clear: () => store.clear() }; + const observers = [], torrents = [], calls = [], disposals = [], updates = [], timeline = []; + let networkAttempts = 0, peak = 0; + class Observer { + constructor(callback) { this.callback = callback; this.cards = []; observers.push(this); } + observe(card) { this.cards.push(card); } + takeRecords() { return []; } + disconnect() { this.disconnected = true; } + show() { + this.callback(this.cards.map((target, index) => ({ target, isIntersecting: true, + intersectionRatio: 1, intersectionRect: { top: index * 20, width: 100, height: 20 } }))); + } + } + class FakeTorrent extends EventEmitter { + constructor(source, options) { + super(); this.source = source; this.options = options; this.numPeers = 0; + this.destroyed = false; this.destroyCount = 0; this.emitting = false; + } + on(event, listener) { + super.on(event, listener); + if (config.syncEvent === event && !this.syncEmitted) { + this.syncEmitted = true; + if (event === 'wire') this.wire(); else this.error(); + } + return this; + } + destroy(options) { + assert.deepEqual(options, { destroyStore: true }); + this.destroyedDuringEvent = this.emitting; + this.destroyedDuringAdd = config.adding === true; + this.destroyed = true; this.destroyCount++; + if (config.throwDestroy) throw new Error('controlled destroy exception'); + this.removeAllListeners(); + timeline.push(['destroy', this.source, clock.now]); + } + wire() { this.numPeers = 1; this.emitting = true; + try { this.emit('wire', {}); } finally { this.emitting = false; } } + error() { this.emit('error', new Error('controlled fake torrent error')); } + } + class FakeClient { + constructor() { config.onConstruct?.(); } + setMaxListeners() {} + destroy() { assert.fail('shared probe client must never be destroyed'); } + add(source, options) { + if (config.throwAdd) throw new Error('controlled add exception'); + const torrent = new FakeTorrent(source, options); + torrents.push(torrent); + peak = Math.max(peak, torrents.filter(x => !x.destroyed).length); + timeline.push(['add', source, clock.now]); + config.adding = true; + try { config.onAdd?.(torrent); } finally { config.adding = false; } + return torrent; + } + } + Object.assign(globalThis, { window: dom.window, document: dom.window.document, + HTMLElement: dom.window.HTMLElement, localStorage: memoryStorage, + IntersectionObserver: Observer, + setTimeout: (fn, ms = 0) => clock.add(fn, ms), clearTimeout: id => clock.jobs.delete(id), + setInterval: (fn, ms) => clock.add(fn, ms, true), clearInterval: id => clock.jobs.delete(id), + fetch: () => { networkAttempts++; throw new Error('network forbidden'); }, + WebSocket: class { constructor() { networkAttempts++; throw new Error('network forbidden'); } } + }); + const savedClient = { probeClient: torrentClient.probeClient, WebTorrentClass: torrentClient.WebTorrentClass, + probePeers: torrentClient.probePeers }; + torrentClient.probeClient = null; + torrentClient.WebTorrentClass = FakeClient; + // Transparent measurement wrapper: execute the actual production method, do not stub its logic. + torrentClient.probePeers = function(source, options, lifecycle) { + const call = { source, options, lifecycle, settled: false, result: undefined }; + calls.push(call); + return savedClient.probePeers.call(this, source, options, lifecycle).then(result => { + call.settled = true; call.result = result; return result; + }); + }; + setCardLivenessPolicy('show-pending'); + function feed(sources) { + const container = document.createElement('section'); + const cards = sources.map(source => { + const card = document.createElement('article'); + card.className = 'card'; card.dataset.videoId = source; card.dataset.magnet = source; + const badge = document.createElement('span'); badge.className = 'torrent-health-badge'; + card.append(badge); container.append(card); return card; + }); + document.body.append(container); + const events = []; + const dispose = attachHealthBadges(container, { onUpdate: event => { events.push(event); updates.push(event); } }); + disposals.push(dispose); + return { container, cards, dispose, events, observer: observers.at(-1), + show() { this.observer.show(); } }; + } + const cache = source => readTorrentProbeFromStorage(source.match(/btih:([a-f0-9]{40})/)[1]); + const snapshot = source => ({ started: torrents.length, activeTorrents: torrents.filter(x => !x.destroyed).length, + destroyed: torrents.filter(x => x.destroyed).length, + listeners: torrents.reduce((n, t) => n + t.eventNames().reduce((m, e) => m + t.listenerCount(e), 0), 0), + unsettled: calls.filter(x => !x.settled).length, timers: clock.counts(), + cache: source ? cache(source) : undefined, peak, networkAttempts }); + async function drain() { await turn(); clock.tick(0); await turn(); } + async function cleanup() { + disposals.forEach(dispose => dispose()); + for (let i = 0; i < 10 && (calls.some(x => !x.settled) || clock.jobs.size); i++) { + torrents.filter(x => !x.destroyed).forEach(t => t.wire()); + await drain(); + } + const final = snapshot(); + + try { + assert.equal(final.activeTorrents, 0); assert.equal(final.unsettled, 0); + assert.equal(final.listeners, 0); assert.equal(clock.jobs.size, 0); + assert.equal(networkAttempts, 0); + assert.ok(torrents.every(x => x.destroyCount === 1), 'destroy exactly once'); + assert.ok(torrents.every(x => !x.destroyedDuringEvent && !x.destroyedDuringAdd), 'destroy after event/add unwind'); + assert.ok(calls.every(x => !x.lifecycle?.cancelActive), 'cancel hook removed'); + } finally { + Object.assign(torrentClient, savedClient); + setCardLivenessPolicy(previousPolicy); + dom.window.close(); + for (const [key, desc] of saved) { + if (desc) Object.defineProperty(globalThis, key, desc); else delete globalThis[key]; + } + } + } + t.after(cleanup); + return { feed, cache, snapshot, drain, clock, torrents, calls, timeline, config, writes, + probe: (source, lifecycle) => torrentClient.probePeers(source, { timeoutMs: 20000 }, lifecycle), + get peak() { return peak; } }; +} + +const cases = [ + ['final-owner-cleanup', async f => { + const source = magnet(), feed = f.feed([source]); feed.show(); + assert.equal(f.torrents.length, 1); + feed.dispose(); await f.drain(); + assert.equal(f.snapshot().activeTorrents, 0, 'last owner must not retain an active torrent'); + assert.equal(f.snapshot().unsettled, 0, 'last owner must settle without original timeout'); + assert.equal(f.calls[0].result, null); + assert.equal(f.calls[0].lifecycle.cancelActive, null); + assert.equal(f.clock.jobs.size, 0); + assert.equal(f.cache(source), null); + }], + ['disposed-late-success-no-cache', async f => { + const source = magnet(), feed = f.feed([source]); feed.show(); feed.dispose(); + f.torrents[0].wire(); await f.drain(); + assert.equal(feed.cards[0].dataset.streamHealthState, 'checking', 'stale badge guard retained'); + assert.equal(f.cache(source), null, 'obsolete active completion must not populate persistent cache'); + }], + ['same-turn-fresh-rejoin', async f => { + const source = magnet(), old = f.feed([source]); old.show(); old.dispose(); + const replacement = f.feed([source]); replacement.show(); + await f.drain(); + assert.equal(f.calls.length, 2, 'new same-turn owner must start a fresh probe'); + }], + ['later-fresh-rejoin', async f => { + const source = magnet(), old = f.feed([source]); old.show(); old.dispose(); await f.drain(); + const replacement = f.feed([source]); replacement.show(); await f.drain(); + assert.equal(f.calls.length, 2, 'new later owner must start a fresh probe'); + }], + ['disposal-releases-fifo-capacity', async f => { + const active = Array.from({ length: 4 }, () => f.feed([magnet()])); active.forEach(x => x.show()); + const queued = f.feed([magnet()]); queued.show(); assert.equal(f.calls.length, 4); + active[0].dispose(); await f.drain(); + assert.equal(f.calls.length, 5, 'queued live owner must gain released obsolete active capacity'); + assert.ok(f.peak <= 4); + }], + ['shared-live-owner', async f => { + const source = magnet(), old = f.feed([source]), live = f.feed([source]); old.show(); live.show(); + assert.equal(f.calls.length, 1); old.dispose(); await f.drain(); + assert.equal(f.snapshot().activeTorrents, 1); assert.equal(f.snapshot().timers.timeout, 1); + f.torrents[0].wire(); await f.drain(); + assert.equal(live.cards[0].dataset.streamHealthState, 'healthy'); + assert.equal(old.cards[0].dataset.streamHealthState, 'checking'); assert.ok(f.cache(source)); + }], + ['live-wire-cache', async f => { + const source = magnet(), live = f.feed([source]); live.show(); f.torrents[0].wire(); await f.drain(); + assert.equal(live.cards[0].dataset.streamHealthState, 'healthy'); assert.ok(f.cache(source)); + const cached = f.feed([source]); cached.show(); assert.equal(f.calls.length, 1); + assert.equal(cached.cards[0].dataset.streamHealthState, 'healthy'); + }], + ['live-error-cleanup-cache', async f => { + const source = magnet(), live = f.feed([source]); live.show(); f.torrents[0].error(); await f.drain(); + assert.equal(live.cards[0].dataset.streamHealthState, 'unhealthy'); + assert.equal(f.calls[0].result.reason, 'error'); assert.ok(f.cache(source)); + assert.equal(f.snapshot().activeTorrents, 0); assert.equal(f.clock.jobs.size, 0); + }], + ['live-timeout-cleanup-cache', async f => { + const source = magnet(), live = f.feed([source]); live.show(); + f.clock.tick(19999); await turn(); assert.equal(f.calls[0].settled, false); + f.clock.tick(1); await turn(); + assert.equal(live.cards[0].dataset.streamHealthState, 'unhealthy'); + assert.equal(f.calls[0].result.reason, 'timeout'); assert.ok(f.cache(source)); + assert.equal(f.snapshot().activeTorrents, 0); assert.equal(f.clock.jobs.size, 0); + }], + ['queued-cancel-priority-fifo', async f => { + const active = f.feed(Array.from({ length: 4 }, magnet)); active.show(); + const firstSource = magnet(), lowSource = magnet(), equalSource = magnet(), cancelledSource = magnet(); + const batch = f.feed([firstSource, lowSource]); batch.show(); + const equal = f.feed([equalSource]); equal.show(); + const cancelled = f.feed([cancelledSource]); cancelled.show(); cancelled.dispose(); + for (const [slot, expected] of [[0, firstSource], [4, equalSource], [5, lowSource]]) { + f.torrents[slot].wire(); await f.drain(); + assert.ok(f.torrents.at(-1).source.includes(expected.slice(-40))); + } + assert.equal(f.torrents.some(x => x.source.includes(cancelledSource.slice(-40))), false); + assert.equal(f.calls.some(x => x.source === cancelledSource), false, 'pruned queued job never invokes helper'); + assert.ok(f.peak <= 4); assert.equal(f.cache(cancelledSource), null); + }], + ['deferred-teardown-precedes-next-slot', async f => { + const active = f.feed(Array.from({ length: 4 }, magnet)); active.show(); + const queued = f.feed([magnet()]); queued.show(); + f.torrents[0].wire(); await turn(); + assert.equal(f.calls.length, 4, 'slot retained until delayed destroy'); + assert.equal(f.snapshot().timers.teardown, 1); + f.clock.tick(0); await turn(); assert.equal(f.calls.length, 5); assert.equal(f.peak, 4); + const destroyIndex = f.timeline.findIndex(x => x[0] === 'destroy'); + assert.equal(f.timeline[destroyIndex + 1][0], 'add'); + }], + ['late-observer-disposed-guard', async f => { + const old = f.feed([magnet()]); old.show(); old.dispose(); + const before = old.events.length; old.observer.show(); f.torrents[0].wire(); await f.drain(); + assert.equal(old.events.length, before); assert.equal(f.calls.length, 1); + assert.equal(old.cards[0].dataset.streamHealthState, 'checking'); + }], + ['old-callbacks-cannot-affect-replacement', async f => { + const source = magnet(), old = f.feed([source]); old.show(); + const wire = f.torrents[0].listeners('wire')[0]; + const error = f.torrents[0].listeners('error')[0]; + const timers = [...f.clock.jobs.values()].map(job => job.fn); + old.dispose(); + assert.equal(f.calls[0].lifecycle.cancelled, true, 'cancelled identity unavailable synchronously'); + const replacement = f.feed([source]); replacement.show(); + await f.drain(); + wire(); error(new Error('late')); timers.forEach(fn => fn()); await f.drain(); + const shared = f.feed([source]); shared.show(); + assert.equal(f.calls.length, 2, 'old finalizer must not delete replacement identity'); + assert.equal(f.cache(source), null); + assert.equal(replacement.cards[0].dataset.streamHealthState, 'checking'); + f.torrents[1].wire(); await f.drain(); + assert.equal(f.writes.length, 1, 'only the new live result is cached'); + assert.equal(replacement.cards[0].dataset.streamHealthState, 'healthy'); + assert.equal(shared.cards[0].dataset.streamHealthState, 'healthy'); + assert.equal(old.cards[0].dataset.streamHealthState, 'checking'); + }], + ['repeated-release-and-noncooperative-io', async f => { + const live = f.feed([magnet()]); live.show(); + const cancel = f.calls[0].lifecycle.cancelActive; + const lateWire = f.torrents[0].listeners('wire')[0]; + live.dispose(); live.dispose(); cancel(); cancel(); + // No fake transport completion or abort event is required to settle. + await f.drain(); + assert.equal(f.calls[0].settled, true); assert.equal(f.calls[0].result, null); + assert.equal(f.torrents[0].destroyCount, 1); + lateWire(); cancel(); await f.drain(); + assert.equal(f.calls[0].result, null); assert.equal(f.torrents[0].destroyCount, 1); + }], + ['cancel-before-probe-start', async f => { + const lifecycle = { cancelled: true, owners: new Set() }; + const promise = f.probe(magnet(), lifecycle); await f.drain(); + assert.equal(f.calls[0].settled, true); assert.equal(await promise, null); + assert.equal(f.torrents.length, 0); assert.equal(torrentClient.probeClient, null); + assert.equal(f.clock.jobs.size, 0); + }], + ['cancel-during-client-construction', async f => { + const live = f.feed([magnet()]); + f.config.onConstruct = () => live.dispose(); live.show(); await f.drain(); + assert.equal(f.calls[0].settled, true); assert.equal(f.calls[0].result, null); + assert.equal(f.torrents.length, 0); assert.equal(f.clock.jobs.size, 0); + assert.equal(f.calls[0].lifecycle.cancelActive, null); + }], + ['cancel-during-add-defers-destroy', async f => { + const source = magnet(), live = f.feed([source]); + f.config.onAdd = () => live.dispose(); live.show(); + assert.equal(f.calls[0].lifecycle.cancelled, true); + assert.equal(f.calls[0].settled, false); + assert.equal(f.torrents[0].destroyCount, 0); + assert.equal(f.clock.counts().timeout, 0); assert.equal(f.clock.counts().poll, 0); + f.torrents[0].error(); // Noncooperative IO can report an error before deferred destruction. + await f.drain(); + assert.equal(f.calls[0].settled, true); assert.equal(f.calls[0].result, null); + assert.equal(f.torrents[0].destroyCount, 1); + assert.equal(f.torrents[0].destroyedDuringAdd, false); assert.equal(f.cache(source), null); + }], + ['same-source-owner-registers-during-add', async f => { + const source = magnet(), first = f.feed([source]); + let shared; + f.config.onAdd = () => { + f.config.onAdd = null; + shared = f.feed([source]); shared.show(); first.dispose(); + }; + first.show(); assert.equal(f.calls.length, 1); + assert.equal(f.calls[0].lifecycle.cancelled, false); + f.torrents[0].wire(); await f.drain(); + assert.equal(shared.cards[0].dataset.streamHealthState, 'healthy'); + assert.equal(first.cards[0].dataset.streamHealthState, 'checking'); + }], + ['cancel-on-wire-unwind-before-destroy', async f => { + const live = f.feed([magnet()]); live.show(); + f.torrents[0].on('wire', () => live.dispose()); + f.torrents[0].wire(); + assert.equal(f.torrents[0].destroyCount, 0); + await f.drain(); + assert.equal(f.calls[0].settled, true); assert.equal(f.calls[0].result, null); + assert.equal(f.torrents[0].destroyedDuringEvent, false); assert.equal(f.writes.length, 0); + }], + ['cancel-on-error-unwind-before-destroy', async f => { + const live = f.feed([magnet()]); live.show(); + f.torrents[0].on('error', () => live.dispose()); + f.torrents[0].error(); + assert.equal(f.torrents[0].destroyCount, 0); + await f.drain(); + assert.equal(f.calls[0].result, null); assert.equal(f.writes.length, 0); + assert.equal(f.torrents[0].destroyedDuringEvent, false); + }], + ['throwing-destroy-still-settles-and-cleans-own-listeners', async f => { + const live = f.feed([magnet()]); live.show(); + f.config.throwDestroy = true; live.dispose(); await f.drain(); + assert.equal(f.calls[0].settled, true); assert.equal(f.calls[0].result, null); + assert.equal(f.torrents[0].destroyCount, 1); + assert.equal(f.torrents[0].listenerCount('wire'), 0); + assert.equal(f.torrents[0].listenerCount('error'), 0); + assert.equal(f.calls[0].lifecycle.cancelActive, null); + }], + ['standalone-ownerless-caller-stays-live', async f => { + const source = magnet(), promise = f.probe(source); + assert.equal(f.calls[0].lifecycle, undefined); + f.torrents[0].wire(); await f.drain(); assert.equal(f.calls[0].settled, true); + const result = await promise; + assert.equal(result.healthy, true); assert.equal(result.reason, 'peer'); + assert.equal(f.torrents[0].destroyCount, 1); + }], + ['synchronous-wire-listener-registration', async f => { + f.config.syncEvent = 'wire'; const promise = f.probe(magnet()); + assert.equal(f.torrents[0].destroyCount, 0); + await f.drain(); assert.equal(f.calls[0].settled, true); + assert.equal((await promise).healthy, true); assert.equal(f.clock.jobs.size, 0); + }], + ['synchronous-error-listener-registration', async f => { + f.config.syncEvent = 'error'; const promise = f.probe(magnet()); + await f.drain(); assert.equal(f.calls[0].settled, true); + assert.equal((await promise).reason, 'error'); assert.equal(f.clock.jobs.size, 0); + }], + ['add-error-cleans-hook-and-keeps-shared-client', async f => { + const lifecycle = { cancelled: false, owners: new Set([{}]) }; + f.config.throwAdd = true; const promise = f.probe(magnet(), lifecycle); + await f.drain(); assert.equal(f.calls[0].settled, true); + assert.equal((await promise).reason, 'error'); assert.equal(lifecycle.cancelActive, null); + assert.equal(f.torrents.length, 0); assert.equal(f.clock.jobs.size, 0); + const client = torrentClient.probeClient; + f.config.throwAdd = false; const next = f.probe(magnet()); + f.torrents[0].wire(); await f.drain(); assert.equal(f.calls[1].settled, true); + assert.equal((await next).healthy, true); assert.equal(torrentClient.probeClient, client); + }], + ['missing-AbortController-still-cancels', async f => { + globalThis.AbortController = undefined; + const source = magnet(), live = f.feed([source]); live.show(); live.dispose(); + await f.drain(); assert.equal(f.calls[0].settled, true); + assert.equal(f.calls[0].result, null); assert.equal(f.cache(source), null); + assert.equal(f.clock.jobs.size, 0); assert.equal(f.torrents[0].destroyCount, 1); + }], + ['error-and-throwing-teardown-release-queued-capacity-once', async f => { + const active = f.feed(Array.from({ length: 4 }, magnet)); active.show(); + const source = magnet(), queued = f.feed([source]); queued.show(); + f.config.throwDestroy = true; + f.torrents[0].error(); await turn(); + assert.equal(f.calls.length, 4, 'error result still holds slot until teardown'); + f.clock.tick(0); await turn(); + assert.equal(f.calls.length, 5); assert.equal(f.torrents[0].destroyCount, 1); + assert.equal(f.torrents[0].listenerCount('error'), 0); + f.config.throwDestroy = false; + f.torrents[4].wire(); await f.drain(); + assert.equal(queued.cards[0].dataset.streamHealthState, 'healthy'); assert.equal(f.peak, 4); + }] +]; + +for (const [name, scenario] of cases) { + test(name, async t => { await scenario(fixture(t)); }); +} diff --git a/tests/grid-health-lifecycle.test.mjs b/tests/grid-health-lifecycle.test.mjs index f6bd78bb..f757f17a 100644 --- a/tests/grid-health-lifecycle.test.mjs +++ b/tests/grid-health-lifecycle.test.mjs @@ -369,13 +369,13 @@ test("active probe remains shared while disposed owners and late observer entrie const source = magnet(); const first = f.feed([source]); first.observer.show(); - first.dispose(); const liveUpdates = []; const live = f.feed([source], { onUpdate: (event) => liveUpdates.push(event) }); + live.observer.show(); // Retain a live owner BEFORE releasing the first. + first.dispose(); first.observer.show(); // An already-delivered entry may arrive after disconnect. - live.observer.show(); assert.equal( liveUpdates.some((event) => event.card === first.cards[0]), false, @@ -414,7 +414,7 @@ test("repeated old disposal cannot cancel a reattached live registration", async assert.equal(renewed.cards[0].dataset.streamHealthState, "healthy"); }); -test("disposed active completion remains cached for a later live owner", async (t) => { +test("disposed active completion cannot cache and a later owner requests fresh work", async (t) => { const f = fixture(t); const source = magnet(); const old = f.feed([source]); @@ -427,10 +427,15 @@ test("disposed active completion remains cached for a later live owner", async ( live.observer.show(); assert.equal( f.calls.length, - 1, - "ownerless active completion must retain its healthy cache result" + 2, + "ownerless active completion must not replace a fresh probe" ); + assert.equal(readTorrentProbeFromStorage(source.slice(-40)), null); + assert.equal(live.cards[0].dataset.streamHealthState, "checking"); + f.calls[1].finish(); + await flush(); assert.equal(live.cards[0].dataset.streamHealthState, "healthy"); + assert.equal(readTorrentProbeFromStorage(source.slice(-40)).value.healthy, true); }); test("completed healthy and negative probes retain existing cache TTL behavior", async (t) => { diff --git a/todo/TODO_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md b/todo/TODO_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md new file mode 100644 index 00000000..917a5ac9 --- /dev/null +++ b/todo/TODO_2026-10-26_18-55-00_client-reliability-9-torrent-implementation.md @@ -0,0 +1,7 @@ +- [x] Read exact dispatch routing and newest rules/current tree. +- [x] Write explicit spec correction and integrity note before superseded expectations. +- [ ] Implement narrow grid ownership and optional helper lifecycle. +- [ ] Focused real-chain/helper tests, edge callbacks, shared/live/legacy/queue controls. +- [ ] Every new scenario rejects a deliberate restored mutant. +- [ ] Targeted lint and evidence/READY handoff. +- [ ] Later full/build/browser/normal landing under separate resource grant. diff --git a/todo/TODO_2026-10-26_19-07-50_client-reliability-9-ready.md b/todo/TODO_2026-10-26_19-07-50_client-reliability-9-ready.md new file mode 100644 index 00000000..0a3f9100 --- /dev/null +++ b/todo/TODO_2026-10-26_19-07-50_client-reliability-9-ready.md @@ -0,0 +1,6 @@ +- [x] Resume rules/mailbox/item9 claim and saved candidate review. +- [x] Four candidate hashes exactly match saved focused/mutant evidence; no repeat baseline/tests. +- [x] Record thermal hold and READY scope/validation limits. +- [ ] Commit named files via fleet; merge unstable without rebase; inspect runtime equality. +- [ ] Dispatch fresh resource grant for remaining lint/full/build/browser/submission. +- [ ] Normal queue durable landing plus unstable ancestry before closing item9. diff --git a/todo/TODO_2026-10-26_19-15-00_client-reliability-9-restart.md b/todo/TODO_2026-10-26_19-15-00_client-reliability-9-restart.md new file mode 100644 index 00000000..fd142e62 --- /dev/null +++ b/todo/TODO_2026-10-26_19-15-00_client-reliability-9-restart.md @@ -0,0 +1,8 @@ +- [x] Narrow implementation and explicit spec/integrity correction preserved. +- [x] Final focused6files60/60/0cancelled. +- [x] 19unique mutants killed; all27newcases covered, no surviving variants. +- [x] Targetedlint4pass; sandboxhexEPERM plus unchangedhostpass retained. +- [x] Durable candidate/log/mutant snapshots+manifest saved; SAFE TO RESTART. +- [ ] Resume: review final delta/notes; finish READY and commit named paths. +- [ ] Merge currentunstable (never rebase), verify runtime equality/checks. +- [ ] Explicit grant for remaining lint/full/build/browser/submission; durable landing/ancestry before closure. From c20635bc8539328ca1677f3cf63cbe870adeb9c2 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Mon, 26 Oct 2026 15:09:00 -0400 Subject: [PATCH 5/6] docs: checkpoint client-reliability-9 merged candidate and resource hold --- docs/TODO.md | 2 ++ docs/agents/backlog/client-reliability-9.json | 2 +- ...026-10-26_19-08-50_client-reliability-9-merged-ready.md | 7 +++++++ ...026-10-26_19-08-50_client-reliability-9-merged-ready.md | 5 +++++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test_logs/TEST_LOG_2026-10-26_19-08-50_client-reliability-9-merged-ready.md create mode 100644 todo/TODO_2026-10-26_19-08-50_client-reliability-9-merged-ready.md diff --git a/docs/TODO.md b/docs/TODO.md index 9083df4d..9c1d5de1 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -80,6 +80,8 @@ ## client-reliability +- 2026-10-26 resumed item9 active-torrent candidate `1b2362d2`, merged unstable `04c8c7cf` at `1bf50c1f`; exact saved hashes/focused60/60/19distinct killed mutants preserved. Remaining full lint/full/build/browser/normal landing require dispatch slot plus fresh health; TCPU97.1C at19:07:29 exceeds85C. No new tests or submission. Hold recorded and blocker mailed; real peers/byte teardown/wholeStage3 unverified. Evidence: test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md. + - 2026-10-20: item6 DONE: retained actual profile-history wiring regression landed b3fab032;normal gate exit0 with431 discovered/431 unique file starts,focused38/38,5 killed mutants,lint11/11,submitted ancestry0. Test-only,existing product behavior passes. Evidence test_logs/TEST_LOG_2026-10-20_15-41-00_client-reliability-6-landed.md. Real signers/relays/encryption/full-app modal/browser/build/synced Clear unverified. Expensive slot released;IDLE for owner local review,no optional work. - 2026-10-20: item6 test-only retention ready:new real-profile wiring3/3,focused5files/38scenarios,5 isolated runtime mutants failnaturally/0cancelled,lint11pass. Local remove/lastitem/clear/recreation andfake-synced reduced+empty replacement covered;historicalno-op rejected. No product/existing suite edits;full/normal slot pendingexplicit grant,full/browser/build unrun;real signers/relays/fullapp/syncedClear unverified. Unique integrity/evidence in test_logs/*client-reliability-6*. diff --git a/docs/agents/backlog/client-reliability-9.json b/docs/agents/backlog/client-reliability-9.json index 82ea5053..bc29531f 100644 --- a/docs/agents/backlog/client-reliability-9.json +++ b/docs/agents/backlog/client-reliability-9.json @@ -7,5 +7,5 @@ "addedOn": "2026-10-22", "filedAt": "fb54cea3a2ba99b4860421724a5050af6b97c293", "brief": "docs/agents/CAMPAIGN-2026-10-22.md", - "evidence": "HEAD-only fix e9c960ed/merged09f52bdd durably landed f41ac656 normalgateexit0,435discovered/435unique starts missingextra0,ancestry0;build/artifactexit0;controlled native Chromium+Firefox lifecycle PASS with synthetic loadeddata/publicdeny. Prior60focused/16mutants/lint11. Resources released. HLS/torrent/RangeGET separately OPEN; no wholeStage3 claim. test_logs/TEST_LOG_2026-10-22_20-52-00_client-reliability-9-browser.md HLS read-only atd04d501e:12modes/7controls pass/5cancellationfail/0cancelled/naturalexit1; GET/body finalowner retains timer/unsettled,rejoin old,latecache. Await explicit controller+HLShelper routing. test_logs/TEST_LOG_2026-10-22_20-54-00_client-reliability-9-hls-investigation.md HLS explicitlyrouted20:55:13Z;minimal controllerhandoff+helperfetch/bodycancel implemented;new35+existing94=129pass/6files,19isolatedmutantsnaturallyfail/cancelled0,lint11exit0;noexistingtestsmodified. READY for serialized full/build/browser/normal slot after candidatecommit/merge; notsubmitted. test_logs/TEST_LOG_2026-10-22_21-03-00_client-reliability-9-hls-ready.md 2026-10-26 active-torrent investigation at e9af76df: actual grid observer/queue/probePeers fake WebTorrent IO+clock; corrected scratch12=7pass/5fail/naturalexit1/allcleanup0/network0. Final-owner retains1torrent/2listeners/timeout+poll/unsettled, same-turn+later joins obsolete probe, latecache and occupied FIFO capacity; shared/live-wire/error/timeout/queued-priority/deferred-teardown/staleobserver controls pass. Existing lifecycle11/11 unchanged naturalexit0. First JSDOM timer-confounded12=5pass/7fail preserved; IO-isolated correction documented. Proposed gridHealth+probePeers optional lifecycle ONLY, needs explicit routing/spec correction for prior active-sharing/cache assertions; no product/test edits/full/build/browser/submission. test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md" + "evidence": "HEAD-only fix e9c960ed/merged09f52bdd durably landed f41ac656 normalgateexit0,435discovered/435unique starts missingextra0,ancestry0;build/artifactexit0;controlled native Chromium+Firefox lifecycle PASS with synthetic loadeddata/publicdeny. Prior60focused/16mutants/lint11. Resources released. HLS/torrent/RangeGET separately OPEN; no wholeStage3 claim. test_logs/TEST_LOG_2026-10-22_20-52-00_client-reliability-9-browser.md HLS read-only atd04d501e:12modes/7controls pass/5cancellationfail/0cancelled/naturalexit1; GET/body finalowner retains timer/unsettled,rejoin old,latecache. Await explicit controller+HLShelper routing. test_logs/TEST_LOG_2026-10-22_20-54-00_client-reliability-9-hls-investigation.md HLS explicitlyrouted20:55:13Z;minimal controllerhandoff+helperfetch/bodycancel implemented;new35+existing94=129pass/6files,19isolatedmutantsnaturallyfail/cancelled0,lint11exit0;noexistingtestsmodified. READY for serialized full/build/browser/normal slot after candidatecommit/merge; notsubmitted. test_logs/TEST_LOG_2026-10-22_21-03-00_client-reliability-9-hls-ready.md 2026-10-26 active-torrent investigation at e9af76df: actual grid observer/queue/probePeers fake WebTorrent IO+clock; corrected scratch12=7pass/5fail/naturalexit1/allcleanup0/network0. Final-owner retains1torrent/2listeners/timeout+poll/unsettled, same-turn+later joins obsolete probe, latecache and occupied FIFO capacity; shared/live-wire/error/timeout/queued-priority/deferred-teardown/staleobserver controls pass. Existing lifecycle11/11 unchanged naturalexit0. First JSDOM timer-confounded12=5pass/7fail preserved; IO-isolated correction documented. Proposed gridHealth+probePeers optional lifecycle ONLY, needs explicit routing/spec correction for prior active-sharing/cache assertions; no product/test edits/full/build/browser/submission. test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md 2026-10-26 resumed active-torrent candidate1b2362d2 merged unstable04c8c7cf at1bf50c1f; four candidate hashes exactly match durable focused60/60/fail0/cancelled0 and19unique killed mutants/20variant executions/all27newcase map. No runtime validation-input change on merge. Four targeted lint passes only; full lint/full/build/browser/normal queue pending explicit dispatch resource grant; health19:07:29 TCPU97.1C exceeds85C. No new tests/repeated baseline/submission. test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md" } diff --git a/test_logs/TEST_LOG_2026-10-26_19-08-50_client-reliability-9-merged-ready.md b/test_logs/TEST_LOG_2026-10-26_19-08-50_client-reliability-9-merged-ready.md new file mode 100644 index 00000000..6cdbe88b --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_19-08-50_client-reliability-9-merged-ready.md @@ -0,0 +1,7 @@ +# Merged candidate READY checkpoint + +- Fleet commit produced `1b2362d2341414e69f67352e17529ed5dfedd45e` with named paths and no submission. +- Initial sandbox `git merge --no-edit unstable` failed: ORIG_HEAD.lock read-only filesystem. No reset/rewrite attempted. Same merge approved via host escalation, exit0, resulting `1bf50c1f7a55740aa1d1582045cd88033a8de56e` against unstable `04c8c7cf61eed29424f561297ef49c6cdfa91a0a`. +- Postmerge `git status --short --branch`: clean area/client-reliability. `git diff 1b2362d2 HEAD -- js tests config package.json package-lock.json`: exit0/empty. `git diff --check`: exit0. No new validation input changes; saved focused and mutant evidence preserved without repeat. +- Dispatch blocker/READY message delivered via MCP at19:08:37; hold recorded and progress checkpoint written. Heavy clearance pending fresh health and explicit serialized slot; no full/build/browser/submission/landing. +- Prior focused60/60 and19unique killed mutants are saved evidence, not new runs. Full lint and live/real transport qualification remain open. diff --git a/todo/TODO_2026-10-26_19-08-50_client-reliability-9-merged-ready.md b/todo/TODO_2026-10-26_19-08-50_client-reliability-9-merged-ready.md new file mode 100644 index 00000000..5fcbb992 --- /dev/null +++ b/todo/TODO_2026-10-26_19-08-50_client-reliability-9-merged-ready.md @@ -0,0 +1,5 @@ +- [x] Candidate committed1b2362d2 and unstable04c8c7cf merged at1bf50c1f; source inputs unchanged. +- [x] Saved60focused/19distinct killed mutants hashes verified; no baseline/test repeat. +- [x] Thermal hold/progress and dispatch blocker delivered; backlog and area TODO current. +- [ ] Explicit fresh resource grant for remaining full lint/full/build/browser/submission. +- [ ] Durable normal-gate landing and target ancestry before closing item9. From fd31797bd5138260264aee60e5a9efacce258e9f Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN Date: Mon, 26 Oct 2026 15:16:39 -0400 Subject: [PATCH 6/6] docs: preserve client-reliability-9 thermal gate interruption Retain strict partial 275/438 starts, rejected queue result and full lint11 pass. No product changes, gate changes, retry or landing claim; renewed resource slot required. --- docs/TODO.md | 2 ++ docs/agents/backlog/client-reliability-9.json | 2 +- ...OG_2026-10-26_19-12-00_client-reliability-9-lint.md | 7 +++++++ ...-16-00_client-reliability-9-thermal-interruption.md | 10 ++++++++++ ...10-26_19-16-00_client-reliability-9-thermal-hold.md | 5 +++++ 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test_logs/TEST_LOG_2026-10-26_19-12-00_client-reliability-9-lint.md create mode 100644 test_logs/TEST_LOG_2026-10-26_19-16-00_client-reliability-9-thermal-interruption.md create mode 100644 todo/TODO_2026-10-26_19-16-00_client-reliability-9-thermal-hold.md diff --git a/docs/TODO.md b/docs/TODO.md index 9c1d5de1..3063057f 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -80,6 +80,8 @@ ## client-reliability +- 2026-10-26 19:16UTC: item9 full lint11PASS; normal queue c20635bc interrupted for sustained90.1C→86C over38s. Durable rejected/red exit1, unstable04c8c7cf unchanged, not landed. Partial275/438starts/275unique,163notstarted; original log/result preserved in state/evidence/client9-torrent-validation-20261026. Slot RELEASED, fresh resource+new gate grant required; no auto-resubmit/build/browser. Evidence test_logs/TEST_LOG_2026-10-26_19-16-00_client-reliability-9-thermal-interruption.md. + - 2026-10-26 resumed item9 active-torrent candidate `1b2362d2`, merged unstable `04c8c7cf` at `1bf50c1f`; exact saved hashes/focused60/60/19distinct killed mutants preserved. Remaining full lint/full/build/browser/normal landing require dispatch slot plus fresh health; TCPU97.1C at19:07:29 exceeds85C. No new tests or submission. Hold recorded and blocker mailed; real peers/byte teardown/wholeStage3 unverified. Evidence: test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md. - 2026-10-20: item6 DONE: retained actual profile-history wiring regression landed b3fab032;normal gate exit0 with431 discovered/431 unique file starts,focused38/38,5 killed mutants,lint11/11,submitted ancestry0. Test-only,existing product behavior passes. Evidence test_logs/TEST_LOG_2026-10-20_15-41-00_client-reliability-6-landed.md. Real signers/relays/encryption/full-app modal/browser/build/synced Clear unverified. Expensive slot released;IDLE for owner local review,no optional work. diff --git a/docs/agents/backlog/client-reliability-9.json b/docs/agents/backlog/client-reliability-9.json index bc29531f..e8a8d2da 100644 --- a/docs/agents/backlog/client-reliability-9.json +++ b/docs/agents/backlog/client-reliability-9.json @@ -7,5 +7,5 @@ "addedOn": "2026-10-22", "filedAt": "fb54cea3a2ba99b4860421724a5050af6b97c293", "brief": "docs/agents/CAMPAIGN-2026-10-22.md", - "evidence": "HEAD-only fix e9c960ed/merged09f52bdd durably landed f41ac656 normalgateexit0,435discovered/435unique starts missingextra0,ancestry0;build/artifactexit0;controlled native Chromium+Firefox lifecycle PASS with synthetic loadeddata/publicdeny. Prior60focused/16mutants/lint11. Resources released. HLS/torrent/RangeGET separately OPEN; no wholeStage3 claim. test_logs/TEST_LOG_2026-10-22_20-52-00_client-reliability-9-browser.md HLS read-only atd04d501e:12modes/7controls pass/5cancellationfail/0cancelled/naturalexit1; GET/body finalowner retains timer/unsettled,rejoin old,latecache. Await explicit controller+HLShelper routing. test_logs/TEST_LOG_2026-10-22_20-54-00_client-reliability-9-hls-investigation.md HLS explicitlyrouted20:55:13Z;minimal controllerhandoff+helperfetch/bodycancel implemented;new35+existing94=129pass/6files,19isolatedmutantsnaturallyfail/cancelled0,lint11exit0;noexistingtestsmodified. READY for serialized full/build/browser/normal slot after candidatecommit/merge; notsubmitted. test_logs/TEST_LOG_2026-10-22_21-03-00_client-reliability-9-hls-ready.md 2026-10-26 active-torrent investigation at e9af76df: actual grid observer/queue/probePeers fake WebTorrent IO+clock; corrected scratch12=7pass/5fail/naturalexit1/allcleanup0/network0. Final-owner retains1torrent/2listeners/timeout+poll/unsettled, same-turn+later joins obsolete probe, latecache and occupied FIFO capacity; shared/live-wire/error/timeout/queued-priority/deferred-teardown/staleobserver controls pass. Existing lifecycle11/11 unchanged naturalexit0. First JSDOM timer-confounded12=5pass/7fail preserved; IO-isolated correction documented. Proposed gridHealth+probePeers optional lifecycle ONLY, needs explicit routing/spec correction for prior active-sharing/cache assertions; no product/test edits/full/build/browser/submission. test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md 2026-10-26 resumed active-torrent candidate1b2362d2 merged unstable04c8c7cf at1bf50c1f; four candidate hashes exactly match durable focused60/60/fail0/cancelled0 and19unique killed mutants/20variant executions/all27newcase map. No runtime validation-input change on merge. Four targeted lint passes only; full lint/full/build/browser/normal queue pending explicit dispatch resource grant; health19:07:29 TCPU97.1C exceeds85C. No new tests/repeated baseline/submission. test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md" + "evidence": "HEAD-only fix e9c960ed/merged09f52bdd durably landed f41ac656 normalgateexit0,435discovered/435unique starts missingextra0,ancestry0;build/artifactexit0;controlled native Chromium+Firefox lifecycle PASS with synthetic loadeddata/publicdeny. Prior60focused/16mutants/lint11. Resources released. HLS/torrent/RangeGET separately OPEN; no wholeStage3 claim. test_logs/TEST_LOG_2026-10-22_20-52-00_client-reliability-9-browser.md HLS read-only atd04d501e:12modes/7controls pass/5cancellationfail/0cancelled/naturalexit1; GET/body finalowner retains timer/unsettled,rejoin old,latecache. Await explicit controller+HLShelper routing. test_logs/TEST_LOG_2026-10-22_20-54-00_client-reliability-9-hls-investigation.md HLS explicitlyrouted20:55:13Z;minimal controllerhandoff+helperfetch/bodycancel implemented;new35+existing94=129pass/6files,19isolatedmutantsnaturallyfail/cancelled0,lint11exit0;noexistingtestsmodified. READY for serialized full/build/browser/normal slot after candidatecommit/merge; notsubmitted. test_logs/TEST_LOG_2026-10-22_21-03-00_client-reliability-9-hls-ready.md 2026-10-26 active-torrent investigation at e9af76df: actual grid observer/queue/probePeers fake WebTorrent IO+clock; corrected scratch12=7pass/5fail/naturalexit1/allcleanup0/network0. Final-owner retains1torrent/2listeners/timeout+poll/unsettled, same-turn+later joins obsolete probe, latecache and occupied FIFO capacity; shared/live-wire/error/timeout/queued-priority/deferred-teardown/staleobserver controls pass. Existing lifecycle11/11 unchanged naturalexit0. First JSDOM timer-confounded12=5pass/7fail preserved; IO-isolated correction documented. Proposed gridHealth+probePeers optional lifecycle ONLY, needs explicit routing/spec correction for prior active-sharing/cache assertions; no product/test edits/full/build/browser/submission. test_logs/TEST_LOG_2026-10-26_15-25-00_client-reliability-9-torrent-investigation.md 2026-10-26 resumed active-torrent candidate1b2362d2 merged unstable04c8c7cf at1bf50c1f; four candidate hashes exactly match durable focused60/60/fail0/cancelled0 and19unique killed mutants/20variant executions/all27newcase map. No runtime validation-input change on merge. Four targeted lint passes only; full lint/full/build/browser/normal queue pending explicit dispatch resource grant; health19:07:29 TCPU97.1C exceeds85C. No new tests/repeated baseline/submission. test_logs/TEST_LOG_2026-10-26_19-07-50_client-reliability-9-resumed-ready.md 2026-10-26 full lint11pass; normal queue c20635bc thermally interrupted at275/438starts (275unique/163neverstarted), durable rejected/red exit1 at19:15:32, unstable04c8c7cf unchanged. Sustained90.1C\u219286C38s; approved SIGINT only verified owned gate group204078. Partial/result uniquely preserved state/evidence/client9-torrent-validation-20261026; RELEASE sent, renewed dispatch resource+gate grant required/no automatic resubmit. test_logs/TEST_LOG_2026-10-26_19-16-00_client-reliability-9-thermal-interruption.md" } diff --git a/test_logs/TEST_LOG_2026-10-26_19-12-00_client-reliability-9-lint.md b/test_logs/TEST_LOG_2026-10-26_19-12-00_client-reliability-9-lint.md new file mode 100644 index 00000000..3ff9a7ef --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_19-12-00_client-reliability-9-lint.md @@ -0,0 +1,7 @@ +# Client9 exclusive lint stage + +- Dispatch exclusive slot19:10:24 after QA RELEASE19:09:25.820; source review accepted. HEADc20635bc (product1b2362d2, merged1bf50c1f), source unchanged. No baseline/focused repeat. +- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD npm run lint > state/evidence/client9-torrent-validation-20261026/lint-sandbox-1911.log 2>&1`: exit2 after css pass at hex subprocess spawnSync git EPERM. Preserved environmental failure. +- Identical approved host command with output lint-host-1911.log: natural exit0; all11 lint checks pass. No lint suppression/baseline/config changes. +- Fresh health19:11:15 OK/max<75C/load0.9/RAM64.1%/swap-in0;19:11:48 OK/max76.1C/load1.16/RAM65.1%/swap-in0. Earlier transient91.1C19:10:39 retained; no work ran then. Hold cleared, START delivered19:11:24. +- Submit current committedc20635bc to unchanged normal queue; this uncommitted log is evidence only and does not change candidate. No build/browser grant; live peers/byte teardown/playback/CPU/wholeStage3 unverified. diff --git a/test_logs/TEST_LOG_2026-10-26_19-16-00_client-reliability-9-thermal-interruption.md b/test_logs/TEST_LOG_2026-10-26_19-16-00_client-reliability-9-thermal-interruption.md new file mode 100644 index 00000000..4608d3d1 --- /dev/null +++ b/test_logs/TEST_LOG_2026-10-26_19-16-00_client-reliability-9-thermal-interruption.md @@ -0,0 +1,10 @@ +# Client9 normal-gate thermal interruption + +- Committed candidate/submission `c20635bc8539328ca1677f3cf63cbe870adeb9c2`; product1b2362d2/merge1bf50c1f, normal queue START19:12:41. No runner/gate/assertion changes or separate full run. +- Required full lint11/11 passed via approved host route; original sandbox hex spawnSync git EPERM retained. See lint-stage log. +- Health sequence during gate:19:13:35 max87.1C;19:13:51 max87.1C;19:14:05 max83.8C;19:14:40 max90.1C/load12.77;19:15:18 max86C/load13.5. Final two hot samples span38s; thermal threshold85C sustained. No claim heat is caused exclusively by this job or other apps. +- Host inspection verified gate process group204078, parentlander204041, cwd bitvid-lander and timeout1800s. Approved SIGINT only that group19:15:32. No unrelated process stopped. This is an interrupted run, not a natural full pass or a product assertion failure. +- Durable `land_status c20635bc`: rejected/red, unchanged normal gate exit1 at19:15:32.782; lander false. `git rev-parse HEAD unstable`: c20635bc /04c8c7cf61eed29424f561297ef49c6cdfa91a0a. Not landed; no ancestry-success claim. +- Independent runner-equivalent discovery438; partial starts275/unique275/unexpected0, last tests/settings-restore-prompt.test.mjs,163neverstarted. Last started file has no completion evidence. No actual not-ok or nonzero fail/cancelled lines in preserved partial log; not an all-suite result. +- Complete partial log/result copied before any next run to state/evidence/client9-torrent-validation-20261026/test_unit-interrupted-1915.log and result-c20635bc-interrupted-1915.json, hashed in manifest-1915.sha256. Both lint logs also retained there. +- RELEASE and material hold delivered dispatch19:15:58. New explicit hold: dispatch fresh thermal/resource clearance and renewed exclusive slot; NO automatic resubmission. Next light work evidence/discovery review; source unchanged. No build/browser grant, real transport/peer/playback/CPU/wholeStage3 qualification. diff --git a/todo/TODO_2026-10-26_19-16-00_client-reliability-9-thermal-hold.md b/todo/TODO_2026-10-26_19-16-00_client-reliability-9-thermal-hold.md new file mode 100644 index 00000000..95573339 --- /dev/null +++ b/todo/TODO_2026-10-26_19-16-00_client-reliability-9-thermal-hold.md @@ -0,0 +1,5 @@ +- [x] Source-reviewed candidate and full lint11 pass. +- [x] ONE normal queue attempt; preserve interrupted275/438 log and rejected result, no retry. +- [x] RELEASE exclusive slot and record dispatch thermal hold. +- [ ] Fresh thermal/resource clearance plus new dispatch gate grant. +- [ ] Unchanged full gate durable landing/ancestry; then separately granted build/browser follow-up.