feat(KB-130): allow dependent tasks to start from in-review dep branches

- Relax scheduler dep gate to treat in-review tasks as satisfied
- Add resolveBaseBranch() to detect in-review deps with unmerged worktrees
- Executor creates worktrees from dep branch instead of HEAD when baseBranch is set
- Extend file-overlap tracking to include in-review tasks with worktrees
- Add baseBranch field to Task type and store update logic
- Add scheduler and executor tests for in-review dependency handling
This commit is contained in:
Dustin Byrne
2026-03-27 02:15:20 -04:00
parent dd746ba904
commit 69dca3e11f
7 changed files with 507 additions and 27 deletions

View File

@@ -287,7 +287,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
async updateTask(
id: string,
updates: { title?: string; description?: string; prompt?: string; worktree?: string; status?: string | null; dependencies?: string[]; blockedBy?: string | null; paused?: boolean },
updates: { title?: string; description?: string; prompt?: string; worktree?: string; status?: string | null; dependencies?: string[]; blockedBy?: string | null; paused?: boolean; baseBranch?: string },
): Promise<Task> {
return this.withTaskLock(id, async () => {
const dir = this.taskDir(id);
@@ -308,6 +308,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
task.blockedBy = updates.blockedBy;
}
if (updates.paused !== undefined) task.paused = updates.paused || undefined;
if (updates.baseBranch !== undefined) task.baseBranch = updates.baseBranch;
task.updatedAt = new Date().toISOString();
await this.atomicWriteTaskJson(dir, task);

View File

@@ -66,6 +66,12 @@ export interface Task {
blockedBy?: string;
/** When true, all automated agent and scheduler interaction is suspended. */
paused?: boolean;
/** Git branch name (or task ID) to use as the starting point when
* creating this task's worktree. Set by the scheduler when a task's
* explicit dependency or `blockedBy` task is in-review with an
* unmerged branch. The executor reads this to branch from the
* dependency's branch instead of HEAD. Cleared after worktree creation. */
baseBranch?: string;
attachments?: TaskAttachment[];
log: TaskLogEntry[];
size?: "S" | "M" | "L";