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
84 lines
9.6 KiB
Markdown
84 lines
9.6 KiB
Markdown
# 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** at `src/options/options.js:386-447`. Export now blocks on `get-keep-ranking` RPC 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):** `sanitizeImportedSettings` element validation gap → content-script crash on malformed import. **FIXED v0.1.34** at `src/options/options.js:552-633`. Added `ARRAY_ELEMENT_VALIDATORS` for siteAdapters / idNormalizers / partPatterns / knownSitePatterns / profiles. Verified: malformed import shows `siteAdapters[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-level `ensureContextMenu()` call). Verified: right-click on google.com after SW lifecycle shows full rclone-jav menu.
|
|
- **M-3 (host):** `handle_scan` returned success before Popen could fail. **FIXED v0.1.37** at `host/rcjav-host.py:2053-2306`. Per-invocation `threading.Event` + `spawn_result` dict; 500 ms wait; synchronous failure surfacing. Verified via instrumented `raise FileNotFoundError("simulated spawn fail")` runtime test — UI showed `scan failed: FileNotFoundError: simulated spawn fail` synchronously; instrumentation reverted.
|
|
- **M-4 (host):** `post_discord_alert` blocked main loop 5 s on slow Discord. **FIXED v0.1.39** at `host/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 with `alert_source`. Verified runtime: Test (host) returned synchronous `HTTP 401` for bogus token + `HTTP 204` for valid; events.log has `discord_post` with 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 `_currentSearchId` gate in `runCheck` + `runManualSearch`; bumped BEFORE paused early-exit. Verified: unit tests 5/5 pass; stale callbacks bail before any UI write.
|
|
- **M-6 (bg):** `recordRpc` race loses log entries. **FIXED v0.1.42** at `background.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_config` no retry — Windows AV lock crashes `--save`. **FIXED (no manifest bump — CLI repo only)** at `rcjav/cli.py:186-194`. Mirrored `save_cache`'s retry. Verified 3/3 smoke tests.
|
|
|
|
### Light (1/6 fixed; 5 deferred)
|
|
- **L-1 (bg):** `maybeNotifyHostError` rate-limit race over-notification. **FIXED v0.1.43** at `background.js:191-247`. Dedicated `_hostAlertLock` around 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-*.md` files 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_worker` signaled `spawn_event` BEFORE assigning `_scan_proc = proc` under `_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 BEFORE `spawn_event.set()`. handle_scan still gets the spawn-ok signal; cancel handler now sees a live `_scan_proc` reference.
|
|
|
|
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 own `entry`/`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`/`target` keys 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
|
|
|
|
1. **Deferred Lights (5).** Documented as cosmetic / UX polish. None block user workflows. Pass-through risk acceptable.
|
|
2. **M-3 timeout-path response shape change.** Added `startup_pending: true` on Popen timeout. Backward-compatible — existing UI ignores unknown keys. If future UI work parses this field, behavior locked in.
|
|
3. **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.
|
|
4. **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.
|
|
5. **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-*.md` files: zero entries with status `open` except deferred Lights** (L-2 through L-6 — 5 entries; intentionally deferred per Phase 2 close decision).
|
|
- **Extension `manifest.json` version: 0.1.45** (was 0.1.32 at audit start).
|
|
- **Test instrumentation residue check:** no `simulated spawn fail` / `M-3 TEST` / `REMOVE` markers 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.
|