fix(FN-branch-group): address second-round PR review feedback (#1357)

- syncGroupPrCallback forwards owner/repo to updatePr (multi-project daemons
  could 404 or edit an unrelated same-numbered PR via process-cwd fallback)
- merger background reconcile re-reads the group before persisting and skips
  the write when the PR snapshot changed (stale-write race vs newer open PR)
- branchContext.groupId trimmed on metadata emit/parse round-trip
- triageSlice non-shared invariant assertions (no groupId, no group row)
This commit is contained in:
gsxdsm
2026-06-03 15:46:23 -07:00
parent 1b83317cfe
commit 3e927bc5fc
7 changed files with 95 additions and 6 deletions

View File

@@ -1366,6 +1366,11 @@ describe("syncGroupPrCallback (U6)", () => {
const result = await sync({ cwd: "/tmp/project", group: group as never, members });
expect(result).toEqual({ prNumber: 42, prUrl: "https://github.com/owner/repo/pull/42", prState: "open" });
expect(github.updatePr).toHaveBeenCalledTimes(1);
// T4: owner/repo must be forwarded so multi-project daemons target the
// resolved per-project repo, not process.cwd().
expect(github.updatePr).toHaveBeenCalledWith(
expect.objectContaining({ owner: "owner", repo: "repo", number: 42 }),
);
const body = (github.updatePr.mock.calls[0][0] as { body: string }).body;
expect(body).toContain("Completion: 0/2 landed");
expect(body).toContain("FN-A: Alpha");

View File

@@ -39,7 +39,7 @@ interface GitHubOperations {
}>;
mergePr(params: { number: number; method?: "merge" | "squash" | "rebase" }): Promise<PrInfo>;
getPrStatus(owner: string, repo: string, number: number): Promise<PrInfo>;
updatePr(params: { number: number; title?: string; body?: string }): Promise<PrInfo>;
updatePr(params: { owner?: string; repo?: string; number: number; title?: string; body?: string }): Promise<PrInfo>;
closePr(params: { number: number }): Promise<PrInfo>;
}
@@ -287,6 +287,8 @@ export function syncGroupPrCallback(
return { prNumber: current.number, prUrl: current.url, prState: currentState };
}
const updated = await github.updatePr({
owner: repo.owner,
repo: repo.repo,
number: group.prNumber,
title: buildGroupPullRequestTitle(group, members),
body: buildGroupPrSyncBody(group, members),