FN-5839: prevent stale integration-advance sync prompts

Treat rewritten integration-branch advances as handled when the working tree is already aligned.

- Add a new `superseded` resolution for unreachable advance SHAs that remain after history rewrites while HEAD matches the local integration tip.
- Update Git status collection logic and route/API status typings to propagate the new resolution state.
- Update Git Manager modal messaging and dismiss behavior so handled `superseded` entries do not show a sync CTA.
- Extend dashboard route and modal tests, and refresh dashboard guide docs for the new classification behavior.

Files changed:
 docs/dashboard-guide.md                            |  5 +--
 packages/dashboard/app/api/legacy.ts               |  2 +-
 .../dashboard/app/components/GitManagerModal.tsx   |  6 ++--
 .../components/__tests__/GitManagerModal.test.tsx  |  5 ++-
 .../dashboard/src/__tests__/routes-git.test.ts     | 36 ++++++++++++++++++++--
 .../dashboard/src/routes/register-git-github.ts    | 13 ++++++--
 6 files changed, 55 insertions(+), 12 deletions(-)

Fusion-Task-Id: FN-5839

Fusion-Task-Lineage: 6b4afb73-587d-4319-8ad8-f1d5d54bc7bf
This commit is contained in:
gsxdsm
2026-06-01 11:52:02 -07:00
parent 4a20aa140e
commit 3602fb9a23
6 changed files with 55 additions and 12 deletions

View File

@@ -3041,6 +3041,7 @@ describe("GitManagerModal", () => {
describe("recent merge advances panel", () => {
it("hides sync CTA when advances are handled and head is aligned", async () => {
const supersededSha = "e".repeat(40);
(fetchGitStatus as any).mockResolvedValue({
branch: "main",
commit: "abc1234",
@@ -3053,12 +3054,14 @@ describe("GitManagerModal", () => {
recentMergeAdvances: [
{ taskId: "FN-1", fromSha: null, toSha: "a".repeat(40), advancedAt: new Date().toISOString(), needsAction: false, resolution: "orphaned" },
{ taskId: "FN-2", fromSha: null, toSha: "b".repeat(40), advancedAt: new Date().toISOString(), needsAction: false, resolution: "subsumed" },
{ taskId: "FN-3", fromSha: null, toSha: supersededSha, advancedAt: new Date().toISOString(), needsAction: false, resolution: "superseded" },
],
});
render(<GitManagerModal isOpen={true} onClose={vi.fn()} tasks={mockTasks} addToast={mockAddToast} />);
await waitFor(() => expect(screen.getByTestId("recent-merge-advances")).toBeInTheDocument());
expect(screen.getByText(/\(0 need action\)/i)).toBeInTheDocument();
expect(screen.queryByTestId("sync-working-tree-btn")).not.toBeInTheDocument();
expect(screen.getByTestId(`dismiss-advance-${supersededSha}`)).toBeInTheDocument();
});
it("shows sync CTA when pending advance exists", async () => {
@@ -3080,7 +3083,7 @@ describe("GitManagerModal", () => {
await userEvent.click(screen.getByTestId("sync-working-tree-btn"));
});
it("dismisses orphaned/subsumed entries", async () => {
it("dismisses orphaned/subsumed/superseded entries", async () => {
const toSha = "d".repeat(40);
(fetchGitStatus as any).mockResolvedValue({
branch: "main",