← Commit history

Update 1 file(s)

John Lauer ·823c07adf7 ·3mo ago ·parent bcdab8f
1 file changed +36
dev-skills/developing-the-bridge/SKILL.md+36
@@ -240,3 +240,39 @@ wrong-PWA bug that `touchBadge` warns about, reintroduced in the correlation hel   session's next drive verb (`touchBadge` → `extQuery(list_windows)` → `badgeSpawnsIn` → `matchHwnd`).   I restarted the bridge ~20× shipping other fixes that day, so every active thread was un-badged until   its next verb — expected, but verify the self-heal actually re-correlates to the RIGHT window.++## ⭐ A non-2xx from AD is a FAILURE — never treat it as success (2026-07-21, fusion-bridge report)+`adCommand` only treated a *connection* failure (`status === 0`) as an error. Any HTTP error (403, 500)+fell through as "success" with an error body, so `chromeWindowsDetailed()` parsed no windows and returned+`[]`. Result: `nbrowser_os_windows` reported **0 windows while AD saw 21**, and — far worse — the taskbar+BADGE and FLASH silently stopped working, because they go through the same call. Nothing logged.+- **Root cause: the bridge token.** AD injects `ADOM_BRIDGE_TOKEN` at spawn and **rotates it when AD+  self-updates**. A long-running bridge keeps sending the stale one and AD answers **403 to every call**+  (verified: bogus token → 403; no token → 200 + 26 windows). The token is **attribution-only**, so the+  correct recovery is to **DROP it and retry**, then keep going token-less (`adTokenRejected`).+- **Rules:** treat only 2xx as success; on 401/403 retry without the token; log every AD-link+  outage/recovery (`_ad_link`) so degradation is never silent. AD self-updates several times a day, so+  assume the token, the port, AND the API surface can all shift under a running bridge.++## ⭐ Log every badge paint + flash (John, 2026-07-21)+The taskbar badge is a security signal; a silent failure is indistinguishable from "no AI is driving."+`taskbar()` now logs an `_taskbar` activity entry for EVERY call — `hwnd`, `ops`+(`overlay:composite|overlay:adom|overlay:none|flash:until_focused|progress:x`), `ok`, and the HTTP+status on failure — and `nbrowser_activity` carries `hwnd`/`ops` through so you can query+`{verb:"_taskbar"}` and see exactly what was painted where and whether AD accepted it.++## ⭐ A load-unpacked extension has an EMPTY manifest.name on disk (2026-07-21)+`adomExtStateForProfile` matched `extensions.settings[*].manifest.name =~ /adom/`, but a **Load-unpacked**+install stores an empty `manifest.name` (only `path`). So a profile that HAD the extension reported+`extensionInstalled:false`, and the upsell hint told users WITH the extension to install it. Match on the+**pinned extension ID** (`nncjgceobm…`, stable because manifest pins `key`) or the **path** as well.+**Authority order:** a LIVE native-messaging connection (what `nbrowser_readiness` reports) is+authoritative; the on-disk inventory is only a fallback for profiles that are not connected. Never let+two verbs disagree about whether the extension is installed.++## ⭐ Report "did it launch" separately from "did I get an hwnd" (2026-07-21)+`nbrowser_open_os_window` returned `ok:false` when the browser GROUPED the page into an existing window+(no new hwnd within 8s) even though the page opened — for a consent flow that IS success, and a caller+was forced to regex our `_hint` to detect it. Contract now: **`ok:true` + `launched:true`** whenever the+launch fired, with **`hwndResolved:bool` + `hwndReason`** reported separately. Never make a caller parse+prose to learn an outcome — give them a stable boolean.