fix(dashboard): Task Detail's blocking count read the LEGACY lanes (last of the three fan-out surfaces) (#3004)

Third and last of the three surfaces calling the blocker fan-out
wrapper, completing the sweep started in #2990 (Board + Executor bar).

## What was wrong, precisely

The dependent **list** is lane-independent — core pushes `dependentIds`
without consulting lanes — so this section looked broadly right. Two
things beside it are not:

- `overlapBlockedTodoCount`, rendered as **"FN-X is blocking N todo
task(s) via blockedBy overlap"** — counted against the literal `todo`,
so on a renamed board it read **0 while cards were genuinely blocked**.
- the `stale` marker on each blocking dependent — decided against
`terminal`/`review` lanes the operator does not use.

A wrong number sitting beside a right list is the easiest kind to miss,
which is why I checked what the modal actually consumes before deciding
this was worth a PR rather than assuming the whole section was broken.

## Why a prop and not a hook

This was the surface I deferred in #2990 because it had no trait index
in scope. Two options:

- `useBoardWorkflows` inside the modal — rejected. The hook documents
that it does **not** dedupe across consumers: each call installs its own
visibilitychange/focus listeners and its own SSE subscription. That is a
new fetch and subscription per modal open, to answer a question the app
has already answered.
- **Thread the index that already exists** — `App` builds
`footerColumnFlagsByTaskId` for the footer; this forwards it through
`AppModals` as an optional prop. Chosen.

Optional throughout: a card with no entry keeps the documented legacy
fallback, so the remote-node case (where local workflow metadata must
never be applied to foreign ids) and the pre-load window stay
byte-identical.

## Reverted

The new case fails on the rendered text — the modal cannot find `"FN-B
is blocking 2 todo task(s) via blockedBy overlap"`. The pre-existing
legacy-column case above it passes either way, because `todo` satisfies
the literal default; that is exactly why it never caught this.

## Verification

TaskDetailModal.rendering + ExecutorStatusBar + useBlockerFanout **206
passed** · dashboard app suite 11986 passed / 5 skipped (581 files) ·
`pnpm test:gate` 161 + 13 + 487 + 71 · lint · census `--strict` ·
lane-wiring · fnxc-dates · changesets — green.

## One note for whoever owns the FNXC gate

`check-fnxc-future-dates.mjs` **rewrites its baseline as a side effect
and still exits 0**. Today's date roll dropped 183 stamps out of
"future", so any run dirties
`scripts/lib/fnxc-future-dates-baseline.json` in the working tree. It
cost me a stash conflict before I noticed. Not bundled here — it is
repo-wide midnight drift, not this change — but a check that mutates
tracked state on a read is worth a look.
This commit is contained in:
gsxdsm
2026-07-31 00:13:43 -07:00
committed by GitHub
parent d861923355
commit 1de0141ab8
6 changed files with 93 additions and 178 deletions

View File

@@ -1,245 +1,94 @@
{
"packages/cli/src/__tests__/cli-active-count-lanes.test.ts": 5,
"packages/cli/src/__tests__/pr-create-review-lane-resolved.test.ts": 1,
"packages/cli/src/__tests__/task-retry-renamed-review.pg.test.ts": 2,
"packages/cli/src/commands/__tests__/task.test.ts": 1,
"packages/cli/src/commands/dashboard.ts": 1,
"packages/cli/src/commands/task.ts": 8,
"packages/cli/src/commands/task.ts": 6,
"packages/cli/src/extension.ts": 3,
"packages/core/src/__tests__/analytics-timing-roles-resolved.test.ts": 1,
"packages/core/src/__tests__/archive-all-done-lane.test.ts": 1,
"packages/core/src/__tests__/archived-column-gate-parity.test.ts": 3,
"packages/core/src/__tests__/assigned-agent-archived-lanes.test.ts": 1,
"packages/core/src/__tests__/blocker-fanout.test.ts": 2,
"packages/core/src/__tests__/display-ranking-roles-resolved.test.ts": 1,
"packages/core/src/__tests__/duplicate-terminal-roles-resolved.test.ts": 1,
"packages/core/src/__tests__/eval-automation-complete-lane.test.ts": 1,
"packages/core/src/__tests__/intake-duplicate-terminal-lanes.test.ts": 1,
"packages/core/src/__tests__/legacy-auto-merge-stamp-review-lanes.test.ts": 1,
"packages/core/src/__tests__/merge-path-lanes-resolved.test.ts": 2,
"packages/core/src/__tests__/postgres/archived-document-lanes.pg.test.ts": 1,
"packages/core/src/__tests__/postgres/dependency-satisfied-renamed-board.pg.test.ts": 2,
"packages/core/src/__tests__/postgres/mission-store.pg.test.ts": 1,
"packages/core/src/__tests__/postgres/near-duplicate-clear-renamed-terminal.pg.test.ts": 2,
"packages/core/src/__tests__/postgres/store-archive-reads.pg.test.ts": 1,
"packages/core/src/__tests__/postgres/sync-workflow-ir-is-always-default.pg.test.ts": 1,
"packages/core/src/__tests__/postgres/task-dependency-mutation.pg.test.ts": 2,
"packages/core/src/__tests__/project-lane-vocabulary.test.ts": 1,
"packages/core/src/__tests__/postgres/task-dependency-mutation.pg.test.ts": 1,
"packages/core/src/__tests__/pure-lifecycle-predicates.test.ts": 3,
"packages/core/src/__tests__/reads-age-staleness-lane-hydration.test.ts": 1,
"packages/core/src/__tests__/renamed-lanes-staleness-and-blockers.test.ts": 2,
"packages/core/src/__tests__/reopen-semantics-by-role.test.ts": 1,
"packages/core/src/__tests__/store-overlap-repair-lanes-resolved.test.ts": 1,
"packages/core/src/__tests__/sync-workflow-ir-callsite-allowlist.test.ts": 2,
"packages/core/src/__tests__/task-age-staleness.test.ts": 1,
"packages/core/src/__tests__/task-merge-lanes-resolved.test.ts": 1,
"packages/core/src/__tests__/task-update-lanes-resolved.test.ts": 1,
"packages/core/src/__tests__/unarchive-target-lanes.test.ts": 1,
"packages/core/src/__tests__/workflow-ir-resolver.test.ts": 1,
"packages/core/src/__tests__/workflow-lifecycle-traits.test.ts": 3,
"packages/core/src/agent-store.ts": 2,
"packages/core/src/assigned-task-ranking.ts": 1,
"packages/core/src/async-chat-store.ts": 4,
"packages/core/src/async-mission-store-queries.ts": 3,
"packages/core/src/async-mission-store.ts": 2,
"packages/core/src/blocker-fanout.ts": 5,
"packages/core/src/async-mission-store-queries.ts": 1,
"packages/core/src/async-mission-store.ts": 1,
"packages/core/src/blocker-fanout.ts": 1,
"packages/core/src/chat-store.ts": 1,
"packages/core/src/command-center-live.ts": 1,
"packages/core/src/default-workflow-hooks.ts": 1,
"packages/core/src/duplicate-detection.ts": 1,
"packages/core/src/duplicate-intake.ts": 2,
"packages/core/src/eval-automation.ts": 1,
"packages/core/src/index.gate.ts": 1,
"packages/core/src/live-agent-count.ts": 1,
"packages/core/src/mobile-nav-primary-items.ts": 1,
"packages/core/src/near-duplicate-canonical.ts": 1,
"packages/core/src/postgres/migrations/0000_initial.sql": 1,
"packages/core/src/postgres/migrations/0029_planning_active_timing.sql": 1,
"packages/core/src/postgres/migrations/0035_fn_8543_mission_lineage_stop.sql": 1,
"packages/core/src/postgres/migrations/0036_chat_session_tags.sql": 2,
"packages/core/src/project-lane-vocabulary.ts": 3,
"packages/core/src/project-lane-vocabulary.ts": 1,
"packages/core/src/settings-schema.ts": 2,
"packages/core/src/store.ts": 9,
"packages/core/src/task-age-staleness.ts": 1,
"packages/core/src/task-merge.ts": 3,
"packages/core/src/task-priority.ts": 2,
"packages/core/src/store.ts": 2,
"packages/core/src/task-store/archive-lifecycle-2.ts": 2,
"packages/core/src/task-store/async-comments-attachments.ts": 1,
"packages/core/src/task-store/async-merge-coordination.ts": 2,
"packages/core/src/task-store/branch-and-pr-entities.ts": 3,
"packages/core/src/task-store/branch-group-ops.ts": 1,
"packages/core/src/task-store/comments-ops.ts": 2,
"packages/core/src/task-store/lifecycle-ops.ts": 2,
"packages/core/src/task-store/merge-queue-ops-2.ts": 4,
"packages/core/src/task-store/moves.ts": 2,
"packages/core/src/task-store/project-store-ops.ts": 1,
"packages/core/src/task-store/task-artifacts-ops.ts": 6,
"packages/core/src/task-store/task-creation.ts": 2,
"packages/core/src/task-store/task-id-integrity.ts": 1,
"packages/core/src/task-store/task-mutation-ops.ts": 1,
"packages/core/src/task-store/task-store-helpers.ts": 3,
"packages/core/src/task-store/task-update.ts": 5,
"packages/core/src/task-store/update-task-deps.ts": 7,
"packages/core/src/task-store/workflow-definitions.ts": 1,
"packages/core/src/task-store/workflow-integrity.ts": 1,
"packages/core/src/task-symbol-resolution.ts": 1,
"packages/core/src/task-timing.ts": 2,
"packages/core/src/team-analytics.ts": 1,
"packages/core/src/types/merge-queue.ts": 1,
"packages/core/src/workflow-analytics.ts": 1,
"packages/core/src/workflow-ir-resolver.ts": 3,
"packages/core/src/workflow-lifecycle-traits.ts": 2,
"packages/core/src/task-store/task-store-helpers.ts": 2,
"packages/core/src/task-store/task-update.ts": 1,
"packages/core/src/task-store/update-task-deps.ts": 5,
"packages/core/src/task-timing.ts": 1,
"packages/core/src/workflow-ir-resolver.ts": 2,
"packages/dashboard/app/App.tsx": 3,
"packages/dashboard/app/components/AgentDetailView.css": 1,
"packages/dashboard/app/components/ChatView.css": 2,
"packages/dashboard/app/components/PendingAttachmentPreviews.css": 1,
"packages/dashboard/app/components/TaskCard.tsx": 2,
"packages/dashboard/app/components/TaskDetailModal.css": 1,
"packages/dashboard/app/components/TaskReviewTab.tsx": 1,
"packages/dashboard/app/components/__tests__/AgentDetailView.mobile-scroll.test.tsx": 1,
"packages/dashboard/app/components/__tests__/AgentListModal.test.tsx": 1,
"packages/dashboard/app/components/__tests__/ListView.test.tsx": 1,
"packages/dashboard/app/components/__tests__/SubtaskBreakdownModal.test.tsx": 1,
"packages/dashboard/app/components/__tests__/TaskCard.test.tsx": 5,
"packages/dashboard/app/components/__tests__/TaskDetailModal.definition-actions.test.tsx": 1,
"packages/dashboard/app/components/__tests__/TaskDetailModal.models-progress-workflow.test.tsx": 1,
"packages/dashboard/app/components/__tests__/TaskReviewTab.test.tsx": 2,
"packages/dashboard/app/components/command-center/MissionControlPanel.tsx": 1,
"packages/dashboard/app/components/taskSorting.ts": 1,
"packages/dashboard/app/hooks/__tests__/useSessionFiles.test.ts": 1,
"packages/dashboard/app/hooks/useSessionFiles.ts": 2,
"packages/dashboard/app/styles.css": 1,
"packages/dashboard/app/utils/__tests__/appLifecycle.test.ts": 1,
"packages/dashboard/app/utils/__tests__/taskProgress.test.ts": 1,
"packages/dashboard/app/utils/__tests__/taskTiming.test.ts": 1,
"packages/dashboard/app/utils/appLifecycle.ts": 1,
"packages/dashboard/app/utils/prFeedback.ts": 1,
"packages/dashboard/app/utils/taskProgress.ts": 1,
"packages/dashboard/app/utils/taskTiming.ts": 1,
"packages/dashboard/src/__tests__/agent-task-link-terminal-lanes.test.ts": 1,
"packages/dashboard/src/__tests__/ai-session-diagnostics.test.ts": 1,
"packages/dashboard/src/__tests__/board-workflows.test.ts": 1,
"packages/dashboard/src/__tests__/chat.test.ts": 1,
"packages/dashboard/src/__tests__/command-center-analytics-column-flags.test.ts": 1,
"packages/dashboard/src/__tests__/devserver-manager.test.ts": 1,
"packages/dashboard/src/__tests__/devserver-preview-detect.test.ts": 1,
"packages/dashboard/src/__tests__/github-tracking-comments.test.ts": 1,
"packages/dashboard/src/__tests__/github-tracking-reconciler.test.ts": 2,
"packages/dashboard/src/__tests__/github-tracking-renamed-board.test.ts": 3,
"packages/dashboard/src/__tests__/github-tracking-state.test.ts": 1,
"packages/dashboard/src/__tests__/gitlab-parity-inventory-documentation.test.ts": 1,
"packages/dashboard/src/__tests__/gitlab-tracking-comments.test.ts": 1,
"packages/dashboard/src/__tests__/issue-image-attachments.test.ts": 1,
"packages/dashboard/src/__tests__/register-git-github.review-lanes.test.ts": 1,
"packages/dashboard/src/__tests__/register-signal-routes.test.ts": 1,
"packages/dashboard/src/__tests__/reliability-metrics.test.ts": 1,
"packages/dashboard/src/__tests__/routes-github.test.ts": 4,
"packages/dashboard/src/__tests__/routes-pull-requests.test.ts": 1,
"packages/dashboard/src/__tests__/routes-tasks.test.ts": 1,
"packages/dashboard/src/__tests__/sse.test.ts": 1,
"packages/dashboard/src/__tests__/task-lifecycle-lanes.test.ts": 1,
"packages/dashboard/src/github-tracking-reconciler.ts": 3,
"packages/dashboard/src/github-tracking-state.ts": 2,
"packages/dashboard/src/project-store-resolver.ts": 1,
"packages/dashboard/src/routes/__tests__/register-task-workflow-routes.move-bypassguards.test.ts": 2,
"packages/dashboard/src/routes/__tests__/register-task-workflow-routes.resolved-review-column.test.ts": 5,
"packages/dashboard/src/routes/register-command-center-routes.ts": 2,
"packages/dashboard/src/routes/register-git-github.ts": 1,
"packages/dashboard/src/routes/register-project-routes.ts": 2,
"packages/dashboard/src/routes/register-system-maintenance-routes.ts": 1,
"packages/dashboard/src/routes/register-task-workflow-routes.ts": 11,
"packages/dashboard/src/routes.ts": 3,
"packages/dashboard/vitest.config.ts": 2,
"packages/engine/src/__tests__/_workflow-vocabulary-fixture.ts": 1,
"packages/engine/src/__tests__/agent-assignment.test.ts": 2,
"packages/engine/src/__tests__/agent-tools-intake-column.test.ts": 1,
"packages/engine/src/__tests__/auto-heal-review-lane-callsite-audit.test.ts": 1,
"packages/engine/src/__tests__/backlog-pressure-reporter.test.ts": 1,
"packages/engine/src/__tests__/builtin-workflows-lifecycle.test.ts": 3,
"packages/dashboard/src/routes/__tests__/register-task-workflow-routes.resolved-review-column.test.ts": 4,
"packages/dashboard/src/routes/register-task-workflow-routes.ts": 4,
"packages/dashboard/vitest.config.ts": 1,
"packages/engine/src/__tests__/census-query-role-split.test.ts": 1,
"packages/engine/src/__tests__/census-reclassification-message.test.ts": 1,
"packages/engine/src/__tests__/ephemeral-worker-manager.test.ts": 2,
"packages/engine/src/__tests__/eval-followups.test.ts": 1,
"packages/engine/src/__tests__/executor-fast-mode-workflows.test.ts": 1,
"packages/engine/src/__tests__/executor-graph-failure-lanes-resolved.test.ts": 7,
"packages/engine/src/__tests__/executor-planner-lanes-resolved.test.ts": 1,
"packages/engine/src/__tests__/executor-resume-query-lanes.test.ts": 1,
"packages/engine/src/__tests__/executor-stale-spec-active-lanes.test.ts": 2,
"packages/engine/src/__tests__/executor-user-cancel.test.ts": 1,
"packages/engine/src/__tests__/executor-stale-spec-active-lanes.test.ts": 1,
"packages/engine/src/__tests__/heartbeat-terminal-lane.test.ts": 1,
"packages/engine/src/__tests__/lifecycle-column-census-ast.test.ts": 1,
"packages/engine/src/__tests__/lifecycle-column-census.test.ts": 2,
"packages/engine/src/__tests__/logger-mock-completeness.test.ts": 1,
"packages/engine/src/__tests__/notification-service.test.ts": 2,
"packages/engine/src/__tests__/plan-approval-hold-invariant.test.ts": 1,
"packages/engine/src/__tests__/planner-lanes-async-resolution.test.ts": 1,
"packages/engine/src/__tests__/planner-overseer.test.ts": 1,
"packages/engine/src/__tests__/lifecycle-column-census.test.ts": 1,
"packages/engine/src/__tests__/planning-continuation-terminal-lanes.test.ts": 1,
"packages/engine/src/__tests__/project-engine-merge-lane-resolved.test.ts": 2,
"packages/engine/src/__tests__/restart-recovery-coordinator.test.ts": 2,
"packages/engine/src/__tests__/review-handoff-lane.test.ts": 1,
"packages/engine/src/__tests__/scheduler-fanout-escalation-lanes.test.ts": 2,
"packages/engine/src/__tests__/scheduler-load-lane-union.test.ts": 2,
"packages/engine/src/__tests__/self-blocked-dependency-deadlock.pg.test.ts": 1,
"packages/engine/src/__tests__/self-healing-db-corruption.test.ts": 1,
"packages/engine/src/__tests__/stale-task-reporter.test.ts": 1,
"packages/engine/src/__tests__/task-completion-dependency-lanes.test.ts": 1,
"packages/engine/src/__tests__/transition-pending-recovery-deadlock.pg.test.ts": 2,
"packages/engine/src/__tests__/unwired-lane-parameter-guard.test.ts": 4,
"packages/engine/src/__tests__/usage-limit-detector.test.ts": 3,
"packages/engine/src/__tests__/workflow-file-scope-lease-caller-gap-live-e2e.pg.test.ts": 1,
"packages/engine/src/__tests__/workflow-graph-optional-step-fix.test.ts": 3,
"packages/engine/src/__tests__/workflow-ir-provenance-live-e2e.pg.test.ts": 2,
"packages/engine/src/__tests__/workflow-optional-role-param-caller-audit-live-e2e.pg.test.ts": 1,
"packages/engine/src/__tests__/workflow-planning-continuation-terminal-gap-live-e2e.pg.test.ts": 1,
"packages/engine/src/__tests__/workflow-settings-fallback-alignment.test.ts": 1,
"packages/engine/src/__tests__/workflow-sweep-sentinel-task-id-live-e2e.pg.test.ts": 1,
"packages/engine/src/__tests__/workflow-sync-selection-blast-radius-live-e2e.pg.test.ts": 2,
"packages/engine/src/__tests__/workflow-terminal-node-sync-resolution-live-e2e.pg.test.ts": 1,
"packages/engine/src/__tests__/workflow-timing-trait-live-e2e.pg.test.ts": 1,
"packages/engine/src/__tests__/workflow-unarchive-target-live-e2e.pg.test.ts": 1,
"packages/engine/src/agent-assignment.ts": 2,
"packages/engine/src/agent-heartbeat.ts": 2,
"packages/engine/src/agent-session-helpers.ts": 2,
"packages/engine/src/agent-tools.ts": 1,
"packages/engine/src/auto-merge-finalization.ts": 1,
"packages/engine/src/backlog-pressure-reporter.ts": 1,
"packages/engine/src/concurrency.ts": 5,
"packages/engine/src/ephemeral-worker-manager.ts": 2,
"packages/engine/src/eval-followups.ts": 2,
"packages/engine/src/ipc/__tests__/ipc-host.test.ts": 1,
"packages/engine/src/ipc/__tests__/ipc-worker.test.ts": 1,
"packages/engine/src/concurrency.ts": 4,
"packages/engine/src/merger.ts": 2,
"packages/engine/src/mission-feature-sync.ts": 2,
"packages/engine/src/mission-symbol-admission.ts": 2,
"packages/engine/src/notification/notification-service.ts": 3,
"packages/engine/src/mission-symbol-admission.ts": 1,
"packages/engine/src/pi.ts": 3,
"packages/engine/src/planner-lane-resolution.ts": 1,
"packages/engine/src/planner-overseer.ts": 1,
"packages/engine/src/project-engine.ts": 11,
"packages/engine/src/replan-target.ts": 4,
"packages/engine/src/restart-recovery-coordinator.ts": 4,
"packages/engine/src/runtime-primitives.ts": 1,
"packages/engine/src/project-engine.ts": 8,
"packages/engine/src/restart-recovery-coordinator.ts": 1,
"packages/engine/src/runtime-resolution.ts": 1,
"packages/engine/src/runtimes/__tests__/child-process-worker.test.ts": 3,
"packages/engine/src/runtimes/in-process-runtime.ts": 4,
"packages/engine/src/scheduler.ts": 9,
"packages/engine/src/stale-task-reporter.ts": 2,
"packages/engine/src/task-completion.ts": 1,
"packages/engine/src/triage.ts": 9,
"packages/engine/src/usage-limit-detector.ts": 5,
"packages/engine/src/workflow-node-handlers.ts": 1,
"packages/engine/src/workflow-work-processor.ts": 2,
"packages/engine/src/workflow-work-scheduler.ts": 1,
"packages/engine/src/worktree-pool.ts": 1,
"packages/engine/vitest.config.ts": 1,
"scripts/__tests__/check-inert-flag-seams.test.mjs": 1,
"scripts/check-fnxc-future-dates.mjs": 3,
"scripts/check-inert-flag-seams.mjs": 2,
"scripts/check-sql-column-literals.mjs": 1,
"packages/engine/src/scheduler.ts": 3,
"packages/engine/src/triage.ts": 6,
"packages/engine/src/workflow-work-processor.ts": 1,
"scripts/lib/lifecycle-column-census-ast.mjs": 3,
"scripts/lib/unwired-lane-parameter.mjs": 3,
"scripts/lifecycle-column-census.mjs": 12,
"scripts/lifecycle-column-census.mjs": 3,
"docs/dashboard-guide.md": 3,
"docs/testing.md": 1,
"docs/workflow-steps.md": 1