mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Merge branch 'unstable' into area/playback-qa
This commit is contained in:
commit
e661e6a3b1
19 files changed
+511
-10
No files matched your search
@@ -0,0 +1,3 @@
|
||||
# Item6 audit
|
||||
|
||||
Atd88716e3 real profile remove local/synced controls pass;historical runtime no-op fails both actual-wiring diagnostics after cleanup but existing profile27 stillpass. Valuable missing regression,notcurrentproductfailure. Verified metadata merge tobbf57388/claimed;profile product/tests unchanged. Await test-only routing;notes only,no product/test commits. See test_logs/TEST_LOG_2026-10-20_15-04-00_client-reliability-6.md. QA full/normal slot respected.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Item6 retention
|
||||
|
||||
New tests/profile-history-removal-wiring.test.mjs retains3 actual profile/factory/DOM/controller/service scenarios;five runtime mutants fail with0cancelled. Product and existing suites unchanged. Focused/lint running;no full/browser/build until explicit resource grant. Unique integrity in test_logs/TEST_INTEGRITY_client-reliability-6.md. No real signer/relay/fullapp/reload claim.
|
||||
@@ -0,0 +1,3 @@
|
||||
# Item6
|
||||
|
||||
Classify historical no-op as a regression gap: actual wiring works,but existing fake-renderer profile suite passes27/27 even with historical override. Propose focused new real-wiring test and unique integrity,not product or app/history-service/cache edits. Exercise DOM event and backing persistence/recreation;fake only synced external IO and unrelated constructor dependencies. No live signer/relay or full app/reload claim.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Item6 test design
|
||||
|
||||
- Use actual profile config/factory and DOM click with original renderer removal/controller/local service. Observe actual removal promise only for deterministic completion. Required unrelated constructor services and read/metadata boundary are controlled; no fake renderer/remove implementation.
|
||||
- Local and synced removal include final-item case and renderer recreation; local Clear is a separate scenario with real queue reset. No synced Clear assumption.
|
||||
- Synced IO twin respects replace vs merge, so missing replace is observable rather than rubber-stamped. Assert all published payload/options plus publication occurrence, without requiring duplicate implementation calls.
|
||||
- Isolated runtime mutants exercise historical config no-op,clear no-op,drop-replace,wrong actor and final-item no-op. Explicit teardown runs on assertion failure and restores queue/app/client/globals.
|
||||
- No product/existing suite edits; focused/lint only until dispatch allocates full/normal slot. Build/browser remain unverified/outside current grant for test-only retention.
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
## dispatch
|
||||
|
||||
- 2026-10-20 local-review checkpoint: storage2 producte7b9afb3/closurec5818cfe and history6 regressionb3fab032/closure386cc60e durably complete. Normal latest gate431files exit0; dispatch cleanup13/13 and history3/3. Integrated preview1834b6a9 runtime equals current test/docs-only descendants. Final actual-app/mobile QA2 browser pass active; readiness awaits actual flow evidence/handoff. Feed3 and public-promised playback roadmap deferred/open; real Amber/cloud/peers/release gates remain. No optional new tasks.
|
||||
|
||||
- 2026-10-20 trial outputs complete:QA regression1bb3a4fc/closurebbf57388 verified,dispatch independent4/4/runtime unchanged so no extra build. Same3 workers continue:client6 real history test-only retention after independent current pass/historical-noop failure;storage2 method-only malformed metadata no-throw guard after independent2rejects/6controls;QA2 actual-app local core/mobile3viewports browser-only grant. Full slots on validated-ready after QA browser release;no feature/readiness/live-proof claim.
|
||||
|
||||
|
||||
@@ -40,6 +42,12 @@
|
||||
|
||||
## client-reliability
|
||||
|
||||
- 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*.
|
||||
|
||||
- 2026-10-20: item6 audit atd88716e3(profile paths unchanged throughbbf57388):real local profile remove/clear and fake-synced remove/recreation pass,0network;historical runtime no-op failsboth aftercleanup but existingprofile27/27 stillpasses;lowerlayers3files/8pass. Classify missing real-wiring regression,notcurrentproductfailure. Proposed test-only focused file+uniqueintegrity;await routing,QA expensive slot respected. Evidence test_logs/TEST_LOG_2026-10-20_15-04-00_client-reliability-6.md. No product/test changes or live signer/relay/fullapp proof.
|
||||
|
||||
- 2026-10-20: item5 done/closed after normal product landing0bd0b1c3(submission4bc52f9d,gate exit0,unstable ancestry exit0). Full427files/focused28/lifecycle18/six reverted mutants/lint11/build-artifact/Chromium+Firefox controlled smoke pass;obsolete mirror HEAD1→0. Browser+expensive slot released13:57UTC after10m57s initial wait. Dispatch landing/release event sent;preview refresh dispatch-owned. Closure metadata/final follow;no next item. Active abort/actual fallback/livepeers/CPU/fullStage3 unverified.
|
||||
|
||||
- 2026-10-20: item5 ready atmergedf2a392fa(product12f92732):full427/427 files60s-bound exit0,focused28/lifecycle18,six reverted mutants,lint11/build-artifact/native Chromium+Firefox smoke pass;obsolete mirror HEAD1→0,shared/rejoin/retry/hidden reveal pass,0 external/pageerrors. Full-slot wait10m57s recorded;browser released,expensive slot held through normal landing. Remaining queue/durable ancestry/close;active abort/real playback/CPU unverified.
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
{
|
||||
"id": "client-reliability-6",
|
||||
"area": "client-reliability",
|
||||
"status": "open",
|
||||
"status": "done",
|
||||
"title": "Audit real profile history removal wiring and historical no-op regression coverage",
|
||||
"blockedOn": null,
|
||||
"addedOn": "2026-10-20",
|
||||
"filedAt": "7f99c0456931c917082d6a6680c79655221dcc82"
|
||||
"filedAt": "7f99c0456931c917082d6a6680c79655221dcc82",
|
||||
"evidence": "Test-only retained regression9afe48a5 landed b3fab0326b3924d128b7928f4588751a003390ad via ec41d338;unchanged normal gate exit0,431 discovered/431 unique starts;focused38/38,5 mutants killed,lint11/11. Ancestry exit0. Final evidence test_logs/TEST_LOG_2026-10-20_15-41-00_client-reliability-6-landed.md. No product fix or live/browser qualification;IDLE owner local review.",
|
||||
"closedOn": "2026-10-20"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "client-reliability-7",
|
||||
"area": "client-reliability",
|
||||
"status": "open",
|
||||
"title": "Restore cold-feed live subscription onVideos notification after eligible relay updates",
|
||||
"blockedOn": null,
|
||||
"addedOn": "2026-10-20",
|
||||
"filedAt": "386cc60e1fa3ba6d9b67a1171a1ab89c03df84ca",
|
||||
"evidence": "QA actual app at386cc60e:cache0\u2192EVENT3/EOSE\u2192filtered3/access/include true\u2192viewEMPTY/DOM0. live service branch emits videos:updated but omits onVideos callback used by actual feed refresh. Scope/reproduction/controls in area prompt;minimal method-only fix after natural failing regression."
|
||||
}
|
||||
@@ -1,6 +1,16 @@
|
||||
# Area: Client reliability (client-reliability)
|
||||
|
||||
## Current assignment: client-reliability-6 — retain actual history wiring regression
|
||||
## Current assignment: client-reliability-7 — cold feed live notification blocker
|
||||
|
||||
QA actual-app passive reproduction at386cc60e: fresh Trending/cache0, local relay delivers3 valid signed VIDEO events+EOSE; raw/all/active/appvideo maps3,actual filtered3 and every access/include true,whitelist/lockdown false. Connected visible view remains current0/rendered0/signatureEMPTY/DOM0 after15s;metadata reasoncache. Service emits videos:cache3 then videos:updated(subscription3),but app refresh owner is onVideos callback. Source loadVideos cache/optimistic paths call onVideos;live subscription branch does not. This is a demonstrated local-review blocker,not optional work.
|
||||
|
||||
Temporary item ownership: ONLY js/services/nostrService.js loadVideos live-subscription notification path;new focused regression (prefer tests/nostr-service-live-feed-notification.test.mjs),unique integrity/evidence/backlog. Read app/feed/bootstrap and existing tests;do not edit them or sharedTODO without routing. No app.js,cache/filter policy,signer/protocol,runner/config/kit/styling changes. Current service area exclusion is overridden only for this method/item.
|
||||
|
||||
Merge unstable non-destructively,claimitem7,read currentrules/KNOWN_ISSUES/test-integrity/localNIP/schema docs. Before edits reproduce actual service coldcache→controlled subscribeVideos callback→actualonVideos consumer notification absent;prove cache0 theneligible updates/deletion callbacks,not event-string assertions. Preserve filtered full-list ordering,deleted updates,tombstone removal,existing videos:updated payload and persistence,callbackthrow isolation/no event loss,optimistic/cache semantics. After natural failing regression,implement smallest method-only callback delivery fix and restored failing mutants. Retain no product-policy change or forced refresh substitute.
|
||||
|
||||
Cheap focused tests and lint now;no browser/full/build until slot grant. QA owns actual-app execution and will verify cold feed plus original core/mobile baseline after durable fix/preview rebuild. Send reproduction/controls/files before widening;ready event with focused counts/mutants/lint. One unchanged normal full gate can be authoritative after merged focused/lint;avoid duplicate full solely for logs. Normal commit/merge/queue/ancestry/closure rules apply. No external operations/newoptional tasks;idle once local-review blocker is closed.
|
||||
|
||||
## Archived completed assignment: client-reliability-6 — retain actual history wiring regression
|
||||
|
||||
Investigation complete:actual profile→real renderer→DOM remove→real controller/service works locally and through fake synced publish/read. Historical no-op override resurrects removal while existing profile27 tests still pass (worker evidence). Dispatch independently ran local/synced actual wiring exit0 and historical-noop local exit1 after cleanup. No current product failure established.
|
||||
|
||||
|
||||
@@ -118,3 +118,15 @@
|
||||
- Owner exact stopping quote "Ready for me to review and test locally" recorded GOAL/PROGRAM/QUALITY. Finish current bounded fixes/tests/baseline,then handoff current preview/branch/SHA/flows/limits;no optional feature churn or production claim.
|
||||
- Inspected upstream8d4622bb:only12lines in canonicalprelaunchTODO,local110/remote1 divergent count. New public-promised HIGH1RangeGET/2health-persistence-hostscore/4warmup andotherplayback followups absent from local source used earlier. Staticrevalidation sees HEAD remains,URL localStorage persistence alreadyexists,torrent mapcache,viewport healthmetadata/orderedmirrors/SWcaches partial;no whole-item completion or new demonstrated hardreviewblocker. Non-destructive docs merge/normalqueue next,no push.
|
||||
- Storage2 full430/430exit0 andnormal1650b343 gating;QA2 genuineasset planready anddocs-only25942a15 queuedbehindit. Client6ready9afe48a5 waitsfullafterstorage+shortQA2browser. No expensive successor started.
|
||||
|
||||
## 2026-10-20 — Integrated fixes and final browser handoff
|
||||
|
||||
- Storage2 producte7b9afb3/closurec5818cfe durable; dispatch independently13 cleanup cases pass/build-artifact0. Preview rebuilt at1b3ef49c as1834b6a9,HTTP200/index equal;node135479 preserved. Upstream docs8d4622bb integrated at1b3ef49c,ancestry0;promises remain open.
|
||||
- History6 single unchanged normal gateec41d338 landedb3fab03215:40:11,closure386cc60e15:41:44;dispatch verified durable status/ancestry.431 configured files independently match431unique retained starts;empty quarantine/no shard,exit0. Durable result tail omits final stdout marker and is not full transcript;no full rerun/kit change. Worker38focused/5mutants/lint11;dispatch new3/3 naturalexit0(554.90ms).
|
||||
- Client RELEASE15:40:56/IDLE. QA genuine local VP8 fixture1019B/64x64/2s/20frames preflight7contracts+3rejected mutants;noninteractive driverdc10bf51. Interpreter grant15:44:32,dispatch15:44:58 after recovering READY15:40:37. Frozen822appfiles/runtime diff0 through386cc60e;no rebuild. Actual UI baseline still pending. No optional work;finish local-review handoff then idle.
|
||||
- QA final attempt15:45:39.511→15:45:46.059 stopped on scratch contract error:nostrToolsReady success is frozenCanonical toolkit,not ok:true. Actual media HEAD/GET/Range pass,0local404/pageerrors;UI untouched. Source confirmed line678;interpreter diagnosed same. Authorized scratch-only canonical APIs/real synthetic crypto/tampered rejection/no-mock correction+one bounded rerun,failed attempt preserved. No app defect/readiness claim.
|
||||
- QA corrected run ended15:49:48.277:real toolkit/canonicalidentity/frozen/no-mock/Node-browser crypto/tamper checks passed;genuine media wire passed. Next actual3-card prerequisite timedout0/3,so login/navigation/modals/390/1280 not run;ownedresources released. Bounded faithful seed/schema/mode/relay diagnosis vs existing e2e authorized,not app defect or readiness from boot. No assertion relaxation/newmodulemirror/product changes.
|
||||
- Source-backed QA setup correction15:54:01:app instance is assigned before init/start awaits;priorrunner omitted exported application-ready promise. Genuine events verify+matchactualfilter3/3,sourceordering3/3;devmode theory withdrawn. Authorized awaitrealready15s+official postsetupsetTestRelays,unchanged3cards15s/guards/allUIassertions and read-only relay diagnostics. No manualcardinsertion/productpatch;final actualUI stillpending.
|
||||
- QA source-ready correction still0/3 at15:55:18.667,so stopped fixes and routed pipeline measurement. Interpreter found missing requireds tag;actual schema validator rejectswithout/acceptswith,while converteracceptsboth,so notyetcausal. Existing saved data lacksWS/request/event trace. Granted one passive instrumented original-input diagnostic15:58:27:REQ/EVENT/EOSE+read-onlycache/rendercounts,unchanged3cardassertion/guards/artifact,no injection/productpatch.
|
||||
- Passive trace16:00:32.126→16:00:50.999 proves localvideoREQ kinds30078/#tvideo→3EVENT+EOSE;raw/all/active/appvideo mapsall3,DOM0. Firstmissingboundary downstreamingest/beforeDOM;missingstag notthisingestcause. Targeted feed stage/filter/render decision measurement routed16:01:39 underexistingboundedauthority,no blindretry/productpatch. UI baseline stillpending;resourcesreleased.
|
||||
- Targeted actualapp16:06:34.174→16:06:51.787 proves active3/filtered3/allaccess+include true,whitelist/lockdownfalse,viewmountedvisible butcurrent/rendered0/signatureEMPTY. Events cache0 then cache3/videos:updated(subscription3),metadata remainscache. Source live loadVideos branch omits onVideos used by feed refresh. Hardreviewblocker routed existingclient7 temporarymethodonly+newregression16:08:41;QA productreadonly/evidencehold. Not broader structure/feature change;mustfix/retention/durablegate+preview+actualUIbefore readiness.
|
||||
+7
-7
@@ -6,21 +6,21 @@ Updated2026-10-20. Owner stopping milestone:"Ready for me to review and test loc
|
||||
|---|---|---|---|
|
||||
| Feed/load/navigation | Existing client tombstone/buffer guards and broad428-file normal gate; current CRUD spec includes delete-modal/cancel coverage | Feed/view tombstone gap deferred as storage-cors-3 behind latest storage safety priority, TODO1 seed→delete→stale refresh scenario | Full app/feed behavior and documented parallel Firefox hydration flakes; live zombie reports |
|
||||
| Playback/fallback/magnets | Queued torrent/URL lifecycle fixes7d20a509/89ccb907; mirror guard0bd0b1c3; independent URL18 scenarios. QA actual coordinator/service scratch4 and local Chromium/Firefox3 each, literal hash/webseed checks | Retained QA1 landed1bb3a4fc;dispatch independently4/4,normal gate429 files | Actual WebTorrent/live peers; full-app fallback; local decoded mirror/substituted torrent does not prove real torrent |
|
||||
| Profile/session/history | Profile fixture hang fixedde6918ce;27 focused historical scenarios and current broad suite. History lazy-init test injects fake renderer | client-reliability-6 test-only real wiring regression after current pass/historical-noop failure, TODO2 regression gap | Amber NIP46 identity/switch/logout across refresh, real signers; KNOWN_ISSUES isolated logout UI failure |
|
||||
| Storage/upload safety | CORS productd3f4c215,closure7f99c045; independent9 CORS scenarios,worker focused13/10mutants/full428/lint/build; content-addressed/cleanup safeguards documented | storage-cors-2 narrow metadata no-throw guard after2 reproduced rejects/6controls | Live bucket/IAM/provider serialization; concurrent read-modify-write has no CAS; no credentials/cloud writes tested |
|
||||
| Mobile usability | No fresh local mobile flow/visual qualification from trial | QA2 first360pass BLOCKED:static genuineBufferCDN guard+missing generatedCSS,remainingflows unverified. Genuinecached pinned mirror+verified builtartifact prep ready;secondpass afterstorage2 integration,no UI edits | Real-device/manual accessibility and UX; visual baselines remain CI-canonical |
|
||||
| Trustworthy validation | Unchanged normal gates and restored failing mutants; latest product gate428 files. QA retained regression429-file diagnostic+normal gate passed1bb3a4fc | Retain exact counts, ancestry, fixture boundaries, failed mutants and Known Issues classification | Full broad E2E/release/manual cross-browser checks; never weaken assertions or treat mocked boundaries as live proof |
|
||||
| Preview | Preserved localhost3000,storage integrated7f99c045; build/artifact pass,HTTP200/index matches dist | Refresh after each verified product landing; QA is test-only so inspect product delta before rebuilding | Production/live-site state not touched or qualified |
|
||||
| Profile/session/history | Real profile-history wiring regression landed b3fab032, closure386cc60e; normal431-file gate exit0, focused38/38,5 rejected mutants; dispatch independently new3/3 | Complete; current behavior passed, regression protects historical no-op | Amber NIP46 identity/switch/logout across refresh, real signers; KNOWN_ISSUES isolated logout UI failure |
|
||||
| Storage/upload safety | CORS preservation d3f4c215 and malformed cached metadata guard e7b9afb3/closurec5818cfe; dispatch independent9 CORS+13 cleanup scenarios; worker430-file gate/24 focused/7 mutants | Complete within bounded contract; generic S3 shares deletion service, no counterpart invented | Live bucket/IAM/provider serialization; concurrent read-modify-write has no CAS; no credentials/cloud writes tested |
|
||||
| Mobile usability | Actual integrated app boot with genuine cached Buffer; owned media actual HEAD/GET/Range checks pass,0local404/pageerrors | QA2 measured hard cold-feed notification blocker:eligible/cache3→DOM0 despite connectedview; client7 method-only regression/fix routed. Original core/mobile flows pending after fix; driver mistakes preserved separately | Real-device/manual accessibility and UX; visual baselines remain CI-canonical |
|
||||
| Trustworthy validation | Unchanged normal gate candidate b3fab032 exit0;431 configured files match431 unique retained starts; no shard/quarantine. QA fallback regression1bb3a4fc independently4/4 | Durable gate tail is not a complete process transcript; stdout final marker absent, explicitly disclosed | Full broad E2E/release/manual cross-browser checks; never weaken assertions or treat mocked boundaries as live proof |
|
||||
| Preview | Preserved localhost3000/node135479; build1834b6a9 from integrated1b3ef49c; build/artifact pass,HTTP200/index byte equality | Runtime/build-input diff0 through client6 closure386cc60e; preserve frozen QA snapshot | Production/live-site state not touched or qualified |
|
||||
|
||||
## Milestones
|
||||
|
||||
1. Finish prepared trial outputs: two product fixes are durable; retained QA regression is durable1bb3a4fc;next work continues under sustained goal. Report actual timings: implementation parallelism exists, but serialized duplicate full gates and39m57 dispatch wake/checkpoint lag prevent an overall speedup claim.
|
||||
2. Revalidate high-priority history wiring and storage/delete safety at current HEAD;feed-view deletion gap remains deferred,not cancelled using real wiring plus controlled IO; route only reproduced defects or valuable mutant-proven regressions. No product changes authorized by investigation assignments.
|
||||
3. Establish fresh local core-flow/mobile baseline after those checks; keep live Amber/cloud/peer/manual release gates separate. Continue useful bounded work under existing authority; surface substantive blockers/owner product choices instead of inventing features or keeping agents busy.
|
||||
3. Finish faithful local core-flow/mobile baseline and handoff,then IDLE for owner local review. Keep live Amber/cloud/peer/manual release gates and optional backlog separate;route only demonstrated hard local-review blockers.
|
||||
|
||||
## Resource and operating limits
|
||||
|
||||
QA currently owns full/normal gate; other investigations may use cheap focused local checks, no expensive full suite/build/browser without dispatch slot. Separate worktrees/branches; no competing product writers or app.js edits. Keep team at dispatch+3 existing workers while useful disjoint tasks exist. Clear inherited NODE_TEST_CONTEXT for CLI launches. Use mailbox/CLI/status recovery, actual send/consume times, no raw pane bodies or unattended-wakeup claim. No push/deploy/spend/real-wallet/production-data/scheduler/credentialed external operations.
|
||||
Client7 cold-feed hard-blocker actual-service regression/minimalfix now cheapfocused/lint;QA browser resources released16:06:51,retains repro/evidence. Storage IDLE. Full/browser/build successor only after validated-ready grant; no optional work. No expensive competing suite/build/browser. Separate worktrees/branches; no competing product writers or app.js edits. Keep team at dispatch+3 existing workers while useful disjoint tasks exist. Clear inherited NODE_TEST_CONTEXT for CLI launches. Use mailbox/CLI/status recovery, actual send/consume times, no raw pane bodies or unattended-wakeup claim. No push/deploy/spend/real-wallet/production-data/scheduler/credentialed external operations.
|
||||
|
||||
## Reconciled Oct2026 upstream playback promises
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ a landing rule changes.
|
||||
|
||||
## 2026-10-20
|
||||
|
||||
- Local-review hard blocker measured: coldTrending cache0 then relayEVENT3/EOSE ingests eligible3 but view remainsEMPTY/DOM0. client-reliability-7 temporary ownership ONLY nostrService.loadVideos subscription notification path + new focused regression/integrity/evidence; reproduce current method before minimal fix. Existing app/feed modules read-only unless additional evidence/routing. Preserve access/filter/deletion/cache/event semantics; no forcedrefresh baseline substitute. QA retains actual-app/browser qualification; client cheapfocused until explicit fullslot.
|
||||
|
||||
- Owner stopmilestone is Ready for me to review and test locally. Finish current storage2/history6/faithful actual-app baseline+preview/handoff,then no new optional tasks before review. Reconcile upstream docs-only8d4622bb via area merge+normal queue;new playback promises stay explicit/open,do not churn current scope or declare them done from partial/static evidence. Genuine cached offline dependency mirror is testprep only,not CDN/deployed/offline production proof.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Item6 retained profile history wiring
|
||||
|
||||
```yaml
|
||||
test_integrity_note:
|
||||
change_type: ["new_tests"]
|
||||
scenarios:
|
||||
- id: SCN-profile-local-remove-real-wiring
|
||||
given: "local-only actor has two real service queue entries rendered by the actual profile history factory"
|
||||
when: "actual profile DOM remove controls delete one item then the last item, recreating the renderer between steps"
|
||||
then: "backing queue and DOM remain reduced then empty, no publish IO or historical onHistoryReady callback runs"
|
||||
- id: SCN-profile-local-clear-real-wiring
|
||||
given: "actual profile history contains two local entries"
|
||||
when: "actual Clear local history button is clicked and renderer recreated"
|
||||
then: "real local queue and DOM remain empty with zero publish IO"
|
||||
- id: SCN-profile-synced-remove-real-wiring
|
||||
given: "synced actor renders two entries through real profile/default removal/controller/service with fake read/publish IO"
|
||||
when: "profile DOM removes an item then the last, with renderer recreation"
|
||||
then: "publish IO receives reduced then empty replacements with correct actor; recreation never resurrects removed entries"
|
||||
observable_outcomes:
|
||||
- "actual DOM removal controls and card state, service loadLatest/queue persistence, renderer recreation"
|
||||
- "fake external publish payload, replace and actor options; zero local publishes and network attempts"
|
||||
determinism_controls:
|
||||
- "actual component markup, ProfileModalController config/factory, renderer, removal controller and local service"
|
||||
- "fixed fake pointers, unique actors, isolated jsdom localStorage, controlled synced read/publish twin honoring merge vs replace"
|
||||
- "task-turn drain and actual removal promise observation; no arbitrary sleeps/retries, real signer/relay/network"
|
||||
- "teardown destroys renderer/subscriptions, resets actor service state, restores application/client/globals and closes DOM, even on failure"
|
||||
anti_cheat_rationale:
|
||||
prevents:
|
||||
- "historical no-op removal hidden by optimistic DOM changes"
|
||||
- "fake renderer or source-string-only configuration assertion"
|
||||
- "local clear without backing persistence or missing synced replace/actor options"
|
||||
- "last-item no-op and publish twin that always replaces regardless of options"
|
||||
relaxation:
|
||||
did_relax_any_assertion: false
|
||||
if_true_explain_spec_basis: ""
|
||||
```
|
||||
|
||||
Only a new test file is retained; no existing suite/product assertions changed. Publish boundary assertions require at least one appropriate publication and verify every emitted payload/options, preserving behavior without locking in today's duplicate publication count. Clear coverage is local-only; no synced Clear-local/relay-list-clear equivalence claim.
|
||||
|
||||
Fault injections operate only in isolated CLI process memory, never edit product files. `python3 /tmp/item6-retention-mutants.py`: all five naturally exit1 with named assertion failures,zero cancelled; process exit restores injected prototypes and fixture after-hooks release queue/app/client/globals on failed assertions. Historical-noop kills local+synced real wiring; clear-noop (one dropped reset then cleanup forwards normally) kills local Clear; drop-replace kills local+synced; wrong-actor kills synced and explicitly releases injected actor state; ignore-last kills local+synced final removal. Logs `/tmp/item6-retained-mutant-*.log`,summary `/tmp/item6-retained-mutants.json`.
|
||||
|
||||
Independent audit showed existing profile27/27 survive the historical no-op while both actual wiring scratch variants fail after cleanup. New retained local+synced tests reject that same injected override. Actual application load/show/reload,real signing/encryption/relay persistence and manual user confirmation remain unverified.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Item6 profile history wiring audit
|
||||
|
||||
## State and scope
|
||||
|
||||
- Audit executed atd88716e3c6351468a53bc7fdb84fe912c01697b5; actual profile/history product files unchanged from filedAt7f99c045. Subsequently merged verified assignment/QA metadata tobbf57388cb4724ff915c2090cf29506bce2c69f7 and claimed item6. `git diff --exit-code d88716e3..HEAD -- js/ui/profileModalController.js js/historyView.js js/ui/watchHistoryController.js js/watchHistoryService.js tests/profile-modal-controller.test.mjs`: exit0. No unnecessary reruns after unchanged product merge.
|
||||
- Initial claim returned no item while normal assignment metadata was behind QA gate. Dispatch explicitly authorized continued read-only evidence before prose landing; claim succeeded once metadata landed. QA expensive slot respected: no full/browser/build/normal-gate launch.
|
||||
- No product or committed test edits; unique evidence/scratch only. NIP51/33 and Known Issues reviewed. No private data, real signer/relay/cloud/wallet activity.
|
||||
|
||||
## Coverage inventory
|
||||
|
||||
- `rg -n 'createWatchHistoryRenderer|onHistoryReady' tests/profile-modal-controller.test.mjs tests/watch-history.test.mjs`: profile test imports actual factory but injects fake renderer at1386; its history test checks lazy initialization/pause/resume. No removal is invoked and captured config's remove callback is not exercised. Other actual renderer construction is feed-registration/service-fallback case atwatch-history.test.mjs2306, not profile removal.
|
||||
- `rg -l 'profileHistory|profilePaneHistory|handleRemove\(|remove-history' tests --glob '*.mjs' --glob '*.ts'`: profile file plus two menu markup test files. E2E search profileNavHistory/profileHistoryClear/profilePaneHistory has no matches; standalone history-view E2E clear is not this profile config path.
|
||||
- Existing lower-layer removal/controller/snapshot suites exercise local persistence, synced replace options, last-item clear and disabled behavior independently of profile renderer wiring. Their coverage does not reject the historical profile override (confirmed behaviorally below).
|
||||
|
||||
## Real wiring diagnostic
|
||||
|
||||
Scratch `/tmp/bitvid-client-reliability-6-history-audit.mjs`, finalSHA256c9f7cc21426d930d37ecf7a5edc4dfff5c99fdc6b2bcceb5b637959730f6c812. Actual ProfileModalController constructor/ensureProfileHistoryRenderer config→actual createWatchHistoryRenderer→actual profile DOM remove click→default remove selecting actual WatchHistoryController→actual watchHistoryService. Wrapper only observes returned handleRemove promise for deterministic event completion; it calls the original method. Controlled actor/fetchHistory boundary uses actual local service and fake synced publish/read backend; required unrelated profile services are empty shims. Actual component markup is used. No modal.load/show, application bootstrap, live signer/relay or full reload claim.
|
||||
|
||||
Commands: `env -u NODE_TEST_CONTEXT NODE_ENV=test node /tmp/bitvid-client-reliability-6-history-audit.mjs <mode> [--historical-noop]`.
|
||||
|
||||
- `local`: natural exit0. Seed2 real local queue items,click remove first; renderer/service retain only audit-keep. Fake publish calls0,errors0,forbidden fetch/WebSocket0. Actual profile Clear local history button empties real local queue; renderer recreation reads empty. Logs `/tmp/item6-local.log`.
|
||||
- `synced`: natural exit0. Actual removal leaves audit-keep in renderer/fake backend; exactly2 fake publish-boundary calls (service snapshot plus controller list update),both replace:true/actorPubkey actor/reducedlist; second source remove-item. Renderer recreation retains only audit-keep. No-op calls0/errors0/forbidden network0. Logs `/tmp/item6-synced-final.log`. Fake backend substitutes signing/relay/publish serialization; no real encrypted-event or all-relay acceptance proof.
|
||||
- Local and synced `--historical-noop`: each naturally exits1 AFTER destroy/reset/DOM cleanup,deepStrictEqual actual[audit-first,audit-keep] expected[audit-keep]. Historical runtime config override routes remove to callbacks.onHistoryReady returning null: no-op1,publish0;removed item reappears after renderer's real refresh and remains in backing state. Logs `/tmp/item6-noop-local.log`,`/tmp/item6-noop-synced.log`. Earlier versions of diagnostic preceded extra synced actor/source assertions; those assertions only execute in non-mutant synced branch and final synced run verifies them.
|
||||
- Initial scratch fixture failed controller's required-services contract before any audited action; supplied unrelated required service objects and reran. That fixture setup error is not a product failure.
|
||||
|
||||
## Existing suite mutant escape
|
||||
|
||||
Preloader `/tmp/item6-historical-noop-preload.mjs`,SHA2561d4209ef87dc9732876d12411999a2b7a232561f2ec1ab46bacdcad1db0cc890 injects same historical no-op into actual ProfileModalController prototype entirely at runtime. No source/test file edits.
|
||||
|
||||
- `env -u NODE_TEST_CONTEXT NODE_ENV=test node --import ./tests/test-helpers/setup-localstorage.mjs tests/profile-modal-controller.test.mjs`: natural exit0,27pass/0fail/0cancelled/0skip; duration7635.26ms (`/tmp/item6-existing-profile-baseline.log`).
|
||||
- Same command plus `--import /tmp/item6-historical-noop-preload.mjs`: natural exit0,27pass/0fail/0cancelled/0skip; duration7085.08ms (`/tmp/item6-existing-profile-mutant.log`). This deliberately reintroduced bug escapes all existing profile assertions.
|
||||
- `env -u NODE_TEST_CONTEXT node scripts/run-unit-tests.mjs watch-history-local-remove watch-history-controller-local-remove watch-history-remove-snapshot`: natural exit0,3files/8scenarios. These are lower-layer controls, not profile wiring qualification (`/tmp/item6-existing-history-layers.log`).
|
||||
|
||||
## Classification and proposed scope
|
||||
|
||||
Missing high-value regression, not a demonstrated current product failure: real local and fake-synced wiring currently works, but original no-op bug survives current profile suite. Proposed test-only `tests/profile-history-removal-wiring.test.mjs` plus unique integrity/evidence, using actual profile/factory/DOM/default remove/controller/local service; controlled synced read/publish only. Acceptance: local remove persists, local clear/recreation empty, synced reducedlist replacement options and recreation correct; historical no-op must fail after deterministic cleanup. Preserve assertions and reject source-string-only/fake-renderer substitutes. No app/history-service/cache/product edits needed.
|
||||
|
||||
Sent concrete evidence/proposed test scope to dispatch; awaiting retained-test routing before any committed test changes. Unverified: real Nostr/signing/encryption/relay persistence, full application/modal lifecycle/reload, synced Clear-local behavior versus encrypted-list clearing, manual user confirmation and other TODO2 feed/view coverage (separate area). No full/browser/build/routing/landing readiness claim.
|
||||
@@ -0,0 +1,10 @@
|
||||
# Item6 test-only ready
|
||||
|
||||
- Retained `tests/profile-history-removal-wiring.test.mjs` only; no product/existing suite changes. Test-only routing merged from verifiedac99ae9a after audit notes8356f27d.
|
||||
- `env -u NODE_TEST_CONTEXT NODE_ENV=test node tests/profile-history-removal-wiring.test.mjs`: natural exit0,3/3pass,0failed/cancelled/skipped,1388.42ms final readable run (`/tmp/item6-retention-final.log`). Real local removal through final item+recreation,actual local Clear+recreation,and synced reduced+empty replacements through fake IO.
|
||||
- `python3 /tmp/item6-retention-mutants.py`: five/five isolated runtime faults each naturally exit1,0cancelled,cleanup after-hooks still pass. Historical no-op kills both real removal scenarios;skip clear/drop replace/wrong actor/skip last cover all new scenarios. No source file mutated; unique mapping `test_logs/TEST_INTEGRITY_client-reliability-6.md`.
|
||||
- `env -u NODE_TEST_CONTEXT node scripts/run-unit-tests.mjs profile-history-removal-wiring profile-modal-controller watch-history-local-remove watch-history-controller-local-remove watch-history-remove-snapshot`: natural exit0,5files/38scenarios (3+27+8),log `/tmp/item6-retention-focused.log`.
|
||||
- `env -u NODE_TEST_CONTEXT npm run lint` with approved git subprocess access: exit0,11stages (`/tmp/item6-retention-lint.log`).
|
||||
- Globals/app/client/local actor queues restored and DOM/subscriptions closed even on named failing mutations;network guards cover global and window fetch/WebSocket. No arbitrary sleeps/retries/live signer/relay/credentials.
|
||||
- Full/browser/build/normal queue have not been launched;await explicit full/normal slot after QA bounded browser work. Build/browser have no fresh qualification from this test-only change. No product behavior fix claimed;real signing/encryption/relay persistence/full app modal lifecycle/reload/manual confirmation and synced Clear remain unverified.
|
||||
- Retention data is behavior-based,publish twin honors merge vs replace;all emitted replacement actor/payload/options checked without locking in duplicate call count. Existing profile27 passes historical no-op in audit;new tests reject it.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Item6 landed verification
|
||||
|
||||
- Test-only retention commit `9afe48a5b534ac273b7ad321ccffc5b216711645`; merged verified unstable `c5818cfe67c2f986138e8322951d99bcb94a5c47` into submission `ec41d3381c4befb2f3a83212f8517d29d2921c36`. Actual tested candidate and durable landed SHA `b3fab0326b3924d128b7928f4588751a003390ad` at15:40:11.180UTC. `land_status` state landed, `git log -1 unstable` agrees, `git merge-base --is-ancestor ec41d3381c4befb2f3a83212f8517d29d2921c36 unstable` exit0.
|
||||
- Slot request15:13:57UTC; first interpreter grant15:30:07UTC, wait16m10s; dispatch confirms first grant. Merged focused/lint launched approximately15:32UTC; normal gate submitted15:33:02.334UTC. Slot release mailbox15:40:56UTC; no browser taken.
|
||||
- Merged focused runner5files exit0 `/tmp/item6-merged-focused.log`. Its output only reports file completion, so independently executed each same five files via `node tests/<file>.test.mjs` with NODE_TEST_CONTEXT removed and NODE_ENV=test:3+27+3+2+3=38/38,0fail/cancel/skip,each natural exit0. `/tmp/item6-merged-focused-direct.log`; no duplicate full-suite run. Prior explicit new3/3 direct and all5 naturally failing mutants are in ready/integrity notes.
|
||||
- `env -u NODE_TEST_CONTEXT npm run lint` exit0,11stages; `/tmp/item6-merged-lint.log`.
|
||||
- Single authoritative full candidate gate launched with `env -u NODE_TEST_CONTEXT UNIT_TEST_TIMEOUT_MS=60000 node tools/fleet/bin/landq.mjs submit`; UNIT_TEST_SHARD absent from launch environment, no args filters/shard, empty quarantine. Existing unchanged gate: `if [ -f package.json ]; then if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then npm ci --ignore-scripts || npm install; else npm install; fi; npm test; else echo 'set gates.land' >&2; exit 1; fi`. Durable result explicitly records exit0. Runner/package/config Git blobs identical to c5818cfe; no gate/assertion/discovery changes.
|
||||
- Configured discovery independently derived from `git ls-tree` at tested b3fab032 using unchanged runner rules:431 files. Existing lander unit log retains431 unique file-start records,including final test output. This is431-file full-gate success; no assertion that every file has the same test framework/scenario count.
|
||||
- Durable original result `/home/user/.local/state/agent-fleet/bitvid/landq/results/ec41d3381c4befb2f3a83212f8517d29d2921c36.json`; preserved before another gate at `/tmp/client-reliability-6-normal-result.json`,3471bytes,SHA256 `7a58a7e789a507c16a74e0fb33d4c31f34f4ce168d09ef354be744a118196c65`. Result detail retains gate exit0 and stderr tail; it does NOT retain stdout All unit tests passed marker.
|
||||
- Existing runner artifact `/home/user/Documents/GitHub/bitvid-lander/artifacts/test_unit.log` copied before overwrite to `/tmp/client-reliability-6-normal-unit.log`,687357bytes,SHA256 `b6827c8c406721ecdcc69cfe171d4f61f495a5036302144744e6d61b5d737c79`. Retained unit stdout/stderr and file starts, not entire npm install/full-process transcript or guarantee of flushed final runner marker. Raw logs kept outside committed notes.
|
||||
- Scope: new actual-profile DOM wiring test, integrity and evidence only; no product/existing suite edits. Real signers/encryption/relay persistence, full-app modal load/show/reload/manual confirmation, synced Clear, browser/build are unverified. Stop at owner local-review milestone; no new optional task.
|
||||
@@ -0,0 +1,315 @@
|
||||
import "./test-helpers/setup-localstorage.mjs";
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { JSDOM } from "jsdom";
|
||||
import ProfileModalController from "../js/ui/profileModalController.js";
|
||||
import { createWatchHistoryRenderer } from "../js/historyView.js";
|
||||
import WatchHistoryController from "../js/ui/watchHistoryController.js";
|
||||
import watchHistoryService from "../js/watchHistoryService.js";
|
||||
import { nostrClient } from "../js/nostrClientFacade.js";
|
||||
import { getApplication, setApplication } from "../js/applicationContext.js";
|
||||
|
||||
const markup = await readFile(
|
||||
new URL("../components/profile-modal.html", import.meta.url),
|
||||
"utf8"
|
||||
);
|
||||
const flush = () => new Promise((resolve) => setImmediate(resolve));
|
||||
let actorSequence = 100;
|
||||
|
||||
async function fixture(t, { synced = false } = {}) {
|
||||
const dom = new JSDOM(`<!doctype html><body>${markup}</body>`, {
|
||||
url: "https://example.invalid"
|
||||
});
|
||||
const globals = [
|
||||
"window",
|
||||
"document",
|
||||
"HTMLElement",
|
||||
"HTMLInputElement",
|
||||
"HTMLImageElement",
|
||||
"HTMLButtonElement",
|
||||
"Node",
|
||||
"Event",
|
||||
"CustomEvent",
|
||||
"MutationObserver",
|
||||
"localStorage",
|
||||
"fetch",
|
||||
"WebSocket",
|
||||
"IntersectionObserver"
|
||||
];
|
||||
const savedGlobals = globals.map((key) => [
|
||||
key,
|
||||
Object.getOwnPropertyDescriptor(globalThis, key)
|
||||
]);
|
||||
for (const key of globals.slice(0, 10)) {
|
||||
globalThis[key] =
|
||||
key === "window"
|
||||
? dom.window
|
||||
: key === "document"
|
||||
? dom.window.document
|
||||
: dom.window[key];
|
||||
}
|
||||
globalThis.localStorage = dom.window.localStorage;
|
||||
globalThis.IntersectionObserver = class {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
};
|
||||
let networkAttempts = 0;
|
||||
globalThis.fetch = dom.window.fetch = () => {
|
||||
networkAttempts++;
|
||||
throw new Error("Unexpected history fixture network request");
|
||||
};
|
||||
globalThis.WebSocket = dom.window.WebSocket = class {
|
||||
constructor() {
|
||||
networkAttempts++;
|
||||
throw new Error("Unexpected history fixture socket");
|
||||
}
|
||||
};
|
||||
|
||||
const actor = (++actorSequence).toString(16).padStart(64, "0");
|
||||
const clientKeys = [
|
||||
"pubkey",
|
||||
"sessionActor",
|
||||
"updateWatchHistoryList",
|
||||
"resolveWatchHistory",
|
||||
"getWatchHistoryFingerprint"
|
||||
];
|
||||
const savedClient = clientKeys.map((key) => [key, nostrClient[key]]);
|
||||
const previousApp = getApplication();
|
||||
const seed = [
|
||||
{ type: "e", value: "profile-first", watchedAt: 1700000000 },
|
||||
{ type: "e", value: "profile-keep", watchedAt: 1700000001 }
|
||||
];
|
||||
let publishedItems = structuredClone(seed);
|
||||
const publishes = [],
|
||||
errors = [],
|
||||
noops = [];
|
||||
nostrClient.pubkey = synced ? actor : "";
|
||||
nostrClient.sessionActor = synced ? null : { pubkey: actor };
|
||||
// Publish/read IO twin honors merge vs replace so a lost replace flag cannot
|
||||
// look successful merely because the fake publisher always replaces its list.
|
||||
nostrClient.updateWatchHistoryList = async (items, options = {}) => {
|
||||
publishes.push({ items: structuredClone(items), options: { ...options } });
|
||||
publishedItems =
|
||||
options.replace === true
|
||||
? structuredClone(items)
|
||||
: [
|
||||
...new Map(
|
||||
[...publishedItems, ...items].map((item) => [
|
||||
`${item.type}:${item.value}`,
|
||||
structuredClone(item)
|
||||
])
|
||||
).values()
|
||||
];
|
||||
return { ok: true, items: structuredClone(publishedItems) };
|
||||
};
|
||||
nostrClient.resolveWatchHistory = async () => structuredClone(publishedItems);
|
||||
nostrClient.getWatchHistoryFingerprint = async () =>
|
||||
JSON.stringify(publishedItems);
|
||||
const historyController = new WatchHistoryController({
|
||||
watchHistoryService,
|
||||
nostrClient,
|
||||
getActivePubkey: () => actor,
|
||||
showError: (message) => errors.push(message)
|
||||
});
|
||||
setApplication({
|
||||
watchHistoryController: historyController,
|
||||
showSuccess() {},
|
||||
showError: (message) => errors.push(message),
|
||||
isAuthorBlocked: () => false,
|
||||
getHashtagPreferences: () => ({ interests: [], disinterests: [] })
|
||||
});
|
||||
let renderer;
|
||||
const profile = new ProfileModalController({
|
||||
services: {
|
||||
relayManager: {},
|
||||
userBlocks: {},
|
||||
accessControl: {},
|
||||
nostrClient
|
||||
},
|
||||
callbacks: {
|
||||
onHistoryReady(payload) {
|
||||
noops.push(payload);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
createWatchHistoryRenderer: (config) =>
|
||||
createWatchHistoryRenderer({
|
||||
...config,
|
||||
getActor: () => actor,
|
||||
fetchHistory: async () => ({
|
||||
items: await watchHistoryService.loadLatest(actor, {
|
||||
allowStale: false,
|
||||
forceRefresh: true
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
profile.profileModalPanel = document.body;
|
||||
profile.profileModalRoot = document.body;
|
||||
t.after(() => {
|
||||
try {
|
||||
renderer?.destroy();
|
||||
watchHistoryService.resetProgress(actor);
|
||||
assert.deepEqual(
|
||||
watchHistoryService.getQueuedPointers(actor),
|
||||
[],
|
||||
"fixture must release its local queue"
|
||||
);
|
||||
} finally {
|
||||
setApplication(previousApp);
|
||||
for (const [key, value] of savedClient) nostrClient[key] = value;
|
||||
dom.window.close();
|
||||
for (const [key, descriptor] of savedGlobals) {
|
||||
if (descriptor) Object.defineProperty(globalThis, key, descriptor);
|
||||
else delete globalThis[key];
|
||||
}
|
||||
}
|
||||
assert.equal(
|
||||
networkAttempts,
|
||||
0,
|
||||
"no network or relay activity is permitted"
|
||||
);
|
||||
});
|
||||
if (!synced)
|
||||
await watchHistoryService.snapshot(seed, { actor, replace: true });
|
||||
renderer = profile.ensureProfileHistoryRenderer();
|
||||
await renderer.init({ actor, force: true });
|
||||
const values = () =>
|
||||
renderer
|
||||
.getState()
|
||||
.items.map((item) => item.pointer.value)
|
||||
.sort();
|
||||
const persisted = async () =>
|
||||
(
|
||||
await watchHistoryService.loadLatest(actor, {
|
||||
allowStale: false,
|
||||
forceRefresh: true
|
||||
})
|
||||
)
|
||||
.map((item) => item.value)
|
||||
.sort();
|
||||
const grid = document.querySelector("#profileHistoryGrid");
|
||||
assert.deepEqual(values(), ["profile-first", "profile-keep"]);
|
||||
assert.equal(grid.querySelectorAll("[data-history-card]").length, 2);
|
||||
|
||||
async function remove(value) {
|
||||
// Observe completion of the actual method invoked by the real DOM listener;
|
||||
// no remove/controller/service implementation is replaced by this wrapper.
|
||||
let pending;
|
||||
const original = renderer.handleRemove.bind(renderer);
|
||||
renderer.handleRemove = (...args) => {
|
||||
pending = original(...args);
|
||||
return pending;
|
||||
};
|
||||
try {
|
||||
const trigger = grid.querySelector(
|
||||
`[data-history-action="remove"][data-pointer-key="e:${value}"]`
|
||||
);
|
||||
assert.ok(trigger, "profile pane must render an actual removal control");
|
||||
trigger.click();
|
||||
assert.ok(
|
||||
pending instanceof Promise,
|
||||
"DOM click must invoke renderer removal"
|
||||
);
|
||||
await pending;
|
||||
await flush();
|
||||
} finally {
|
||||
renderer.handleRemove = original;
|
||||
}
|
||||
}
|
||||
async function recreate() {
|
||||
renderer.destroy();
|
||||
profile.profileHistoryRenderer = null;
|
||||
renderer = profile.ensureProfileHistoryRenderer();
|
||||
await renderer.init({ actor, force: true });
|
||||
await flush();
|
||||
}
|
||||
return {
|
||||
actor,
|
||||
profile,
|
||||
values,
|
||||
persisted,
|
||||
remove,
|
||||
recreate,
|
||||
grid,
|
||||
publishes,
|
||||
errors,
|
||||
noops
|
||||
};
|
||||
}
|
||||
|
||||
test("real profile local removal persists through recreation and removing the last item", async (t) => {
|
||||
const f = await fixture(t);
|
||||
await f.remove("profile-first");
|
||||
assert.deepEqual(await f.persisted(), ["profile-keep"]);
|
||||
assert.deepEqual(f.values(), ["profile-keep"]);
|
||||
assert.equal(
|
||||
f.grid.querySelector('[data-pointer-key="e:profile-first"]'),
|
||||
null
|
||||
);
|
||||
await f.recreate();
|
||||
assert.deepEqual(f.values(), ["profile-keep"]);
|
||||
await f.remove("profile-keep");
|
||||
assert.deepEqual(await f.persisted(), []);
|
||||
await f.recreate();
|
||||
assert.deepEqual(f.values(), []);
|
||||
assert.equal(f.grid.querySelectorAll("[data-history-card]").length, 0);
|
||||
assert.equal(f.publishes.length, 0, "local-only removal must never publish");
|
||||
assert.equal(
|
||||
f.noops.length,
|
||||
0,
|
||||
"historical onHistoryReady no-op must not handle removal"
|
||||
);
|
||||
assert.deepEqual(f.errors, []);
|
||||
});
|
||||
|
||||
test("real profile Clear local history empties the queue and remains empty after recreation", async (t) => {
|
||||
const f = await fixture(t);
|
||||
const clear = document.querySelector("#profileHistoryClear");
|
||||
assert.ok(clear);
|
||||
clear.click();
|
||||
await flush();
|
||||
assert.deepEqual(await f.persisted(), []);
|
||||
assert.deepEqual(f.values(), []);
|
||||
await f.recreate();
|
||||
assert.deepEqual(f.values(), []);
|
||||
assert.equal(f.grid.querySelectorAll("[data-history-card]").length, 0);
|
||||
assert.equal(f.publishes.length, 0);
|
||||
assert.deepEqual(f.errors, []);
|
||||
});
|
||||
|
||||
test("real profile synced removal publishes reduced replacement and empty final replacement through fake IO", async (t) => {
|
||||
const f = await fixture(t, { synced: true });
|
||||
await f.remove("profile-first");
|
||||
assert.deepEqual(await f.persisted(), ["profile-keep"]);
|
||||
assert.ok(f.publishes.length > 0, "synced removal must reach publish IO");
|
||||
for (const { items, options } of f.publishes) {
|
||||
assert.deepEqual(
|
||||
items.map((item) => item.value),
|
||||
["profile-keep"]
|
||||
);
|
||||
assert.equal(options.replace, true);
|
||||
assert.equal(options.actorPubkey, f.actor);
|
||||
}
|
||||
const firstPublishCount = f.publishes.length;
|
||||
await f.recreate();
|
||||
assert.deepEqual(f.values(), ["profile-keep"]);
|
||||
await f.remove("profile-keep");
|
||||
assert.deepEqual(await f.persisted(), []);
|
||||
assert.ok(
|
||||
f.publishes.length > firstPublishCount,
|
||||
"last removal must publish an empty replacement"
|
||||
);
|
||||
for (const { items, options } of f.publishes.slice(firstPublishCount)) {
|
||||
assert.deepEqual(items, []);
|
||||
assert.equal(options.replace, true);
|
||||
assert.equal(options.actorPubkey, f.actor);
|
||||
}
|
||||
await f.recreate();
|
||||
assert.deepEqual(f.values(), []);
|
||||
assert.equal(f.grid.querySelectorAll("[data-history-card]").length, 0);
|
||||
assert.equal(f.noops.length, 0);
|
||||
assert.deepEqual(f.errors, []);
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
# Item6
|
||||
|
||||
- [x] Read current objective/rules,mergeverifiedunstable and claim aftermetadata visibility.
|
||||
- [x] Audit full corpus for actual profile removal wiring.
|
||||
- [x] Real local remove/clear and fake-synced replacement/recreation controls.
|
||||
- [x] Historical no-op fails2diagnostics but existingprofile27/27 survives;lowerlayers8pass.
|
||||
- [x] Send gap classification/test-only scope to dispatch.
|
||||
- [ ] Dispatch routes retained tests or audit closure;no product/committed tests authorized yet.
|
||||
@@ -0,0 +1,7 @@
|
||||
# Item6 retention
|
||||
|
||||
- [x] Independent audit/routing and3 actual-wiring scenarios.
|
||||
- [x] Five isolated failing runtime mutants,cleanup preserved.
|
||||
- [ ] Focused/lint final results,ready commit and slot request.
|
||||
- [ ] Verified unstable merge,full/normal gate slot,durable landing/ancestry.
|
||||
- [ ] Close backlog and final dispatch report.
|
||||
@@ -0,0 +1,10 @@
|
||||
# Item6 completed
|
||||
|
||||
- [x] Audit current actual profile behavior and historical no-op coverage gap.
|
||||
- [x] Retain3 actual-wiring scenarios;kill5 isolated runtime mutants.
|
||||
- [x] Commit/merge unstable;focused38/38 andlint11/11.
|
||||
- [x] One unchanged normal gate exit0,431 files;durable landed b3fab032 and ancestry0;archive logs/hashes.
|
||||
- [x] Close backlog;release expensive slot to dispatch/interpreter.
|
||||
- [ ] Land this documentation-only closure through normal queue,then IDLE for owner local review.
|
||||
|
||||
No optional task starts. Unverified live/browser/full-modal behavior stays listed in final test log.
|
||||
Reference in new issue
Block a user