From c5e6407e18323ca25b168865e93f4d69452c398b Mon Sep 17 00:00:00 2001 From: Mubashir Rahim Date: Thu, 4 Jun 2026 06:10:12 +0500 Subject: [PATCH 1/2] fix: match root planner by exact name in kickoff dedupe findActiveRootPlanner adopted any active cloud agent whose name merely started with the kickoff slug (`name.startsWith(rootSlug)`). Because the kickoff command names every root planner exactly `${rootSlug}-root`, a slug that is a prefix of another goal's slug would wrongly adopt the unrelated planner: kicking off goal `auth` while `auth-ui-root` is active matched `"auth-ui-root".startsWith("auth")`, silently attaching a fresh run to the wrong goal's planner instead of starting a new one. Match the deterministic canonical name `${rootSlug}-root` exactly. Adds a regression test asserting a prefix-only slug overlap does not adopt. Co-Authored-By: Claude Opus 4.8 --- .../scripts/__tests__/kickoff-dedupe.test.ts | 28 +++++++++++++++++++ .../skills/orchestrate/scripts/cli/task.ts | 8 +++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts b/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts index bc7cc2f..e48561c 100644 --- a/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts +++ b/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts @@ -75,6 +75,34 @@ describe("kickoff dedupe", () => { expect(active).toBeNull(); }); + test("does not adopt a planner whose slug only shares a prefix", async () => { + const now = Date.parse("2026-05-01T16:00:00.000Z"); + // An active planner for the distinct goal "refactor-ui" (named + // "refactor-ui-root") must not be adopted when kicking off goal "refactor": + // "refactor-ui-root".startsWith("refactor") is true, so a bare prefix match + // would silently attach the new run to the wrong goal's planner. + const active = await findActiveRootPlanner( + { + async list() { + return { + items: [ + { + agentId: "bc-refactor-ui", + name: "refactor-ui-root", + createdAt: now - 1_000, + latestRun: { id: "run-refactor-ui", status: "running" }, + }, + ], + }; + }, + }, + "refactor", + now + ); + + expect(active).toBeNull(); + }); + test("falls back to listRuns when list omits latest run", async () => { const now = Date.parse("2026-05-01T16:00:00.000Z"); const active = await findActiveRootPlanner( diff --git a/orchestrate/skills/orchestrate/scripts/cli/task.ts b/orchestrate/skills/orchestrate/scripts/cli/task.ts index cd3284e..785efc0 100644 --- a/orchestrate/skills/orchestrate/scripts/cli/task.ts +++ b/orchestrate/skills/orchestrate/scripts/cli/task.ts @@ -478,10 +478,16 @@ export async function findActiveRootPlanner( nowMs: number = Date.now() ): Promise { const list = await agentApi.list({ runtime: "cloud", limit: 50 }); + // Kickoff names the root planner exactly `${rootSlug}-root` (see the + // `kickoff` action). Match that full name, not a bare `startsWith(rootSlug)` + // prefix — otherwise slug `auth` would adopt an unrelated `auth-ui-root` + // planner because `"auth-ui-root".startsWith("auth")` is true, silently + // attaching a fresh run to a different goal's planner. + const rootPlannerName = `${rootSlug}-root`; for (const item of listItems(list)) { const name = stringField(item, "name"); if (!name) continue; - if (!name.startsWith(rootSlug)) continue; + if (name !== rootPlannerName) continue; const createdAt = timeMs(field(item, "createdAt")); if (createdAt === null || nowMs - createdAt > MAX_BOOT_MS) continue; const agentId = From 8b2194be47d6372a494e841290425d43887ef2d4 Mon Sep 17 00:00:00 2001 From: lauren Date: Sat, 6 Jun 2026 00:11:49 -0700 Subject: [PATCH 2/2] orchestrate: tighten kickoff-dedupe comments --- .../orchestrate/scripts/__tests__/kickoff-dedupe.test.ts | 4 ---- orchestrate/skills/orchestrate/scripts/cli/task.ts | 7 ++----- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts b/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts index e48561c..0814586 100644 --- a/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts +++ b/orchestrate/skills/orchestrate/scripts/__tests__/kickoff-dedupe.test.ts @@ -77,10 +77,6 @@ describe("kickoff dedupe", () => { test("does not adopt a planner whose slug only shares a prefix", async () => { const now = Date.parse("2026-05-01T16:00:00.000Z"); - // An active planner for the distinct goal "refactor-ui" (named - // "refactor-ui-root") must not be adopted when kicking off goal "refactor": - // "refactor-ui-root".startsWith("refactor") is true, so a bare prefix match - // would silently attach the new run to the wrong goal's planner. const active = await findActiveRootPlanner( { async list() { diff --git a/orchestrate/skills/orchestrate/scripts/cli/task.ts b/orchestrate/skills/orchestrate/scripts/cli/task.ts index 785efc0..b23c115 100644 --- a/orchestrate/skills/orchestrate/scripts/cli/task.ts +++ b/orchestrate/skills/orchestrate/scripts/cli/task.ts @@ -478,11 +478,8 @@ export async function findActiveRootPlanner( nowMs: number = Date.now() ): Promise { const list = await agentApi.list({ runtime: "cloud", limit: 50 }); - // Kickoff names the root planner exactly `${rootSlug}-root` (see the - // `kickoff` action). Match that full name, not a bare `startsWith(rootSlug)` - // prefix — otherwise slug `auth` would adopt an unrelated `auth-ui-root` - // planner because `"auth-ui-root".startsWith("auth")` is true, silently - // attaching a fresh run to a different goal's planner. + // Exact match, not startsWith: a prefix slug would otherwise adopt another + // goal's `-root` planner (e.g. "auth" adopting "auth-ui-root"). const rootPlannerName = `${rootSlug}-root`; for (const item of listItems(list)) { const name = stringField(item, "name");