experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(tasks): prune shipped tag-actions entry, sharpen display-topology entry

Two cleanups to keep `docs/tasks.md` in sync with what's actually open:

1. **Tag-action toggles** — pruned the 6-phase plan from the active list.
The bug was actually fixed across earlier commits (manifest topic
allowlists in all 4 consumer features, proactive broadcast in
`tag-actions/home.js:init` to defeat the cold-start race) AND has
`tests/desktop/tag-actions-toggles.spec.ts` (4/4) covering render +
click-to-swap + gate round-trips. The full multi-phase rationale is
already preserved in the pruned-log entry from 2026-04-26.

2. **Display-topology bug (page host wrong-monitor jump)** — added
today's investigation findings inline so the entry is actionable
for the next person who picks it up. Discovered:
* `display-watcher.ts` IS initialized at startup
(`entry.ts:104`) and handles already-orphaned windows.
* Fresh window opens use `screen.getDisplayNearestPoint(
getCursorScreenPoint())` (ipc.ts:754, 792) — cursor-following,
not stale-display-anchored.
* Repro requires multi-monitor hardware to verify; without it,
guessing at the root cause is wasted effort.
Added three concrete next-step lanes: (a) diagnostic logging in the
page-host open path so the next user repro yields data; (b)
investigate parent-window-relative position inheritance from the
cmd panel; (c) check workspace-key dedup against stale bounds from
a since-disappeared display.

No code changes. Doc drift cleanup only.

+2 -16
+2 -16
docs/tasks.md
··· 29 29 30 30 - [ ] **Tauri: rename `pubsub:ext:*` startup topics to `pubsub:feature:*`.** `backend/tauri/src-tauri/src/lib.rs` still emits `pubsub:ext:startup:phase` and `pubsub:ext:all-loaded`. Electron side renamed 2026-04-24; Tauri/mobile is on hold per the v1-removal plan, but track this so it lands when Tauri is unfrozen. 31 31 - [ ] **Migrate bootstrap IPC channels to tile:lifecycle:* namespace.** `session-restore-pending` and `frontend-ready` in `backend/electron/entry.ts` are bare `ipcMain.handle()` registrations from before the tile system initializes. They're only reachable from trustedBuiltin renderers via `api.invoke()`, so the security gap is theoretical, but they're the last bare main-process IPC handlers outside `tile-ipc-gate.ts`. Decision skipped 2026-04-24: leaving them bare for now since they exist *before* any tile loads — the indirection through tile-ipc-gate would require either bootstrapping the gate earlier or having two IPC modes (bootstrap vs. post-init). Worth revisiting if tile-ipc-gate ever gains a "no token required for these specific channels" mode, or if entry.ts gets folded into a tile lifecycle. 32 - - [ ] **Page host window jumps to wrong position after switching primary monitor.** Repro: connect external monitor, set it primary; open page host (cmd+L); disconnect/swap so the laptop becomes primary; cmd+L again — the whole window shifts to a different (off-screen / wrong-display) position. Likely cause: `computeWindowBounds`/canvas positioning caches screen bounds at first compute or reads stale `screen.getPrimaryDisplay()`/`getDisplayNearestPoint` results across display topology changes. Fix path: subscribe to Electron's `screen` `display-added`/`display-removed`/`display-metrics-changed` events and recompute the page-host window's normal+maximized bounds against current displays before show; clamp restored positions to a visible display. Surfaced 2026-04-24. 32 + - [ ] **Page host window jumps to wrong position after switching primary monitor.** Surfaced 2026-04-24. Repro: connect external monitor, set it primary; open page host (cmd+L); disconnect/swap so the laptop becomes primary; cmd+L again — the whole window shifts to a different (off-screen / wrong-display) position. **Investigation 2026-04-27**: existing `backend/electron/display-watcher.ts` (initialized in `entry.ts:104`) handles already-orphaned windows (rescue if <30% overlap with any display), and `ipc.ts:754` / `ipc.ts:792` use `screen.getDisplayNearestPoint(getCursorScreenPoint())` for fresh window opens — so the obvious code paths look correct. Repro requires multi-monitor hardware. Next steps: (a) add diagnostic logging in the page-host open path that captures the cursor display, current display set, computed bounds, and any workspace-key collision at the moment of open, so the next user repro yields data; (b) investigate whether the cmd-panel-spawned page-host inherits a parent-window-relative position from a since-disappeared display via the cmd panel's own bounds; (c) check `key`-based window dedup logic — if the second cmd+L matches a stale workspace key from the previous display, restoring its OLD bounds would explain the wrong position. 33 33 - [ ] **Proton Pass extension doesn't autofill.** Still broken — doesn't show up in form fields, no autofill suggestions. Likely a content-script injection or messaging API gap in the webview/canvas setup. Reproduce: install Proton Pass extension, navigate to any login page, observe no inline autofill UI. (2026-04-17: agent triaged, 5 hypotheses in agent-ae11e03d worktree — extension gitignored so couldn't repro.) 34 34 35 - - [x] **Tag-action toggles never render in the tiles world.** Surfaced 2026-04-26 after fixing the `api.settings.get('data')` storage bug in `tag-actions/home.js` — even with valid pair data in the datastore, no toggle affordances appear on item cards in tags/groups/search/pagestream. Confirmed via direct user testing. Tag-actions toggles were "completely untested in tiles world" per the user. Fix is multi-step: 36 - 37 - **Phase 1 — pubsub topic allowlists.** Consumer features (`features/{tags,groups,search,pagestream}/manifest.json`) call `api.publish('tag-actions:get-all', {})` and subscribe to `:get-all:response` / `:create:response` / `:update:response` / `:delete:response` via `app/lib/tag-action-affordances.js:createActionRulesCache`. None of the 4 consumer manifests declare `tag-actions:*` in their `pubsub.topics` allowlist, so the publish is rejected (silently or with a `gate:rejected` event per `tile-ipc-gate.ts`). Add the 5 topics (`tag-actions:get-all`, `:get-all:response`, `:create:response`, `:update:response`, `:delete:response`) to each consumer's allowlist. Confirm by running packaged with `DEBUG=1`, opening tags/home and searching for `gate:rejected.*tag-actions` in stderr. 38 - 39 - **Phase 2 — verify the renderer end-to-end.** Once the round-trip publishes succeed, confirm `createActionRulesCache.getRules()` returns the rules to the consumer, that `resolveAffordances()` picks the right rule for an item's tags, and that `createAffordanceElements()` renders the toggle into a `.tag-action-affordances` container that's actually attached to each card. Search for callers in tags/groups/search/pagestream `home.js` — confirm each invokes both `resolveAffordances` AND inserts the returned element into the DOM. Likely gaps: missing call site, container CSS hides it, render is gated on a flag that's never set. 40 - 41 - **Phase 3 — subscribe-before-publish race on cold start.** The pubsub-FSM Phase 4/5 invariant is "subscribe before publish — no buffering." `tag-actions/home.js:init` subscribes to `tag-actions:get-all` only after `await loadSettings()` (≥1 datastore round-trip, plus migration writes). Consumer tiles (tags is `lazy:true`, groups/search/pagestream all eager + resident) may publish their first `tag-actions:get-all` before tag-actions has subscribed → request is dropped and the cache stays empty forever. Two viable fixes: (a) **proactive broadcast** — tag-actions/home.js publishes `tag-actions:get-all:response` once when its own init completes, so any consumer that subscribed earlier picks up the rules without needing to publish a request; (b) **lifecycle gate** — consumers wait for a `feature:tag-actions:ready` signal before publishing. (a) is simpler and matches the Phase-4 invariant; recommended. 42 - 43 - **Phase 4 — `api.subscribe`/`api.publish` legacy alias check.** `tag-action-affordances.js` still uses the legacy bare `api.subscribe`/`api.publish` (not `api.pubsub.subscribe`). Verify these aliases survive in `tile-preload.cts` (most tiles use `api.pubsub.*` now). If the bare names are gone, migrate. 44 - 45 - **Phase 5 — Playwright coverage.** Add `tests/desktop/tag-actions-toggles.spec.ts` that opens tags/home, applies the active tag (`todo`) to a test item, and asserts the toggle element renders and is clickable; click it, assert the active tag becomes the completed tag (`done`). Mirror for groups/search/pagestream. Without these, this regresses the next time someone touches the pubsub topic gate. 46 - 47 - **Phase 6 — toggle interaction.** Once toggles render, verify clicking one fires the add-tag/remove-tag round-trip (`tag-action-affordances.js:227,234`) — the consumer needs `tag:*` topics (which most already have) AND the right datastore.tags grants. Likely already covered but worth confirming. 48 - 49 - Don't ship the data-storage fix as "complete" until Phases 1-3 land. The data fix is necessary but insufficient. 35 + _(Tag-action toggles entry pruned 2026-04-27 — fully shipped + Playwright coverage in `tests/desktop/tag-actions-toggles.spec.ts` (4/4). See pruned log below for the one-liner.)_ 50 36 51 37 --- 52 38