[client-reliability] client-reliability-9 cancel ownerless active HEAD probes

This commit is contained in:
thePR0M3TH3AN committed 2026-10-22 10:26:08 -04:00
1 parent e21be27f34
commit e9c960edcf
7 files changed
+654 -10

No files matched your search

@@ -0,0 +1,73 @@
# HEAD lifecycle integrity
```yaml
test_integrity_note:
change_type: ["new_tests", "spec_correction"]
scenarios:
- id: SCN-head-final-owner
given: "actual observer/controller HEAD with abortable, ignoring-abort or missing AbortController transport"
when: "final owner disposes, including duplicate disposal and already-completed HEAD boundary"
then: "prompt null settlement, timer cleanup, no cache/media/mirror/stale badge; abort if supported"
- id: SCN-head-replacement
given: "same-turn or later rejoin after disposal"
when: "obsolete success, error or timeout callback runs"
then: "fresh HEAD and inflight identity preserved, fresh healthy result only reaches live badge"
- id: SCN-head-sharing
given: "same-controller, cross-controller or legacy live survivor"
when: "other observer disposes then HEAD/media completes"
then: "one un-aborted HEAD, survivor gets healthy cache/badge, disposed badge unchanged"
- id: SCN-head-live-fallback
given: "live HEAD success/error/timeout/opaque/405 or failing media and mirror"
when: "controlled transport/media settles"
then: "healthy fallback or honest offline cache, timers/media slots released"
- id: SCN-head-handoff-fifo
given: "HEAD transitioning to media or saturated real media queue"
when: "owner leaves or live media releases slots"
then: "new media cancellation hook works, live FIFO and cap3 remain intact"
- id: SCN-head-before-start
given: "lifecycle already cancelled or without owners"
when: "real probeUrl entry is called"
then: "cancelled result, no fetch/media/timer"
observable_outcomes:
- "fetch count/AbortSignal, settled value, timer/source/listener cleanup"
- "real cache/inflight identity, live/disposed badges and media queue/FIFO"
determinism_controls:
- "controlled fetch with native AbortSignal and optional ignored abort"
- "manually driven positive-delay timers, native zero-delay JSDOM tasks"
- "actual observer/controller/cache/DOM media events; external network never used"
- "cleanup completes controlled transports/media and restores globals before natural exit"
anti_cheat_rationale:
prevents:
- "abort signal without prompt settlement"
- "null-only fake fix retaining transport or timer"
- "reuse of obsolete request or cache-on-cancel"
- "dropping shared/legacy owners or fallback/FIFO behavior"
- "stale inflight finalizer deleting fresh work"
- "retry/sleep/assertion relaxation"
relaxation:
did_relax_any_assertion: false
if_true_explain_spec_basis: ""
```
Spec scope extension: docs/spec_changes/2026-10-22-client-reliability-9-active-head.md. No existing test was changed. Original controller fails12/23 assertions and passes11 controls, cancelled0. Fixed controller23/23. All16 isolated mutants exit1 with actual failed assertions/cancelled0; production source never contains a mutant. Isolated cache-finalizer mutant changes a scratch copy only.
| Mutant | Failed scenarios | Pass | Exit |
|---|---:|---:|---:|
| baseline | 12 | 11 | 1 |
| no-head-hook | 10 | 13 | 1 |
| no-head-abort | 2 | 21 | 1 |
| no-prompt-settlement | 8 | 15 | 1 |
| no-sync-invalidation | 3 | 20 | 1 |
| retained-head-timer | 21 | 2 | 1 |
| no-prestart-guard | 2 | 21 | 1 |
| lost-shared-owner | 3 | 20 | 1 |
| cache-on-cancel | 12 | 11 | 1 |
| no-live-error-fallback | 1 | 22 | 1 |
| lost-media-hook | 1 | 22 | 1 |
| healthy-cache-corrupted | 14 | 9 | 1 |
| no-live-timeout-abort | 1 | 22 | 1 |
| no-mirror-fallback | 1 | 22 | 1 |
| fifo-reversed | 1 | 22 | 1 |
| stale-inflight-finalizer | 3 | 20 | 1 |
Mutant generation/reproduction: /tmp/client9-run-mutants.py; per-mutant source/test/TAP under /tmp/client9-mutant-*.mjs/.tap; structured /tmp/client9-mutants.json. Changes disable HEAD hook/abort/prompt settlement/synchronous marker/timer cleanup/prestart guard, lose shared owner, cache on cancellation, lose live error fallback/media hook/timeout abort/mirror fallback, corrupt healthy cache, reverse FIFO and remove cache finalizer identity guard. Baseline uses pre-change git controller. Every scenario is rejected by at least one mutant (grouped coverage); none survived. No forced termination, retries or waits for real timeout.
@@ -0,0 +1,12 @@
# HEAD-only candidate verification
- Test parent e21be27f34402bb274fa698b721dc01a0fa12623 (merge of notes145c09f7 and routing unstablee04549f8). Candidate source/tests subsequently committed byte-for-byte; no full/build/browser/product submission yet.
- `node_modules/.bin/prettier --write tests/url-health-head-lifecycle.test.mjs js/ui/urlHealthController.js`: formatting complete; product38+/10-, focused new suite23 scenarios. `git diff --check` exit0.
- Initial `env -u NODE_TEST_CONTEXT node --test tests/url-health-head-lifecycle.test.mjs` baseline/fixed produced file-level1 summary only (exit1/0); not used for scenario counts. Switched to direct Node per repo runner. Initial before-start baseline awaited blocked transport and cancelled3 tests; changed test to first assert no transport after draining continuations so broken variants fail assertions and clean naturally. No expectation relaxed.
- Final original-controller reproduction: /tmp/client9-baseline-tests.mjs imports isolated pre-change controller with absolute dependency imports. `env -u NODE_TEST_CONTEXT node /tmp/client9-baseline-tests.mjs`: exit1,23 total/11pass/12fail/0cancelled. /tmp/client9-direct-baseline.tap. Fixed direct23/23 exit0, /tmp/client9-direct-fixed.tap (before last test-only no-start assertion order adjustment); authoritative final focused run below covers final bytes.
- `env -u NODE_TEST_CONTEXT node scripts/run-targeted-tests.mjs tests/url-health-head-lifecycle.test.mjs tests/url-health-lifecycle.test.mjs tests/url-health-multisource.test.mjs tests/ui/url-health-controller.test.mjs`: /tmp/client9-focused.tap shows23+29+4+4 pass but initial concurrent tool completion metadata exit2 was inconsistent with all child results and runner success. Retained that observation; authoritative host rerun clears shard context too.
- `env -u NODE_TEST_CONTEXT -u UNIT_TEST_SHARD node scripts/run-targeted-tests.mjs tests/url-health-head-lifecycle.test.mjs tests/url-health-lifecycle.test.mjs tests/url-health-multisource.test.mjs tests/ui/url-health-controller.test.mjs`: approved host exit0,4files/60scenarios pass,0failed/0cancelled. /tmp/client9-focused-host.tap. Existing29+4+4 unchanged.
- `env -u NODE_TEST_CONTEXT npm run lint`: initial sandbox /tmp/client9-lint.log failed at git spawnEPERM. Approved identical host run /tmp/client9-lint-host.log exit0,11lint checks completed. No suppression/config/baseline edit.
- `python3 /tmp/client9-run-mutants.py`: final16 isolated mutants, each exit1/assertionfail>0/cancelled0, all natural exits. /tmp/client9-mutants.json and per-mutant TAP. Initial no-head-hook mutant accidentally targeted media due substring indentation; corrected to HEAD suffix and reran all16. Coverage and counts in integrity note. No product file mutated for experiments.
- Measured new contract: cancelled HEAD prompt null despite uncooperative/noAbort transport; timer0; fresh same-turn and later request; late success/error/timer/replacement identity; shared/cross/legacy live continuation; live fallback/cache; handoff cancellation; media cap3/FIFO preserved. Controller HEAD-only; no observer/cache/app/HLS/torrent edits.
- Unverified: unchanged full normal gate, build/artifact/browser/native abort/network bytes, real playback/CPU, HLS/torrent active cancellation/wholeStage3, remote open PR overlap (prior DNS exit6). No product queue submit or expensive-slot acquisition. Dispatch routing required for next gates.