Files
kandev/docs/plans/github-task-pr-sync-coordination/task-01-coordinate-task-pr-sync-consumers.md
2026-08-27 12:59:30 +00:00

5.6 KiB

id, title, status, wave, depends_on, plan, requirements, acceptance_criteria, system_design
id title status wave depends_on plan requirements acceptance_criteria system_design
01-coordinate-task-pr-sync-consumers Coordinate task PR sync consumers done 1
plan.md
REQ-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.1
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.2
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.3
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.4
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.5
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.6
AC-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001.7
../../specs/integrations/system-design/github-task-pr-sync-coordination.md

Task 01: Coordinate task PR sync consumers

Summary

Add one shared synchronization resource for each store, workspace context, and task. Refactor useTaskPR to lease that resource while preserving its current return contract and task PR store behavior.

In scope

  • Add the task PR sync resource and its test factory.
  • Share initial, retry, reconnect, and manual refresh requests.
  • Publish one loaded snapshot to all consumers.
  • Reference-count consumers and clean up timers, observers, and stale entries.
  • Guard response writes by resource generation and active workspace context.
  • Integrate the resource with useTaskPR without changing callers.
  • Add focused resource and multi-consumer hook regression tests.

Out of scope

  • Backend or protocol changes.
  • UI component changes.
  • Task PR unlink or tooltip hydration redesign.
  • Session Git status subscription deduplication.

Acceptance

  • Two mounted useTaskPR consumers for the same scoped task send one initial request and one request on each retry tick.
  • Concurrent manual refresh calls return the same active completion and send one request.
  • Different task or workspace-context keys remain independent.
  • One consumer release preserves the lifecycle; the final release stops later retries and prevents stale publication.
  • Permanent results stop retries. Reconnect starts one immediate request and one fresh bounded retry window.
  • Empty results, transient failures, terminal failures, discovered pull requests, loaded state, and unlink behavior match the current hook contract.

TDD sequence

Red

  • Extend use-task-pr.test.tsx with two consumers under one StateProvider and assert that the current implementation sends duplicate initial and retry requests.
  • Add task-pr-sync-resource.test.ts cases for request joining, lease cleanup, scope isolation, reconnect transitions, retry terminal states, and stale responses. Confirm they fail before the resource exists.

Green

  • Implement the smallest store-scoped resource that satisfies the tests.
  • Delegate useTaskPR synchronization and loaded state to the resource.
  • Keep store selectors and unlink behavior unchanged.

Refactor

  • Keep resource state transitions explicit and separate from the React hook.
  • Reuse isCurrentWorkspaceContext and the existing TaskPR scope types.
  • Remove the superseded per-hook retry, request, reconnect, and loaded refs and effects.

Verification

cd apps/web && pnpm exec vitest run hooks/domains/github/task-pr-sync-resource.test.ts hooks/domains/github/use-task-pr.test.tsx
cd apps/web && pnpm run typecheck
cd apps && pnpm --filter @kandev/web lint
git diff --check

Files likely touched

  • apps/web/hooks/domains/github/task-pr-sync-resource.ts
  • apps/web/hooks/domains/github/task-pr-sync-resource.test.ts
  • apps/web/hooks/domains/github/use-task-pr.ts
  • apps/web/hooks/domains/github/use-task-pr.test.tsx

Dependencies

None.

Risks

  • Strict Mode effect replay can expose cleanup and re-acquisition races.
  • A stale request can write into a later workspace context if either the store or generation guard is missing.
  • Ref-count errors can stop a needed retry or keep an orphan timer alive.
  • A promise-only solution can pass concurrent-call tests while still producing duplicate requests on later retry ticks.

Parallelism

sequential

The resource and hook integration share one lifecycle contract and one focused regression suite.

Inputs

  • REQ-INTEGRATIONS-GITHUB-TASK-PR-SYNC-COORDINATION-001 and its system design.
  • The confirmed per-instance state in apps/web/hooks/domains/github/use-task-pr.ts.
  • The store-scoped request registry in use-task-pr-tooltip-hydration.ts and external-resource pattern in pr-commits-resource.ts.
  • The repeated github.task_pr.sync requests in the reported browser trace.

Output contract

Report the files changed, the RED failure, GREEN and regression test outcomes, typecheck and lint results, and any remaining lifecycle risk in the primary session. Keep the requirement, design, plan, and work-order statuses in sync.

Results

  • Added the store-scoped task PR sync resource and deterministic resource tests.
  • Refactored useTaskPR to lease the resource while preserving its return contract, loaded behavior, refresh operation, and unlink behavior.
  • RED: the multi-consumer regression observed two initial requests from the previous per-hook implementation instead of one.
  • GREEN: the focused resource and hook suites pass with 21 tests.
  • The web typecheck and lint pass, and no rendered or mobile interaction changed.
  • The resource invalidates publication when its lease is gone or its workspace context is no longer current. WebSocket request timeouts remain owned by the existing client.
  • Unlink invalidates the scoped request generation after local removal, so an in-flight response cannot restore the removed association.