fix(core): expand merge-blocker statuses to cover all transient states
Audit of task.status assignments across packages/core and packages/engine surfaced five additional transient/in-flight statuses that should block auto-merge but weren't in BLOCKING_TASK_STATUSES: - awaiting-approval — triage spec awaiting user approval - needs-replan — scheduler/executor/triage signaled re-plan needed - mission-validation — mission-level validation in flight - queued — scheduler-side transient state - stuck-killed — defensive guard; task killed by stuck detector Each represents a state where finalizing the merge violates user intent or invariants. Group the set with comments explaining the intent of each group so future additions can be slotted appropriately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -60,6 +60,34 @@ describe("getTaskMergeBlocker", () => {
|
|||||||
.toContain("specifying");
|
.toContain("specifying");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("returns reason when task is awaiting-approval", () => {
|
||||||
|
expect(getTaskMergeBlocker({ ...baseTask, status: "awaiting-approval" }))
|
||||||
|
.toContain("awaiting-approval");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns reason when task needs-replan", () => {
|
||||||
|
// scheduler/executor/triage move a task here when its plan must be revisited.
|
||||||
|
expect(getTaskMergeBlocker({ ...baseTask, status: "needs-replan" }))
|
||||||
|
.toContain("needs-replan");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns reason when task is in mission-validation", () => {
|
||||||
|
expect(getTaskMergeBlocker({ ...baseTask, status: "mission-validation" }))
|
||||||
|
.toContain("mission-validation");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns reason when task is queued (scheduler transient)", () => {
|
||||||
|
expect(getTaskMergeBlocker({ ...baseTask, status: "queued" }))
|
||||||
|
.toContain("queued");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns reason when task is stuck-killed", () => {
|
||||||
|
// Defensive: if this transient marker surfaces in in-review, the task
|
||||||
|
// needs investigation rather than auto-merge.
|
||||||
|
expect(getTaskMergeBlocker({ ...baseTask, status: "stuck-killed" }))
|
||||||
|
.toContain("stuck-killed");
|
||||||
|
});
|
||||||
|
|
||||||
it("returns reason when task has incomplete steps", () => {
|
it("returns reason when task has incomplete steps", () => {
|
||||||
expect(getTaskMergeBlocker({
|
expect(getTaskMergeBlocker({
|
||||||
...baseTask,
|
...baseTask,
|
||||||
|
|||||||
@@ -2,15 +2,28 @@ import type { Task, WorkflowStepResult } from "./types.js";
|
|||||||
|
|
||||||
const BLOCKING_TASK_STATUSES = new Set([
|
const BLOCKING_TASK_STATUSES = new Set([
|
||||||
"failed",
|
"failed",
|
||||||
|
// ── User-attention / awaiting-handoff states ─────────────────────────
|
||||||
"awaiting-inspection",
|
"awaiting-inspection",
|
||||||
"awaiting-user-review",
|
"awaiting-user-review",
|
||||||
|
"awaiting-approval", // triage spec awaiting user approval
|
||||||
|
// ── Active merge in-flight ───────────────────────────────────────────
|
||||||
"merging",
|
"merging",
|
||||||
"merging-pr",
|
"merging-pr",
|
||||||
|
// ── Re-planning / triage states (scope not finalized) ────────────────
|
||||||
// A task in planning/triage hasn't finalized its scope yet — letting it
|
// A task in planning/triage hasn't finalized its scope yet — letting it
|
||||||
// merge skips the work the user moved it back to plan. Same for the legacy
|
// merge skips the work the user moved it back to plan. Same for the legacy
|
||||||
// "specifying" alias migrated to "planning" in db.ts.
|
// "specifying" alias migrated to "planning" in db.ts.
|
||||||
"planning",
|
"planning",
|
||||||
"specifying",
|
"specifying",
|
||||||
|
"needs-replan", // scheduler/executor/triage signaled re-plan
|
||||||
|
// ── Mission-level validation in flight ───────────────────────────────
|
||||||
|
"mission-validation",
|
||||||
|
// ── Scheduler-side transient state ───────────────────────────────────
|
||||||
|
"queued", // scheduler placed the task in line; not finalized
|
||||||
|
// ── Abnormal termination — defensive guard ───────────────────────────
|
||||||
|
// Task was killed by the stuck detector. If it surfaces in in-review,
|
||||||
|
// it needs investigation, not auto-merge.
|
||||||
|
"stuck-killed",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const NON_TERMINAL_STEP_STATUSES = new Set([
|
const NON_TERMINAL_STEP_STATUSES = new Set([
|
||||||
|
|||||||
Reference in New Issue
Block a user