fix(gsd): unblock mixed-dependency zero-dep slices (#4025)
This commit is contained in:
parent
510629c8cb
commit
92ac0e3a7d
2 changed files with 31 additions and 0 deletions
|
|
@ -107,6 +107,11 @@ export function getPriorSliceCompletionBlocker(
|
|||
// it may be a cross-milestone reference handled elsewhere.
|
||||
}
|
||||
} else {
|
||||
const milestoneUsesExplicitDeps = slices.some((slice) => slice.depends.length > 0);
|
||||
if (milestoneUsesExplicitDeps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Positional fallback is only a heuristic for legacy slices with no
|
||||
// declared dependencies. Skip any earlier slice that depends on the
|
||||
// target, directly or transitively, or we can deadlock a valid zero-dep
|
||||
|
|
|
|||
|
|
@ -172,6 +172,32 @@ test("dispatch guard ignores positionally-earlier reverse dependents for zero-de
|
|||
);
|
||||
});
|
||||
|
||||
test("dispatch guard treats zero-dependency slices as independent when a milestone uses explicit deps (#3998)", (t) => {
|
||||
const repo = setupRepo();
|
||||
t.after(() => teardownRepo(repo));
|
||||
|
||||
mkdirSync(join(repo, ".gsd", "milestones", "M022"), { recursive: true });
|
||||
|
||||
insertMilestone({ id: "M022", title: "Mixed dependency milestone" });
|
||||
insertSlice({ id: "S02", milestoneId: "M022", title: "Core A", status: "complete", depends: [], sequence: 2 });
|
||||
insertSlice({ id: "S03", milestoneId: "M022", title: "Core B", status: "complete", depends: [], sequence: 3 });
|
||||
insertSlice({ id: "S05", milestoneId: "M022", title: "Blocked integration", status: "pending", depends: ["S02", "S03", "S07"], sequence: 5 });
|
||||
insertSlice({ id: "S06", milestoneId: "M022", title: "Independent zero-dep slice", status: "pending", depends: [], sequence: 6 });
|
||||
insertSlice({ id: "S07", milestoneId: "M022", title: "Late prerequisite", status: "pending", depends: ["S02"], sequence: 7 });
|
||||
|
||||
writeFileSync(join(repo, ".gsd", "milestones", "M022", "M022-ROADMAP.md"), "# M022\n");
|
||||
|
||||
assert.equal(
|
||||
getPriorSliceCompletionBlocker(repo, "main", "execute-task", "M022/S06/T02"),
|
||||
null,
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
getPriorSliceCompletionBlocker(repo, "main", "execute-task", "M022/S05/T01"),
|
||||
"Cannot dispatch execute-task M022/S05/T01: dependency slice M022/S07 is not complete.",
|
||||
);
|
||||
});
|
||||
|
||||
test("dispatch guard allows slice with all declared dependencies complete", (t) => {
|
||||
const repo = setupRepo();
|
||||
t.after(() => teardownRepo(repo));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue