Domain migration. Depends on D2 and PAR-412. It pairs with D6, so coordinate on the webhook entry point.
GithubWebhookService becomes a thin adapter feeding a github facade:
GithubMcpTools moves to github/mcp.Tests pass (webhook fixtures), and the ArchUnit store and ESLint suppressions shrink.
Plan (branch par-421-github off rebuild):
io.paradaux.tasklie.github behind GithubFacade (model / persistence / usecase / api / mcp / client / job / port). Sealed GithubEvent model so PAR-419 can add a deployment event + use case without touching the adapter's signature checks.GithubWebhookController stays at /api/public/github/webhook: constant-time HMAC check kept, then ONE facade call per delivery. Delivery id is recorded in the same transaction as the handling (idempotent, and a failed handling can be redelivered).IssuesFacade (statuses resolved by id from the repo link, or by kind via WorkspacesFacade); activity events recorded through a new IssuesFacade.recordActivity (no SQL on issues from here, no use of issues.event from outside).github.pr_comment outbox messages with idempotency keys; GithubActivitySink becomes a thin sink in activity/job calling the facade, which enqueues them./api/public/w/{slug}/github (reads members-only, writes settings.manage); MCP tasklie_list_repos / tasklie_update_repo move to github/mcp.domains/github data + settings screen; delete lib/sql/github.ts.
Known gap I will flag: the release-PR snapshot (develop -> main) cannot move without new ArchUnit entries; PAR-419 replaces releases.PR open: https://github.com/ParadauxIO/taskl.ie/pull/56 (against rebuild). ArchUnit store 1014 -> 885 distinct entries, 0 added; eslint suppressions 61 -> 58. Known gap: the release-PR snapshot (develop -> default) is no longer created, because calling ReleaseService from the new domain needs TenantContext and would add store entries; left for PAR-419. Waiting on CI.
Merged into rebuild as #56.
What's in it
GithubWebhookController is now a thin adapter. It verifies the HMAC in constant time, then sends a sealed GithubEvent to GithubFacade.receive. Delivery ids are idempotent within the same transaction.IssuesFacade, and statuses are looked up by id or kind.ProjectsFacade. No project SQL is left in github/.Security
IssuesFacade.get.Ratchet
GithubWebhookService entries.Gaps and handoffs
Merged into rebuild as #56.
What's in it
GithubWebhookController is now a thin adapter. It verifies the HMAC in constant time, then sends a sealed GithubEvent to GithubFacade.receive. Delivery ids are idempotent within the same transaction.IssuesFacade, and statuses are looked up by id or kind.ProjectsFacade. No project SQL is left in github/.Security
IssuesFacade.get.Ratchet
GithubWebhookService entries.Gaps and handoffs
Notes from the PAR-415 merge (#54):
GithubWebhookService.transitionByTypeandtransitionTo→TaskModels.Task.ref.issue.activityoutbox handler.lib/sql/github.ts resolveIssueRepostill readsproject.github_repo(see the PAR-418 handoff).