<!doctype html>
<html lang="vi">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Completion — DevCleaner Settings focus</title>
<link rel="stylesheet" href="/assets/report.css">
<link rel="stylesheet" href="../../.claude/skills/html-report/assets/report.css">
</head>
<body>
<header>
<div class="head-inner">
<span class="eyebrow">Bug fix · live focus verified</span>
<h1>DevCleaner — <em>Settings tự focus</em></h1>
<p class="subtitle">Bấm Settings từ menu bar giờ đóng MenuBarExtra popover, đưa cửa sổ Settings lên trước
app khác và biến nó thành focused/main window để nhận bàn phím, click ngay lập tức.</p>
<div class="meta">
<span>📅 2026-07-12 10:04 +07</span>
<span>📦 <code>/Applications/DevCleaner.app</code></span>
<span>🧪 21/21 Swift tests</span>
<span><span class="badge ok">AX focus pass</span></span>
</div>
</div>
</header>
<main>
<section class="panel ok">
<h2>Kết quả</h2>
<p class="lead"><b>Settings không còn mở phía sau popover hoặc app khác.</b> Runtime test bắt đầu khi
Finder đang active, mở DevCleaner menu rồi bấm Settings. Popover biến mất; Settings xuất hiện ở foreground,
được Accessibility xác nhận là focused window và main window.</p>
<div class="cards">
<div class="card ok"><span class="num">1/1</span><span class="label">Popover dismissed</span></div>
<div class="card ok"><span class="num">true</span><span class="label">AXMain</span></div>
<div class="card ok"><span class="num">Settings</span><span class="label">AXFocusedWindow</span></div>
<div class="card ok"><span class="num">21/21</span><span class="label">Swift tests</span></div>
</div>
<div class="callout warn">
<span><strong>Safety boundary:</strong> test chỉ điều khiển cửa sổ. Không chạy clean hoặc purge; 61 safety
holds / 189.829.799.936 bytes vẫn còn nguyên.</span>
</div>
</section>
<section class="panel">
<h2>Mục lục</h2>
<div class="toc">
<a href="#rca">1 — RCA</a>
<a href="#fix">2 — Fix contract</a>
<a href="#proof">3 — Runtime proof</a>
<a href="#gates">4 — Verification gates</a>
</div>
</section>
<section id="rca" class="panel warn">
<h2><span class="num">1</span>RCA</h2>
<table class="zebra">
<thead><tr><th>Layer</th><th>Observed behavior</th><th>Nguyên nhân</th></tr></thead>
<tbody>
<tr><td><code>SettingsLink</code></td><td>Settings scene được tạo/hiện.</td><td>Không bảo đảm activation/key ordering cho app <code>LSUIElement</code>.</td></tr>
<tr><td>MenuBarExtra</td><td>Popover vẫn nổi phía trên Settings.</td><td>Popover là <code>NSPanel</code> có window level riêng.</td></tr>
<tr><td>Focus timing</td><td>Focus ngay trong tap có thể nuốt click.</td><td>Đóng panel trước khi SettingsLink hoàn tất action tạo scene.</td></tr>
<tr><td>macOS process state</td><td>Process có thể báo <code>frontmost=false</code>.</td><td>Đây là hành vi bình thường của app agent; key/main window mới là tín hiệu focus đúng.</td></tr>
</tbody>
</table>
</section>
<section id="fix" class="panel info">
<h2><span class="num">2</span>Fix contract</h2>
<ol class="steps">
<li>Tap Settings lên lịch activation sau 100 ms để SettingsLink hoàn tất trước.</li>
<li><code>SettingsView.onAppear</code> chạy cùng coordinator làm fallback cho lần mở đầu tiên.</li>
<li>Coordinator retry ở 50/100/200/350 ms khi SwiftUI scene chưa tạo xong window.</li>
<li>Chỉ chọn cửa sổ titled, keyable và không phải <code>NSPanel</code>.</li>
<li>Mọi menu panels được <code>orderOut</code> trước khi Settings được <code>makeKeyAndOrderFront</code>.</li>
<li><code>orderFrontRegardless</code> bảo đảm Settings không nằm sau app đang active.</li>
</ol>
<div class="callout ok">
<span><strong>macOS-native boundary:</strong> không đổi activation policy của app menu bar, không tạo Dock
icon và không phụ thuộc title text/localization để tìm Settings window.</span>
</div>
</section>
<section id="proof" class="panel ok">
<h2><span class="num">3</span>Runtime proof</h2>
<table class="kv">
<tr><th>Starting app</th><td>Finder active, DevCleaner Settings chưa mở.</td></tr>
<tr><th>Interaction</th><td>Mở status menu → bấm <code>Settings…</code>.</td></tr>
<tr><th>Popover</th><td>Không còn visible sau Settings action.</td></tr>
<tr><th>Window name</th><td><code>DevCleaner Settings</code>.</td></tr>
<tr><th>Accessibility focus</th><td><code>AXFocusedWindow = DevCleaner Settings</code>.</td></tr>
<tr><th>Main state</th><td><code>AXMain = true</code>.</td></tr>
<tr><th>Visual state</th><td>Settings ở foreground; traffic-light controls active, popover không che.</td></tr>
</table>
</section>
<section id="gates" class="panel ok">
<h2><span class="num">4</span>Verification gates</h2>
<table class="zebra">
<thead><tr><th>Gate</th><th>Kết quả</th><th>Evidence</th></tr></thead>
<tbody>
<tr><td>Swift format strict</td><td><span class="badge ok">Pass</span></td><td>Sources và tests.</td></tr>
<tr><td>Swift tests</td><td><span class="badge ok">21/21</span></td><td>Panel-vs-titled-window regression included.</td></tr>
<tr><td>Release app build</td><td><span class="badge ok">Pass</span></td><td>Installed bundle rebuilt.</td></tr>
<tr><td>Deep/strict codesign</td><td><span class="badge ok">Pass</span></td><td><code>/Applications/DevCleaner.app</code>.</td></tr>
<tr><td>Live focus flow</td><td><span class="badge ok">Pass</span></td><td>External app → menu → Settings.</td></tr>
<tr><td>Diff hygiene</td><td><span class="badge ok">Pass</span></td><td><code>git diff --check</code>.</td></tr>
</tbody>
</table>
<div class="callout warn">
<span><strong>Release boundary:</strong> fix đã cài và chạy local nhưng chưa commit, push, tag, notarize
hoặc phát hành Homebrew artifact mới.</span>
</div>
</section>
</main>
<footer>
<div class="foot-inner">
<span class="foot-brand"><span class="dot"></span>DevCleaner Settings focus</span>
<span>Generated 2026-07-12 10:04 +07</span>
<span>·</span>
<span><code>local installed build</code></span>
<span>·</span>
<span>No commit · no push · no cleanup executed</span>
</div>
</footer>
</body>
</html>