You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: one-shot dock bounce on parked approvals while away (BACKLOG Standing #9)
NotifyPendingApproval's away branch now requests a single
informational dock bounce (window.Flash, wails beta.6's macOS
support) alongside the OS notification and floating prompt -- same
kernel attention-layer class as the dock badge (ADR-0035). The
notify adapter's cgo send aborts headless, so only the nil-window
guard is unit-testable; the real bounce is a manual-only desktop
check (testing.md).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FJ8wStsHyu7XPLTspNjMnQ
Copy file name to clipboardExpand all lines: docs/goals/BACKLOG.md
+10-1Lines changed: 10 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -217,7 +217,16 @@ live-review material, interleaved during owner reviews, not a lane.**
217
217
6. [x] ⌘?/⌘/ multi-binding keybinding alias (tech debt, split from goal 0015's remainder 2026-08-12) — DELIVERED 2026-08-13: `Command` grew an optional `extraBindings: KeyCombo[]` alongside `defaultBinding` (`shared/commands.ts`, backward-compatible); `shared/keybinding.ts`'s `keyFromEventCode` gained `/` support (shift-independent, same as every other key — the Shift mod is what distinguishes ⌘/ from ⌘?, both on the physical Slash key). `palette.open` carries both as `extraBindings`, checked against the full registry + `RESERVED_COMBOS` first (no collision — nothing else uses `/`). `dispatchCommandForEvent` checks a command's effective (override-aware) primary plus its extras every dispatch; extras themselves are deliberately NOT override-checked this pass (Settings' recorder-based rebinding UI still edits only the primary). `views/KeyboardShortcutsSection.tsx` renders extras as read-only secondary `KeyComboChip`s next to the primary's click-to-rebind button. Vitest covers dispatch-matches-either-binding + override-doesn't-disable-extras + no-extraBindings-backward-compat; `keymap.spec.ts` gained both a live ⌘//⌘⇧+/ → palette-opens case and a Settings-renders-the-two-read-only-chips case.
218
218
7. [ ] [0021 — MCP dogfood gap closure](0021-mcp-dogfood-gap-closure.md) Phase 2 (orchestrator-driven live MCP probing) + Phase 3 (that probe's gap closure) DELIVERED 2026-08-13: the live author-from-scratch + full `run_workflow_stepped` probe found the loop mechanics themselves sound, plus two interop gaps — inconsistent identifier argument names across tools (`id` vs. `runId` vs. `workflowId`) and `run_workflow` always landing `test` kind with no way to opt out (silently excluding real agent-triggered production runs from Home's metrics). Both fixed same day: every workflow-identifying tool now accepts a canonical `workflowId` alongside its original `id` (one shared `resolve()` helper, backward compatible); `run_workflow` gained an optional `test` boolean (default `false` → new `RunKindMCP`, counted in Home's automation metrics like a real trigger fire; `test:true` → `RunKindTest`, excluded, matching the UI's Test button) — `run_workflow_stepped` stays unconditionally `test` kind (debug surface). Real-MCP-client Go tests prove both. Left UNCHECKED / not archived: the goal file's own separate Phase 4 (Confluence-markdown-fidelity fixture corpus + M365 bridge dry run) remains genuinely open, substantial, unaddressed work outside this round's scope — the file's own acceptance bar is the owner calling the whole surface real-use-ready, not one phase closing.
219
219
8. [x] Dev-loop instance guards (tech debt, owner-hit 2026-08-12 evening: THREE concurrent `mill.dev.app` instances in the dock, real crash risk on the 16GB machine) — DELIVERED 2026-08-13, both mechanical fixes landed: (a) per-rebuild reap — `build/config.yml`'s `dev_mode.executes` gained a `type: blocking` `pkill -f "bin/mill.dev.app/Contents/MacOS/mill" || true` step right before the `primary` `wails3 task run` step (blocking steps re-run every reload cycle, confirmed directly against the vendored `github.com/atterpac/refresh` engine source — its own `Primary` case already SHOULD kill-then-restart via a process-group SIGKILL, but a live `task dev` session running during this item's own investigation was caught red-handed with two concurrent `mill.dev.app` processes, one orphaned into a foreign process group refresh's own tracking never reaped; root cause not fully pinned to one line since it's in a vendored third-party dependency, so this reap is an independent, pattern-based backstop rather than a patch to code this repo doesn't own — same shape Taskfile.yml's own start-of-session sweep already used); (b) `task dev` now refuses a second concurrent start — `internal/devguard` (a real Go package, `package main`, unit-tested: `guard_test.go` covers process-list parsing, the wails3-dev-process matcher incl. a real false-positive it caught and fixed against a differently-pathed sibling project, port-PID parsing, and message formatting) runs as the FIRST step of `Taskfile.yml`'s `dev:` task, checks for an already-running `wails3 dev` process for this exact repo, and exits non-zero naming the conflicting PID (+ any port occupancy as corroborating detail) before the destructive sweep steps can run — verified live against a genuinely running session (correctly detected + refused, naming the real PID). Manual-only registry entry added (`.claude/skills/run-mill/SKILL.md`) for what CI structurally can't prove: real per-rebuild-orphan-prevention across several live Go-triggered rebuilds, and a genuine second-terminal `task dev` invocation actually refusing to start.
220
-
9.[ ] Dock-bounce on parked approvals (small, unlocked by wails beta.6's Flash() gaining macOS support via NSApp requestUserAttention — PR #44's changelog finding; Mill calls Flash nowhere today) — the attention stack (goal 0023/ADR-0032's away-user layer) gains a one-shot dock bounce when an approval parks while the user is away; kernel attention-layer surface per ADR-0035 (same class as the dock badge), NOT a new composition path. Tiny: one call site in the existing NotifyPendingApproval flow + manual-only registry entry (real dock behavior isn't CI-testable).
220
+
9.[x] Dock-bounce on parked approvals — DELIVERED 2026-08-13 exactly
NSInformationalRequest, bounces once and self-completes — never
224
+
repeating/critical), same kernel attention-layer class as the dock
225
+
badge (ADR-0035); nil-window guard unit-tested, the full away
226
+
branch isn't headless-testable (notify's cgo send aborts under
227
+
`go test` — discovered here, recorded in testing.md's manual-only
228
+
note along with the desktop-mode verification step); SPEC §3.6's
229
+
attention-layer paragraph updated.
221
230
10. [x] resizable-table.spec.ts drag-timing flake, PROPER fix (3 confirmed recurrences POST-hardening: PR #24 original, #43's run, #44's run — the expect.poll hardening from PR #33's wave was insufficient) — DELIVERED 2026-08-13. A keyboard-based resize alternative was checked and ruled out (`shared/ResizableTable.tsx`'s drag handle is built entirely on pointerdown/pointermove/pointerup, no keyboard path at all — building one would be a real feature addition, not a test fix). Landed instead: `test.describe.configure({ mode: 'serial' })` makes the file's own never-interleave requirement explicit rather than an incidental side effect of global config; `waitForStableBoundingBox` replaces the old non-null-only `expect.poll` with a poll for the box being IDENTICAL across two consecutive reads (a non-null box mid-reflow was always possible the old check couldn't see); the synthesized drag itself moved from one batched `page.mouse.move(..., { steps: N })` call to discrete, individually-awaited moves (a browser can coalesce rapid pointermove events within one CDP command — a real, documented behavior via the `PointerEvent.getCoalescedEvents()` API, not Playwright-specific); and two more `expect.poll`s wait for the drag's actual DOM effect and the `localStorage` persist to land before the next step depends on them, instead of assuming the previous Playwright command's own resolution implies the page's JS listener already ran. Verified via 5 separate fresh `npx playwright test` invocations (10/10 passed) — an in-process `--repeat-each` stress loop on the same worker turned out to be a self-confounding methodology (accumulating browser/worker degradation unrelated to the fix, not representative of a real CI run) once cross-checked against genuinely fresh runs.
222
231
11.[x] 0030 second-pass linters (gocritic/prealloc/contextcheck/sqlclosecheck — named future work in goal 0028) + `.ls-lint.yml` gains a root `node_modules` ignore (gap found 2026-08-12: a stray root node_modules broke root-file-naming; tiny, rides this or any PR) — DELIVERED 2026-08-13. All four enabled in `.golangci.yml`; triaged to zero findings on both build-tag variants (default + `server`) — 14 real findings fixed (1 `gocritic` assignOp in a test file, 13 `prealloc` slice-capacity hints across `seedproof_test.go` and `millmcpservice.go`'s resource-index readers), zero `contextcheck`/`sqlclosecheck` findings, zero rules needed a scoped tweak or a `//nolint` suppression this pass. `.ls-lint.yml`'s root `ignore:` list gained `node_modules` with a comment explaining the root-scoped-recursive-rule interaction.
0 commit comments