* fix(server): gate GitHub auto-close on closing keywords (MUL-2680)
Closesmultica-ai/multica#3264. The PR webhook previously treated any
mention of an issue identifier in a PR title/body/branch as a close
intent, so a body of "Closes MUL-1. Follow up in MUL-2. Unblocks MUL-3."
would advance all three issues to done on merge. The auto-link layer
stays generous (mentions still link the PR), but advancing to done now
requires an explicit "Closes/Fixes/Resolves MUL-X" keyword adjacent to
the identifier in the title or body — bare title prefixes (`MUL-1: ...`)
and branch-name references no longer auto-complete.
MUL-2680
Co-authored-by: multica-agent <github@multica.ai>
* fix(server): persist close_intent on issue↔PR link rows (MUL-2680)
The first take of MUL-2680 gated auto-advance on `closingIdents[id]` from
the current webhook event. That broke the multi-PR sibling case: a PR
declaring `Closes MUL-X` could merge first while a link-only sibling
stayed open, leaving the issue in_progress; when the sibling closed
later, its webhook carried no closing keyword and the handler skipped
re-evaluation, so the issue stayed stuck forever.
Move close intent from per-event state to per-link state:
- New `close_intent` column on `issue_pull_request` (migration 109),
set monotonically — `LinkIssueToPullRequest` ORs the existing flag with
the incoming one so a subsequent webhook re-fire without the keyword
cannot clear it.
- New `GetIssuePullRequestCloseAggregate` query returns open-count and
merged-with-close-intent-count for an issue. The auto-advance gate
now reads from this persisted aggregate, which is event-agnostic: any
terminal linked-PR event re-evaluates and the verdict only depends on
accumulated DB state.
- Webhook handler links all mentioned identifiers first (writing
close_intent for the ones declared with a keyword), then iterates the
affected issues in a separate pass to re-evaluate. The 'only fires for
keyword-declared identifiers in this event' gate is gone — replaced by
`merged_with_close_intent_count > 0` against the link rows.
Regression test `TestWebhook_LinkOnlySiblingMergeAfterCloseKeywordPR`
walks the full open→merge→open→merge sequence Elon described and asserts
the issue advances on the link-only sibling's merge.
MUL-2680
Co-authored-by: multica-agent <github@multica.ai>
* Fix GitHub close intent updates
Co-authored-by: multica-agent <github@multica.ai>
---------
Co-authored-by: multica-agent <github@multica.ai>
Co-authored-by: Eve <eve@multica-ai.local>