// task-key.ts — the queue item KEY a harness-built TASK names (KEY: AUTOPILOT-104). // // Every task builder in framework/auto-dispatch.ts (workerTask, reviewTask, // specPassTask) starts its task with a `KEY: ` line. That line is the // task's OWN statement of which queue item it belongs to — independent of any // per-item run ref written at dispatch time. Extracting it lets a completion // be attributed to the item its mission names when the dispatch-time link is // missing (the case that lost a genuine reviewer PASS: the reviewer was // dispatched before the item reached `ai-review`, so entering `ai-review` // cleared the item's `reviewerRunId` and the completion had nothing to match). // // The word boundary before KEY is deliberate: the task text is the FIRST line // (workerTask) or the first line of a prefixed task (reviewTask embeds it as // the whole task; pi derives a `sessionName` of `: `), so // a non-anchored match still reads the real KEY before any scope prose that // might itself mention "KEY:". /** First `KEY: ` token in a task/mission text, or null. */ const TASK_KEY_RE = /\bKEY:\s*([^\s]+)/; export function taskItemKey(text: string | null | undefined): string | null { if (typeof text !== "string" || !text) return null; const m = TASK_KEY_RE.exec(text); return m?.[1] ?? null; }