f7fc15b17c
Includes: - cli.py path fix (parents[1]) for config/catalog resolution - Library cleanup feature design docs (TODO.md, mockup) - Audit + bug-queue markdowns from May 2026 reliability pass - .gitignore expanded for transient artifacts
9.6 KiB
9.6 KiB
Verification — Phase 3 — 2026-05-25
Original snapshot: audit-snapshot-2026-05-24T15-55Z.md
Final snapshot: same code-of-record + 13 manifest bumps (0.1.33 → 0.1.45 inclusive) + 1 CLI-only no-bump fix
Fix summary (all bugs in audit queue)
Severe (1/1 fixed)
- S-1 (opts): Export silently drops
keep_ranking→ backup data loss. FIXED v0.1.33 atsrc/options/options.js:386-447. Export now blocks onget-keep-rankingRPC failure; success path writes_meta.host_config.keep_ranking. Verified: failure path shows clear block message + no file; success path produces JSON with full keep_ranking populated.
Moderate (7/7 fixed)
- M-1 (opts):
sanitizeImportedSettingselement validation gap → content-script crash on malformed import. FIXED v0.1.34 atsrc/options/options.js:552-633. AddedARRAY_ELEMENT_VALIDATORSfor siteAdapters / idNormalizers / partPatterns / knownSitePatterns / profiles. Verified: malformed import showssiteAdapters[0](malformed)in modal; good entry survives; runtime test confirmed. - M-2 (bg): Context menu missing after MV3 SW eviction. FIXED v0.1.36 at
background.js:1193(top-levelensureContextMenu()call). Verified: right-click on google.com after SW lifecycle shows full rclone-jav menu. - M-3 (host):
handle_scanreturned success before Popen could fail. FIXED v0.1.37 athost/rcjav-host.py:2053-2306. Per-invocationthreading.Event+spawn_resultdict; 500 ms wait; synchronous failure surfacing. Verified via instrumentedraise FileNotFoundError("simulated spawn fail")runtime test — UI showedscan failed: FileNotFoundError: simulated spawn failsynchronously; instrumentation reverted. - M-4 (host):
post_discord_alertblocked main loop 5 s on slow Discord. FIXED v0.1.39 athost/rcjav-host.py:174-289. Refactored to_discord_post_worker+_build_discord_body; real alerts threaded fire-and-forget; test RPC waits 6 s with explicit timeout error. Outcomes logged withalert_source. Verified runtime: Test (host) returned synchronousHTTP 401for bogus token +HTTP 204for valid; events.log hasdiscord_postwith all fields. - M-5 (popup): Profile selector race overwrites with stale results. FIXED v0.1.40 + 0.1.41 follow-up at
src/popup/popup.js. Monotonic_currentSearchIdgate inrunCheck+runManualSearch; bumped BEFORE paused early-exit. Verified: unit tests 5/5 pass; stale callbacks bail before any UI write. - M-6 (bg):
recordRpcrace loses log entries. FIXED v0.1.42 atbackground.js:155-180. Promise-chain lock around the body. Verified via simulated-storage smoke test: unlocked 1/5 preserved, locked 5/5 preserved. - M-7 (CLI):
save_configno retry — Windows AV lock crashes--save. FIXED (no manifest bump — CLI repo only) atrcjav/cli.py:186-194. Mirroredsave_cache's retry. Verified 3/3 smoke tests.
Light (1/6 fixed; 5 deferred)
- L-1 (bg):
maybeNotifyHostErrorrate-limit race over-notification. FIXED v0.1.43 atbackground.js:191-247. Dedicated_hostAlertLockaround rate-limit + notification + Discord paths. Verified: unlocked 5/5 fire (bug confirmed), locked 1/5 fire (correct), sequential locked still rate-limited. - L-2 → L-6 (deferred): cosmetic / UX polish — Discord visibility passive UI, stderr 5 s stale on rc-jav stall, expectedId state leak, history chip during modal, Clear button modal stays open. None block S/M user workflows; all have documented workarounds. Tracked in respective
bugs-*.mdfiles for a future polish pass.
Phase 3 re-audit: bug introduced by M-3 fix, caught and fixed
Re-audit of Phase 2 modified files (background.js, options.js, popup.js, rcjav-host.py, cli.py, manifest.json) by a fresh-context Explore agent surfaced one introduced bug:
- M-3 spawn race:
_scan_workersignaledspawn_eventBEFORE assigning_scan_proc = procunder_scan_lock. A cancel arriving in the ~1-5 ms window between signal and assignment would read_scan_proc = None, return "no scan running", and never write the cancel flag — scan would run to completion uninterruptable. - FIXED v0.1.44 at
host/rcjav-host.py:2186-2196. Reordered:_scan_proc = proc(under_scan_lock) now happens BEFOREspawn_event.set(). handle_scan still gets the spawn-ok signal; cancel handler now sees a live_scan_procreference.
No other introduced bugs found. Phase 2 fix code passed scrutiny on:
- Lock nesting (3 independent locks:
_rpcLogLock,_hostAlertLock,_contextMenuLock, plus new_activityLogLock— no path holds two simultaneously) - Closure capture (each lock chain
.then()captures its ownentry/now/etc.) - Unhandled rejection paths (try/catch inside chains; one failure doesn't poison future calls)
- Thread leaks (M-4 rate-limit check runs BEFORE thread spawn)
- M-1 validator backward compat (v1 exports without
source/targetkeys accepted via|| []consumer pattern) - M-5 popup counter (popup is short-lived; counter doesn't need cross-session persistence)
- M-7 retry not infinite (single retry, then re-raises on persistent failure)
- Manifest JSON validity (semver, no trailing commas)
Mirror checks resolved
| Bug | Mirror flagged | Status |
|---|---|---|
| S-1 | other RPC-sourced _meta.host_config data |
None exist beyond keep_ranking. Resolved (nothing to mirror). |
| M-1 | profiles[] + partPatterns[] | Both covered in same commit via ARRAY_ELEMENT_VALIDATORS. Resolved. |
| M-2 | other Chrome APIs needing re-register per SW boot | chrome.alarms persistent, chrome.commands manifest-declared. contextMenus is the outlier. Resolved. |
| M-3 | none flagged | n/a |
| M-4 | extension-side postDiscordAlert parity |
Verified: extension-side already uses fetch(...).catch(...) fire-and-forget. Parity confirmed. Resolved. |
| M-5 | other search entry points | All 6 entry points (search-go, Enter, history chip, profile change, search-clear, pause-while-inflight) funnel through runCheck/runManualSearch. Covered. Resolved. |
| M-6 | options.js settings save / options-library-issues.js / activity log / tabvault | recordActivity had same race — FIXED v0.1.45 at background.js:613-635 with dedicated _activityLogLock. options.js settings save is user-triggered (single SAVE click), low race risk. options-library-issues.js only does set (no get-then-set). Tabvault out-of-scope (separate project). Resolved. |
| M-7 | other os.replace callsites in rcjav/ |
Only save_cache and save_config use os.replace. Both now have retry. Resolved. |
| L-1 | same as M-6 | Covered via recordActivity mirror fix above. Resolved. |
Residual risk
- Deferred Lights (5). Documented as cosmetic / UX polish. None block user workflows. Pass-through risk acceptable.
- M-3 timeout-path response shape change. Added
startup_pending: trueon Popen timeout. Backward-compatible — existing UI ignores unknown keys. If future UI work parses this field, behavior locked in. - Phase 3 re-audit blind spot. Auditor instructed to focus on introduced bugs, not pre-existing. Pre-existing bugs in unmodified files (e.g. tabvault, rc-jav internals beyond cli.py) were not re-checked. Those remain in their respective audit-out-of-scope notes.
- Brave-specific divergence from Chrome contracts. Several REFUTED candidates noted that if Brave is observed diverging from documented Chrome behavior (SW lifecycle, connectNative keepalive), some refuted bugs could re-emerge as Brave-specific. Not currently verified; flagged in chunk-3 candidate notes.
- Manifest version chip semantics. Each fix bumped manifest per the project's reload-verification signal rule. Total 13 bumps (0.1.33 → 0.1.45 inclusive) covering: S-1, M-1, branding follow-up, M-2, M-3, M-2 follow-up (lock), M-4, M-5, M-5 follow-up (paused), M-6, L-1, M-3 follow-up (spawn race introduced + fixed in Phase 3), and M-6 mirror (recordActivity). M-7 had no bump (CLI repo only).
Final pass
- Files modified during Phase 2 + 3:
D:\DEV\Extensions\Production\rclone-jav\background.js(M-2 + M-6 + L-1 + M-2 follow-up + M-6 mirror)D:\DEV\Extensions\Production\rclone-jav\src\options\options.js(S-1 + M-1 + branding)D:\DEV\Extensions\Production\rclone-jav\src\popup\popup.js(M-5 + M-5 follow-up)D:\DEV\Extensions\Production\rclone-jav\host\rcjav-host.py(M-3 + M-4 + M-3 fix-of-fix)D:\DEV\Extensions\Production\rclone-jav\manifest.json(13 bumps: 0.1.33, 0.1.34, 0.1.35, 0.1.36, 0.1.37, 0.1.38, 0.1.39, 0.1.40, 0.1.41, 0.1.42, 0.1.43, 0.1.44, 0.1.45)D:\DEV\Project\rclone-jav\rcjav\cli.py(M-7)
- Independent re-audit by fresh Explore agent: 1 introduced bug found (M-3 spawn race) → fixed in v0.1.44. Final re-audit pass on the M-3 fix: trivial reorder of two adjacent blocks, no further issues.
- All
bugs-*.mdfiles: zero entries with statusopenexcept deferred Lights (L-2 through L-6 — 5 entries; intentionally deferred per Phase 2 close decision). - Extension
manifest.jsonversion: 0.1.45 (was 0.1.32 at audit start). - Test instrumentation residue check: no
simulated spawn fail/M-3 TEST/REMOVEmarkers remain in any source file. - JS syntax (
node --check): background.js, options.js, popup.js, options/* all pass. - Python syntax (
py_compile): rcjav-host.py, rcjav/cli.py pass.
Verification verdict
Phase 2 + 3 closed. All Severe + Moderate fixed and runtime-verified. 1 of 6 Lights fixed (L-1, same bug class as M-6). 1 introduced bug surfaced and fixed during Phase 3 re-audit. All mirror checks resolved or scoped out. 5 cosmetic Lights deferred.
Next polish session (out of audit scope): L-2 through L-6 if/when prioritized.