Initial snapshot before step 10 package split

This commit is contained in:
admin
2026-05-22 21:39:09 +02:00
commit e029e898e9
16 changed files with 3955 additions and 0 deletions
+695
View File
@@ -0,0 +1,695 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>rclone-jav consolidation — final converged plan</title>
<style>
:root {
color-scheme: dark;
--bg: #0c0e10;
--shell: #14171a;
--panel: #181b1e;
--surface: #1f2327;
--line: #292e33;
--line-2: #3a4148;
--text: #e1e6eb;
--muted: #8a949d;
--blue: #6ec5ff;
--green: #7de4a0;
--yellow: #ffd36c;
--red: #ff9097;
--purple: #c5a9ff;
--orange: #ffb072;
}
* { box-sizing: border-box; }
body { margin:0; background:var(--bg); color:var(--text); font:13px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
main { padding:24px; max-width:1380px; margin:0 auto; }
h1 { margin:0 0 4px; font-size:24px; }
h2 { margin:24px 0 8px; font-size:17px; color:#f4f7fa; }
h3 { margin:0 0 6px; font-size:11px; text-transform:uppercase; color:#9ba6af; letter-spacing:0.04em; }
p { margin:0; }
.intro { color:var(--muted); max-width:960px; margin:6px 0 18px; font-size:13px; }
.meta-banner { display:flex; align-items:center; gap:10px; padding:10px 14px; background:#11181f; border:1px solid #1f2b35; border-radius:6px; margin-bottom:18px; font-size:12px; color:var(--muted); }
.meta-banner .dot { width:8px; height:8px; border-radius:50%; background:var(--green); box-shadow:0 0 0 3px rgba(125,228,160,0.15); }
.meta-banner b { color:#cfdde5; }
.status-grid { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; margin-bottom:24px; }
.status-card { background:#13171b; border:1px solid #232a30; border-radius:6px; padding:12px; }
.status-card h3 { color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px; margin-bottom:8px; }
.status-card.done { border-left:3px solid var(--green); }
.status-card.todo { border-left:3px solid var(--yellow); }
.status-card.work { border-left:3px solid var(--blue); }
.status-card ul { margin:0; padding-left:16px; color:var(--muted); font-size:12px; }
.status-card ul li { margin:2px 0; }
.status-card ul li b { color:#dce5ed; font-weight:600; }
.legend { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:14px; }
.pill { border-radius:12px; padding:3px 9px; font-size:11px; border:1px solid var(--line-2); background:#22272b; color:var(--text); }
.pill.keep { color:var(--green); background:#143020; border-color:#245036; }
.pill.move { color:var(--blue); background:#132837; border-color:#284b66; }
.pill.del { color:var(--red); background:#321618; border-color:#5b2228; }
.pill.debug{ color:var(--purple); background:#241d35; border-color:#453363; }
.pill.warn { color:var(--yellow); background:#332b16; border-color:#645228; }
.pill.ctx { color:var(--orange); background:#3a2818; border-color:#7a4b25; }
.mock { border:1px solid #2c333a; border-radius:8px; background:var(--shell); overflow:hidden; }
.top { display:flex; align-items:center; justify-content:space-between; padding:11px 14px; border-bottom:1px solid var(--line); background:#0f1214; }
.brand { font-weight:700; color:#fff; font-size:14px; letter-spacing:0.01em; }
.toolbar { display:flex; gap:6px; align-items:center; }
button { border:1px solid var(--line-2); border-radius:4px; padding:5px 10px; background:#252a2e; color:var(--text); font:inherit; cursor:default; }
button.primary { background:#163923; color:#aaf3bf; border-color:#285b3a; }
button.live { background:#143247; color:#9fd9ff; border-color:#2e607f; }
button.danger { background:#3a191d; color:#ffb2b7; border-color:#722c33; }
button.ghost { background:transparent; color:#9aa4ac; border-color:#3a4148; }
.layout { display:grid; grid-template-columns: 200px minmax(0,1fr); min-height:480px; }
.side { background:#0d1013; border-right:1px solid var(--line); padding:14px 12px; }
.grp { margin-bottom:16px; }
.gtitle { color:#5e6970; text-transform:uppercase; letter-spacing:0.06em; font-size:10px; margin:0 0 6px; padding-left:6px; }
.nav { display:grid; gap:2px; }
.nav a { display:flex; align-items:center; justify-content:space-between; padding:6px 8px; border-radius:4px; color:#b3bdc4; text-decoration:none; gap:6px; }
.nav a.active { background:#27313a; color:#fff; box-shadow:inset 2px 0 var(--blue); }
.nav a:hover:not(.active) { background:#1a1f24; }
.nav .badge { font-size:10px; padding:1px 6px; border-radius:9px; background:#2d343a; color:#a7b2bb; }
.nav .badge.warn { background:#3a3017; color:#ffd784; }
.nav .badge.fresh{ background:#1d3826; color:#9be3b3; }
.content { padding:18px 20px; min-width:0; }
.heading { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; margin-bottom:14px; }
.heading .desc { color:var(--muted); font-size:12px; margin-top:3px; }
.row-actions { display:flex; gap:6px; }
.sub-tabs { display:flex; gap:0; border-bottom:1px solid var(--line); margin-bottom:14px; }
.sub-tabs span { padding:8px 14px; color:#8b95a0; font-size:12px; cursor:default; border-bottom:2px solid transparent; }
.sub-tabs span.active { color:#fff; border-bottom-color: var(--blue); }
.grid2 { display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:10px; }
.grid3 { display:grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap:10px; }
.card { background:var(--panel); border:1px solid var(--line); border-radius:6px; padding:12px; min-width:0; }
.card .meta { color:var(--muted); font-size:11px; margin-top:4px; }
.card .metric { font-size:18px; color:#fff; font-weight:600; }
.dup-list { display:grid; gap:6px; margin-top:8px; }
.dup-row { display:grid; grid-template-columns: 1fr auto auto; align-items:center; gap:8px; padding:8px 10px; background:#141a1e; border:1px solid #232a30; border-radius:4px; }
.dup-row .path { font:12px Consolas, monospace; color:#cdd6dd; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dup-row .size { font-size:11px; color:#8a949d; }
.keep-pill { font-size:10px; padding:1px 7px; border-radius:9px; background:#143b22; color:#9be3b3; border:1px solid #245036; }
.review-pill { font-size:10px; padding:1px 7px; border-radius:9px; background:#332b16; color:#ffd784; border:1px solid #645228; }
/* Decision table */
table.spec { width:100%; border-collapse:collapse; margin-top:10px; font-size:12px; }
table.spec th { text-align:left; padding:8px 10px; background:#181d22; color:#cfdde5; font-weight:600; border-bottom:1px solid #2a3138; }
table.spec td { padding:9px 10px; border-bottom:1px solid #1c2126; color:var(--text); vertical-align:top; }
table.spec tr:nth-child(even) td { background:#10141a; }
table.spec td.order { font-family:Consolas,monospace; color:var(--blue); font-weight:600; }
table.spec td.surface { color:#dce5ed; }
table.spec td .pill { font-size:10px; }
table.spec td .small { color:var(--muted); font-size:11px; display:block; margin-top:2px; }
/* Popup launcher mock */
.popup-mock { background:#0e1114; border:1px dashed #394149; border-radius:6px; padding:18px; display:grid; place-items:center; }
.popup-frame { width:340px; border:1px solid var(--line-2); border-radius:6px; background:#181b1e; padding:12px; box-shadow:0 6px 18px rgba(0,0,0,.4); }
.popup-frame .ptop { display:flex; justify-content:space-between; align-items:center; margin-bottom:8px; }
.popup-frame input { width:100%; background:#0a0c0e; border:1px solid #313840; border-radius:3px; padding:6px 8px; color:var(--text); font:12px Consolas,monospace; }
.popup-frame .pchips { display:flex; gap:5px; flex-wrap:wrap; margin-top:8px; }
.annot { color:var(--muted); font-size:11px; margin-top:10px; font-style:italic; }
/* Checklist */
.checklist { background:#13171b; border:1px solid #232a30; border-radius:6px; padding:14px; margin-top:10px; }
.checklist h3 { color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px; margin-bottom:8px; }
.checkrow { display:grid; grid-template-columns: 22px 1fr auto; gap:8px; padding:7px 0; border-top:1px solid #1c2126; align-items:start; }
.checkrow:first-of-type { border-top:0; }
.checkrow .box { width:14px; height:14px; border:1px solid #4a5560; border-radius:3px; margin-top:3px; background:#0a0c0e; }
.checkrow .what { color:var(--text); font-size:12px; }
.checkrow .what .small { color:var(--muted); font-size:11px; }
.checkrow .who { color:#9aa4ac; font-size:11px; font-style:italic; }
/* Decisions / sub-cards */
.dec { background:#13171b; border:1px solid #232a30; border-radius:7px; padding:14px; }
.dec-head { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:8px; }
.dec-head h3 { color:#dce5ed; text-transform:none; font-size:13px; letter-spacing:0; margin:0; }
.dec-verdict { color:#a8b3bb; font-size:12px; margin-top:8px; }
.dec-verdict b { color:#ddebf3; }
.decisions-2 { display:grid; grid-template-columns: 1fr 1fr; gap:12px; margin-top:10px; }
/* Sequence */
.seq-list { display:grid; gap:6px; margin-top:10px; }
.seq-list .step { display:grid; grid-template-columns: 30px 1fr auto auto; gap:10px; padding:9px 12px; background:#13171b; border:1px solid #232a30; border-radius:5px; align-items:center; }
.seq-list .num { width:24px; height:24px; border-radius:50%; background:#18354a; color:var(--blue); display:grid; place-items:center; font-weight:700; font-size:11px; }
.seq-list .why { color:var(--muted); font-size:11px; }
.seq-list .risk { font-size:10px; padding:2px 7px; border-radius:8px; }
.seq-list .risk.low { color:#9be3b3; background:#0f2218; border:1px solid #1e3b27; }
.seq-list .risk.med { color:#ffd784; background:#231d10; border:1px solid #3d3018; }
.seq-list .risk.high { color:#ffb2b7; background:#2a1216; border:1px solid #4a1f25; }
.seq-list .deps { font-size:10px; color:#7a838c; font-family:Consolas,monospace; }
code { font-family:Consolas, monospace; background:#1a1f24; padding:1px 5px; border-radius:3px; color:#cfdde5; }
.strike { text-decoration:line-through; color:#6b757d; }
@media (max-width: 900px) {
.layout { grid-template-columns: 1fr; }
.side { border-right:0; border-bottom:1px solid var(--line); }
.grid2, .grid3, .decisions-2, .status-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<main>
<h1>rclone-jav Consolidation — Final Converged Plan</h1>
<div class="meta-banner">
<span class="dot"></span>
<span><b>Status:</b> execution in progress. <b>Shipped:</b> steps 1 (Sim Dupe delete), 2 (CSS extraction), 3 (Transfer Assistant delete + Diagnostics replacement), 5 (Recent Activity + Search Troubleshooting → new Debug Tools pane). <b>Pending:</b> steps 6 (options.js split — Cache & Dup Review paired, biggest), 7a (Bulk Check standalone window), 8 (fixtures), 9 (cache contract), 10 (rc-jav.py split), 11 (host fast-path decision). See <code>D:\DEV\Extensions\Production\rclone-jav\AGENTS.md</code> "Console consolidation refactor — execution status" for current state.</span>
</div>
<div class="status-grid">
<div class="status-card done">
<h3>✓ Decided</h3>
<ul>
<li>Console / Settings / Support tri-split</li>
<li>Default landing = <b>Duplicate Review</b></li>
<li>Status badges on tabs, <b>no dashboard pane</b></li>
<li>Launcher pattern over toolbox</li>
<li>Keep Ranking nested in Dup Review</li>
<li>Sim Dupe → <b>delete</b>, samples/ HTML harness</li>
<li>Transfer wizard → <b>delete</b> after Diagnostics replacement verified</li>
<li>Bulk ID Check → <b>detached chrome.windows popup</b>, NOT a Console sidebar tab</li>
<li>Inline rule tests stay, standalone benches → Debug</li>
</ul>
</div>
<div class="status-card done">
<h3>✓ Shipped</h3>
<ul>
<li><b>Step 1:</b> Sim Dupe deleted from popup. <code>samples/sim-dupe.js</code> preserves payload.</li>
<li><b>Step 2:</b> CSS extracted → <code>options.css</code>. options.html 1179 → 794 lines.</li>
<li><b>Step 3:</b> Transfer wizard deleted. Diagnostics → Native host registration now shows Extension ID + Copy button.</li>
<li><b>Step 5:</b> Recent Activity + Search Troubleshooting moved to new Debug Tools pane. Scope verified by code read.</li>
</ul>
</div>
<div class="status-card work">
<h3>📋 Pending</h3>
<ul>
<li><b>Step 6:</b> options.js split (Cache + Dup Review paired). 3133-line file. Biggest, riskiest.</li>
<li><b>Step 7a:</b> bulk-check.html standalone + popup launcher.</li>
<li><b>Steps 810:</b> fixtures, cache contract, rc-jav.py split.</li>
<li><b>Step 11:</b> host fast-path benchmark + narrow/delete decision.</li>
</ul>
</div>
</div>
<!-- ====================================================== -->
<h2>1. Primary recommended layout</h2>
<p class="intro">Default landing = Duplicate Review (user's most-frequent maintenance workflow). Sidebar tab labels carry live status badges — no dashboard pane needed. Launcher pattern: heavy tools open focused panes, not nested fieldsets.</p>
<div class="mock">
<div class="top">
<span class="brand">rclone-jav</span>
<div class="toolbar">
<button>Profile: cq:JAV</button>
<button class="ghost"></button>
</div>
</div>
<div class="layout">
<aside class="side">
<div class="grp">
<div class="gtitle">Console</div>
<div class="nav">
<a href="#" class="active">Duplicate Review<span class="badge warn">27</span></a>
<a href="#">Cache &amp; Scans<span class="badge fresh">28m</span></a>
<a href="#">Library Issues<span class="badge">4</span></a>
</div>
<p style="color:#5e6970; font-size:10px; margin:6px 0 0 6px; font-style:italic;">Bulk Check lives in its own window — popup launcher, not sidebar.</p>
</div>
<div class="grp">
<div class="gtitle">Settings</div>
<div class="nav">
<a href="#">Profiles</a>
<a href="#">Scan Behavior</a>
<a href="#">Matching Rules</a>
<a href="#">Site Extraction</a>
<a href="#">Overlays</a>
<a href="#">Deletion</a>
</div>
</div>
<div class="grp">
<div class="gtitle">Support</div>
<div class="nav">
<a href="#">Diagnostics</a>
<a href="#">Debug Tools</a>
</div>
</div>
</aside>
<div class="content">
<div class="heading">
<div>
<h2 style="margin-top:0;">Duplicate Review <span class="pill warn" style="margin-left:6px;">27 pending</span></h2>
<p class="desc">After-upload workflow. Risky groups skipped by default. Keep Ranking lives here as configuration, not in a separate Settings tab.</p>
</div>
<div class="row-actions">
<button>Re-scan</button>
<button class="primary">Run Delete Queue (12)</button>
</div>
</div>
<div class="sub-tabs">
<span class="active">Pending Review</span>
<span>Skipped — Risky</span>
<span>Keep Ranking Rules</span>
<span>Delete History</span>
</div>
<div class="grid2">
<div class="card">
<h3>Filter (this tool only)</h3>
<div class="row-actions" style="margin-top:6px; flex-wrap:wrap;">
<button class="ghost">Multipart only</button>
<button class="ghost">VIP collision</button>
<button class="ghost">Size diff &gt; 100MB</button>
</div>
<p class="meta">Filters scoped — never exported as global settings.</p>
</div>
<div class="card">
<h3>Delete queue</h3>
<div class="metric">12 files · 47.3 GiB</div>
<p class="meta">Safety: VIP folders + multipart-risk paths auto-excluded.</p>
</div>
</div>
<div style="margin-top:12px;">
<h3>JBD-291 · 2 candidates</h3>
<div class="dup-list">
<div class="dup-row">
<span class="path">/JAV/clearjav/JBD-291 [1080p].mp4</span>
<span class="size">4.94 GiB</span>
<span class="keep-pill">KEEP</span>
</div>
<div class="dup-row">
<span class="path">/JAV/old/JBD-291.mp4</span>
<span class="size">3.82 GiB</span>
<button class="danger" style="padding:2px 8px; font-size:11px;">Queue delete</button>
</div>
</div>
</div>
<div style="margin-top:14px;">
<h3>OFJE-195 · multipart risk</h3>
<div class="dup-list">
<div class="dup-row">
<span class="path">/JAV/OFJE-195_PART1.mp4</span>
<span class="size">2.10 GiB</span>
<span class="review-pill">REVIEW</span>
</div>
<div class="dup-row">
<span class="path">/JAV/OFJE-195_PART2.mp4</span>
<span class="size">2.08 GiB</span>
<span class="review-pill">REVIEW</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- ====================================================== -->
<h2>2. Decision table (refactor spec data)</h2>
<p class="intro">Each current pane mapped to its future home, treatment, ship order, and replacement work (if any). Ship order = execution sequence within phase 3 (UI consolidation). Steps share PR scope where useful.</p>
<div class="legend">
<span class="pill keep">KEEP visible</span>
<span class="pill ctx">CONTEXTUAL (lives with feature)</span>
<span class="pill move">MOVE (relocate)</span>
<span class="pill debug">DEBUG only</span>
<span class="pill del">DELETE</span>
</div>
<table class="spec">
<thead>
<tr>
<th style="width:42px;">#</th>
<th>Current surface</th>
<th>Future home</th>
<th>Treatment</th>
<th>Replacement</th>
</tr>
</thead>
<tbody>
<tr>
<td class="order">1</td>
<td class="surface">Sim Dupe popup action</td>
<td><code>samples/popup-states.html</code> (repo file)</td>
<td><span class="pill del">DELETE</span></td>
<td><span class="small">No product replacement. Repo HTML for layout testing only.</span></td>
</tr>
<tr>
<td class="order">2</td>
<td class="surface">CSS embedded in options.html</td>
<td>Per-pane <code>.css</code> files alongside per-pane JS</td>
<td><span class="pill move">EXTRACT</span></td>
<td><span class="small">No behavior change. Reduces options.html before JS split.</span></td>
</tr>
<tr>
<td class="order">3</td>
<td class="surface">Transfer Assistant wizard</td>
<td>(gone)</td>
<td><span class="pill del">DELETE</span></td>
<td><span class="small">Replacement = Diagnostics 3 actions (see §3 checklist). Delete <em>after</em> verification.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">Cache &amp; Scans pane</td>
<td>Console → Cache &amp; Scans</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Paired with Dup Review extraction. State interface shared.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">Duplicate Review pane</td>
<td>Console → Duplicate Review <em>(default landing)</em></td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Same PR as Cache &amp; Scans. Reads cache state.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">Keep Ranking Rules pane</td>
<td>Duplicate Review → Keep Ranking Rules <em>(sub-tab)</em></td>
<td><span class="pill ctx">CONTEXTUAL</span></td>
<td><span class="small">Moves with Dup Review. Becomes nested sub-tab.</span></td>
</tr>
<tr>
<td class="order">4</td>
<td class="surface">VIP folders config</td>
<td>Duplicate Review → Keep Ranking Rules</td>
<td><span class="pill ctx">CONTEXTUAL</span></td>
<td><span class="small">Feature-specific config moves with feature.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Recent Activity (search/page history)</td>
<td>Support → Debug Tools → Search Activity</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">If audit deletion events also present, split out (pending verification).</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Search Troubleshooting</td>
<td>Support → Debug Tools</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">Standalone bench. No edit locality.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Page Extraction Test (standalone)</td>
<td>Support → Debug Tools</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">Inline "Pick Element" variant stays in Site Extraction settings.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Test ID Extraction (inline)</td>
<td>Settings → Matching Rules (collapsible per editor)</td>
<td><span class="pill ctx">CONTEXTUAL</span></td>
<td><span class="small">Editor feedback. Stays beside rule it tests.</span></td>
</tr>
<tr>
<td class="order">5</td>
<td class="surface">Test ID Extraction (standalone bench)</td>
<td>Support → Debug Tools</td>
<td><span class="pill debug">DEBUG</span></td>
<td><span class="small">Second row — split from inline version above.</span></td>
</tr>
<tr>
<td class="order">6</td>
<td class="surface">Library Issues pane</td>
<td>Console → Library Issues</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Own tab + status badge. Rename UI nested as sub-tab.</span></td>
</tr>
<tr>
<td class="order">6</td>
<td class="surface">Bulk ID Check</td>
<td><code>bulk-check.html</code> — detached <code>chrome.windows</code> popup</td>
<td><span class="pill move">RESHAPE</span></td>
<td><span class="small">Removed from Console sidebar. Single entry path = popup launcher button → opens 640×540 detached window. Different tool type than Console panes (transient utility, no sidebar context).</span></td>
</tr>
<tr>
<td class="order">7</td>
<td class="surface">Profiles, Scan Behavior, Overlays, Deletion settings</td>
<td>Settings → (separate sub-tabs)</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Settings sub-tabs split into separate JS files.</span></td>
</tr>
<tr>
<td class="order">7</td>
<td class="surface">Matching Rules / Site Extraction</td>
<td>Settings → (separate sub-tabs, inline tests retained)</td>
<td><span class="pill keep">KEEP</span></td>
<td><span class="small">Collapsible inline tester beside each rule.</span></td>
</tr>
<tr>
<td class="order">8</td>
<td class="surface">(new) Shared fixture corpus</td>
<td>Top-level <code>fixtures/</code> (neutral location)</td>
<td><span class="pill move">NEW</span></td>
<td><span class="small">Contract between extension and Python. Both consume.</span></td>
</tr>
<tr>
<td class="order">9</td>
<td class="surface">Cache contract design</td>
<td>CACHE_VERSION (exists) + ID_RULES_VERSION (new)</td>
<td><span class="pill move">NEW</span></td>
<td><span class="small">Schema bump = force rebuild. Rules bump = warn-and-mark-stale.</span></td>
</tr>
<tr>
<td class="order">10</td>
<td class="surface">rc-jav.py monolith</td>
<td><code>rcjav/</code> package (ids, cache, dupes, catalog, …)</td>
<td><span class="pill move">SPLIT</span></td>
<td><span class="small">After fixtures + tests + cache contract exist.</span></td>
</tr>
<tr>
<td class="order">11</td>
<td class="surface">Host fast-path search</td>
<td>Narrow / Delete / Keep — based on §4 benchmark</td>
<td><span class="pill warn">DECIDE</span></td>
<td><span class="small">Benchmark idle + under-scan latency first.</span></td>
</tr>
</tbody>
</table>
<!-- ====================================================== -->
<h2>3. Pre-execution checklists (user handoffs)</h2>
<div class="decisions-2">
<div class="checklist">
<h3>Diagnostics replacement verification (gates step 3 — Transfer wizard delete)</h3>
<div class="checkrow"><span class="box"></span><span class="what">Current extension ID shown as one-line text with copy-to-clipboard button<div class="small">Replaces wizard's "your extension ID is…" step.</div></span><span class="who">user opens<br>Diagnostics</span></div>
<div class="checkrow"><span class="box"></span><span class="what">Button labeled "Re-register host" that triggers register-host.bat path<div class="small">Replaces wizard's "run this script" step.</div></span><span class="who">user opens<br>Diagnostics</span></div>
<div class="checkrow"><span class="box"></span><span class="what">Verification result shown inline within 2s of register click<div class="small">Replaces wizard's "now check the result" step.</div></span><span class="who">user opens<br>Diagnostics</span></div>
<div class="checkrow"><span class="box"></span><span class="what">All three above visible without expanding collapsed sections (one screen)<div class="small">If buried in expandable cards, write better UI first.</div></span><span class="who">visual<br>inspection</span></div>
</div>
<div class="checklist">
<h3>Recent Activity scope test (settles split question)</h3>
<div class="checkrow"><span class="box"></span><span class="what">Open Recent Activity. Note current entry types visible.<div class="small">LIVE search, CACHE search, MATCH, NO_MATCH, NO_ID, page-check, etc.</div></span><span class="who">user</span></div>
<div class="checkrow"><span class="box"></span><span class="what">Perform a delete in Duplicate Review. Refresh Recent Activity.<div class="small">Single delete operation, any candidate.</div></span><span class="who">user</span></div>
<div class="checkrow"><span class="box"></span><span class="what">If delete event appears → audit value exists. Split into Dup Review → Delete History.<div class="small">If no → single role. Move entire log to Debug Tools.</div></span><span class="who">user reports</span></div>
</div>
</div>
<p class="annot">Cosmetic remaining: popup launcher button label "Bulk Check" vs icon-only. Either works. Default to label until popup row gets crowded.</p>
<!-- ====================================================== -->
<h2>4. Bulk Check — detached window pattern</h2>
<p class="intro">User clarified: Bulk Check is a transient utility, not a persistent Console surface. Doesn't fit sidebar-tab pattern alongside Dup Review / Cache &amp; Scans / Library Issues. Decision: standalone <code>bulk-check.html</code> opened as detached <code>chrome.windows</code> popup, no Console sidebar entry. Single canonical entry path = popup launcher button.</p>
<div class="grid2" style="margin-top:14px;">
<div>
<h3 style="text-transform:none; letter-spacing:0; font-size:13px; color:#dce5ed; margin-bottom:8px;">Browser-action popup with launcher</h3>
<div class="popup-mock">
<div class="popup-frame">
<div class="ptop">
<b style="color:#fff; font-size:13px;">rclone-jav</b>
<button class="ghost" style="padding:2px 8px; font-size:11px;"></button>
</div>
<input value="BLK-474" />
<div class="pchips">
<button class="primary" style="padding:3px 10px; font-size:11px;">Search</button>
<button class="live" style="padding:3px 10px; font-size:11px;">📋 Bulk Check…</button>
<button class="ghost" style="padding:3px 10px; font-size:11px;"></button>
</div>
<div class="annot" style="margin-top:10px;">Single-search stays primary. Bulk button = one click to detached window.</div>
</div>
</div>
</div>
<div>
<h3 style="text-transform:none; letter-spacing:0; font-size:13px; color:#dce5ed; margin-bottom:8px;">Detached window (640×540) after launch</h3>
<div class="popup-mock" style="padding:10px;">
<div style="width:480px; max-width:100%; background:#181b1e; border:1px solid var(--line-2); border-radius:6px; box-shadow:0 8px 24px rgba(0,0,0,.5); overflow:hidden;">
<div style="display:flex; justify-content:space-between; align-items:center; background:#0f1214; border-bottom:1px solid var(--line); padding:8px 12px;">
<b style="color:#fff; font-size:13px;">Bulk ID Check</b>
<div style="display:flex; gap:4px;">
<button class="ghost" style="padding:2px 7px; font-size:11px;">_</button>
<button class="ghost" style="padding:2px 7px; font-size:11px;"></button>
<button class="ghost" style="padding:2px 7px; font-size:11px;">×</button>
</div>
</div>
<div style="padding:12px;">
<textarea style="width:100%; height:90px; background:#0a0c0e; border:1px solid #313840; border-radius:3px; padding:7px 9px; color:var(--text); font:12px Consolas,monospace; resize:vertical;">BLK-474
FC2-PPV-1841460
KV-118
PRTD-029
JBD-291</textarea>
<div class="row-actions" style="margin-top:8px;">
<button class="primary" style="font-size:12px;">Check 5 IDs</button>
<button style="font-size:12px;">Clear</button>
<button class="ghost" style="font-size:12px;">Import .txt…</button>
</div>
<div style="margin-top:12px; padding:8px 10px; background:#0f1518; border:1px solid #1d2a30; border-radius:4px; font-size:11px; color:var(--muted);">
5 IDs checked · <span style="color:#9be3b3;">3 match</span> · <span style="color:#ffd784;">2 no match</span>
</div>
<div class="dup-list" style="margin-top:8px;">
<div class="dup-row" style="padding:6px 8px;"><span class="path">BLK-474</span><span class="size">4.94 GiB</span><span class="keep-pill">MATCH</span></div>
<div class="dup-row" style="padding:6px 8px;"><span class="path">KV-118</span><span class="size">multi-part</span><span class="keep-pill">MATCH</span></div>
<div class="dup-row" style="padding:6px 8px;"><span class="path">PRTD-029</span><span class="size"></span><span class="review-pill">NO MATCH</span></div>
</div>
</div>
</div>
</div>
<p class="annot">Detached window. No tab bar, no address bar. Closes cleanly when done. Sits over browser, stays visible across tab switches.</p>
</div>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:14px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Why detached window, not Console tab</h3>
<div class="grid2" style="margin-top:8px;">
<div>
<p class="meta" style="font-size:11px;"><b style="color:#cfdde5;">Other Console tools (Dup Review, Cache &amp; Scans, Library Issues):</b></p>
<ul style="color:var(--muted); font-size:11px; margin:6px 0 0 16px; padding:0;">
<li>long workflows, multi-pass</li>
<li>need sidebar context (compare to other tools)</li>
<li>persistent state (review queue, scan job)</li>
<li>fit Options sidebar tab pattern</li>
</ul>
</div>
<div>
<p class="meta" style="font-size:11px;"><b style="color:#cfdde5;">Bulk Check:</b></p>
<ul style="color:var(--muted); font-size:11px; margin:6px 0 0 16px; padding:0;">
<li>short workflow, one-shot</li>
<li>no sidebar context needed</li>
<li>transient state (last-paste persisted, results ephemeral)</li>
<li>fits detached-window pattern</li>
</ul>
</div>
</div>
<p class="annot" style="margin-top:10px;">Different tool type. Treating it like Dup Review was a category error. Single user knows the feature exists — discovery via popup button is enough.</p>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:10px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Implementation notes</h3>
<pre style="font-family:Consolas,monospace; font-size:11px; color:#cfdde5; background:#0a0c0e; padding:10px; border-radius:4px; margin:8px 0 0; overflow-x:auto; white-space:pre-wrap;">// Popup launcher click handler
chrome.windows.create({
url: chrome.runtime.getURL('bulk-check.html'),
type: 'popup',
width: 640,
height: 540
});</pre>
<ul style="color:var(--muted); font-size:12px; margin:8px 0 0 16px; padding:0;">
<li><b style="color:#dce5ed;">Window dedup:</b> track open bulk-check window ID in <code>chrome.storage.session</code>. Second launcher click focuses existing window instead of spawning duplicate.</li>
<li><b style="color:#dce5ed;">State persistence:</b> last paste saved to <code>chrome.storage.local</code> key <code>bulk_check_last_paste</code>. Reopen restores. Results are ephemeral (re-run on reopen).</li>
<li><b style="color:#dce5ed;">Backend reuse:</b> calls native host via same messaging path popup search uses. No new backend code.</li>
<li><b style="color:#dce5ed;">No back nav:</b> window can't navigate. User closes when done. Ctrl+W closes the bulk window, not a browser tab.</li>
</ul>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:10px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Edge cases</h3>
<ul style="color:var(--muted); font-size:12px; margin:8px 0 0 16px; padding:0;">
<li><b style="color:#dce5ed;">Popup auto-closes after launcher click</b> (Chrome behavior). Window survives. Good — that's the intent.</li>
<li><b style="color:#dce5ed;">Window positioning unreliable.</b> Chrome treats <code>left/top</code> as hints, multi-monitor users may get the window on the wrong screen. Acceptable for personal-use tool.</li>
<li><b style="color:#dce5ed;">Brave / Edge variance.</b> Detached popups behave slightly differently across Chromium forks. Test on user's actual browser before shipping. Fallback if broken: open <code>bulk-check.html</code> in a normal tab via <code>chrome.tabs.create</code>.</li>
</ul>
</div>
<div class="card" style="background:#13171b; border:1px solid #232a30; margin-top:10px;">
<h3 style="color:#dce5ed; text-transform:none; letter-spacing:0; font-size:13px;">Does NOT generalize</h3>
<p class="meta" style="font-size:12px;">Detached-window pattern fits Bulk Check because it's transient + no-sidebar-context + short. Doesn't apply to:</p>
<ul style="color:var(--muted); font-size:12px; margin:8px 0 0 16px; padding:0;">
<li>Diagnostics — reference info, lives in sidebar fine</li>
<li>Setup repair button — already inline in Diagnostics, small enough</li>
<li>Dup Review / Cache &amp; Scans / Library Issues — long workflows, sidebar context useful</li>
<li>Settings — set-and-forget, not workflow</li>
</ul>
<p class="annot" style="margin-top:10px;">One-tool answer, not a pattern across the app.</p>
</div>
<!-- ====================================================== -->
<h2>5. Execution sequence (final)</h2>
<p class="intro">Codex's revised order (triage first, boundary doc second) with my refinements. Risk and dependencies marked. Steps 14 are reversible single-file changes (warmup phase). Steps 510 = structural. Step 11 = final architectural call.</p>
<div class="seq-list">
<div class="step"><span class="num">1</span><div><b>Per-pane triage</b> <span class="why">— 30 min with user. Decision table above IS this artifact.</span></div><span class="risk low">zero risk</span><span class="deps">no deps</span></div>
<div class="step"><span class="num">2</span><div><b>Boundary ownership doc</b> <span class="why">— extension extracts query ID, Python owns filename semantics, host adapts. 1 hour, no code.</span></div><span class="risk low">zero risk</span><span class="deps">after #1</span></div>
<div class="step"><span class="num">3</span><div><b>Host fast-path benchmark</b> <span class="why">— latency under idle Python AND under scanning Python. Result gates step 11.</span></div><span class="risk low">measure only</span><span class="deps">no deps</span></div>
<div class="step"><span class="num">4</span><div><b>Delete confirmed surfaces</b> <span class="why">— Sim Dupe popup button (no replacement), Transfer wizard (after Diagnostics verification passes).</span></div><span class="risk low">trivial</span><span class="deps">after §3 checklist</span></div>
<div class="step"><span class="num">5</span><div><b>CSS extraction from options.html</b> <span class="why">— per-pane CSS files. No behavior change. Bisect-friendly.</span></div><span class="risk low">low</span><span class="deps">after #4</span></div>
<div class="step"><span class="num">6</span><div><b>options.js split: Cache &amp; Dup Review paired</b> <span class="why">— Dup Review reads cache state. Single PR extracts both. Keep Ranking moves with Dup Review.</span></div><span class="risk med">moderate</span><span class="deps">after #5</span></div>
<div class="step"><span class="num">7</span><div><b>options.js split: Debug Tools + Library Issues + Settings sub-tabs</b> <span class="why">— remaining Options extractions. Inline test components reused across rule editors. Bulk Check is NOT here — it's a new standalone file (step 7a).</span></div><span class="risk med">moderate</span><span class="deps">after #6</span></div>
<div class="step"><span class="num">7a</span><div><b>Create <code>bulk-check.html</code> standalone + popup launcher button</b> <span class="why">— new HTML file, own JS module, no Options dependency. Popup gets one button calling <code>chrome.windows.create</code>. Window dedup + state persistence in <code>chrome.storage</code>.</span></div><span class="risk low">additive</span><span class="deps">parallel to #7</span></div>
<div class="step"><span class="num">8</span><div><b>Shared fixture corpus</b> <span class="why">— top-level <code>fixtures/</code> (neutral). Python and extension both consume.</span></div><span class="risk low">additive</span><span class="deps">no blocking</span></div>
<div class="step"><span class="num">9</span><div><b>Cache contract design</b> <span class="why">— CACHE_VERSION (exists) + ID_RULES_VERSION (new). Schema vs semantics, two concepts.</span></div><span class="risk med">design decision</span><span class="deps">before #10</span></div>
<div class="step"><span class="num">10</span><div><b>rc-jav.py module split</b> <span class="why">— ids.py, cache.py, dupes.py, catalog.py, rclone_io.py, cli.py. Tests pre-exist via #8.</span></div><span class="risk med">code churn</span><span class="deps">after #8, #9</span></div>
<div class="step"><span class="num">11</span><div><b>Host narrow / keep / delete</b> <span class="why">— based on #3 benchmark. If under-scan responsiveness depends on host = keep narrow. If not = delete.</span></div><span class="risk high">behavior change</span><span class="deps">after #3, #10</span></div>
</div>
<!-- ====================================================== -->
<h2>6. Acceptance criteria template</h2>
<p class="intro">Each step in the sequence needs three things in the final spec: acceptance criterion, rollback procedure, touched-files list. Without these, "ship order N" is a wish not a plan. Template below — fill per step in spec doc.</p>
<div class="card" style="background:#13171b; border:1px solid #232a30;">
<h3>Template per sequence step</h3>
<div style="font-family:Consolas,monospace; font-size:12px; color:#cfdde5; background:#0a0c0e; padding:12px; border-radius:4px; margin-top:8px; white-space:pre-wrap;">step: 6
title: options.js split — Cache &amp; Dup Review paired
touched_files:
- options.html (script tag order changes)
- options.js (DELETE: cache section, dup review section, keep ranking section)
- options-cache.js (NEW)
- options-review.js (NEW)
- options-core.js (NEW: shared helpers, pane nav, save/load)
acceptance:
- Fresh extension reload, options.html opens
- Default landing = Duplicate Review tab
- Cache &amp; Scans tab loads, shows last scan timestamp
- Run Duplicate Review on existing cache — same result set as pre-refactor
- Keep Ranking Rules sub-tab inside Dup Review opens
- No console errors on load or interaction
rollback:
- git revert &lt;sha&gt;
- No data migration. Cache schema unchanged. Storage keys unchanged.
- Diagnostics-verified replacement of Transfer wizard remains intact (step 3 already shipped).</div>
</div>
<!-- ====================================================== -->
<h2>7. Out of scope (explicitly rejected)</h2>
<ul style="color:var(--muted); margin:0 0 30px 18px; font-size:13px;">
<li><b style="color:#dce5ed;">Dashboard pane</b> — tab badges replace. Adding a dashboard creates a feature sink.</li>
<li><b style="color:#dce5ed;">After-Upload workflow wizard page</b> — sidebar nav order already encodes the workflow.</li>
<li><b style="color:#dce5ed;">Matching Lab consolidation page</b> — inline tests cover editor needs, standalone bench in Debug covers diagnostic needs.</li>
<li><b style="color:#dce5ed;">Mode switcher top bar (Console / Settings / Support segmented control)</b> — sidebar groups do this.</li>
<li><b style="color:#dce5ed;">In-extension Sim Dupe / Debug Preview page</b> — repo HTML file is enough for single-user layout work.</li>
<li><b style="color:#dce5ed;">Popup bulk mode toggle</b> — popup stays single-job. Launcher button opens detached window, no inline bulk mode.</li>
<li><b style="color:#dce5ed;">Bulk ID Check as Console sidebar tab</b> — wrong tool type for sidebar pattern. Detached window matches its transient nature.</li>
<li><b style="color:#dce5ed;">Bulk Check as Options-page deep-link tab</b> — previously considered. Rejected: leaves a leftover tab open after use, Options sidebar adds noise to a one-shot tool.</li>
<li><b style="color:#dce5ed;">Frontend framework (React/Vue/Svelte)</b> — vanilla + ordered script files is correct for MV3 + project scale.</li>
<li><b style="color:#dce5ed;">Console.log telemetry for usage audit</b> — manual triage of single-user project beats instrumented signals.</li>
</ul>
<h2>8. Net position</h2>
<p class="intro" style="margin-bottom:30px;">Architecture decided. Three small user handoffs remain (Diagnostics verification, Recent Activity scope check, popup button label). After those, decision table expands into per-step spec with acceptance + rollback. Code work begins on step 1 (smallest, fastest, lowest risk). Total estimated execution span: phased over multiple PRs, no big-bang refactor.</p>
</main>
</body>
</html>