The installer-failure "Queue agent to investigate" button (#5981) queues a CoS task with { useWorktree: true, openPR: true }, but the task carries no investigation identity, so it sits outside the machinery that governs every auto-filed investigation.
Gap
server/lib/investigationTasks.js defines what an investigation task IS:
INVESTIGATION_TASK_DELIVERY = { useWorktree, openPR, prCompletion: MERGE_ON_GREEN } — the UI-queued task matches the first two and omits the third.
isInvestigationTask() keys on metadata.isInvestigation (with a legacy headline-prefix fallback). A UI-queued task matches neither.
buildInvestigationFingerprint() is the durable dedup key consumed by the reaper (cosTaskStore.js) and the retry decision (services/investigationRetry.js).
Consequences for a UI-queued investigation:
- It is invisible to the investigation dedup scan and the circuit breaker, so nothing bounds how many pile up beyond the generic same-description 409.
- It is not covered by the meta-cascade guard — if the queued run itself fails,
agentErrorAnalysis can file an auto-investigation of the investigation.
- It does not participate in investigation auto-retry.
createCosTaskSchema (server/lib/cosValidation.js) has no isInvestigation field, so Zod strips any client attempt to set one — this cannot be fixed client-side.
Scope
- Decide the identity a client-queued investigation gets. Recommended: add a narrowly-typed
isInvestigation boolean (or a small investigation: { source, fingerprint } object) to createCosTaskSchema, routed by cosTaskStore.addTask into metadata.isInvestigation exactly as the server-side producer does — the client supplies the flag, never a hand-crafted fingerprint.
- Derive the fingerprint server-side from the submitted context so a client cannot collide with, or evict, an auto-filed investigation.
- Have
QueueInstallInvestigationButton (client/src/components/install/QueueInstallInvestigationButton.jsx) set the flag, and reconcile its INSTALL_INVESTIGATION_DELIVERY constant with INVESTIGATION_TASK_DELIVERY — including whether a user-initiated install investigation should also carry prCompletion: merge-on-green (a UI-queued repair is user-initiated, so review-then-merge may be the better default; make the call and document it).
- Cover the round-trip: a UI-queued task is recognized by
isInvestigationTask(), is deduped against a matching auto-filed one, and does not trigger a meta-cascade when it fails.
Acceptance criteria
Related to #5981.
The installer-failure "Queue agent to investigate" button (#5981) queues a CoS task with
{ useWorktree: true, openPR: true }, but the task carries no investigation identity, so it sits outside the machinery that governs every auto-filed investigation.Gap
server/lib/investigationTasks.jsdefines what an investigation task IS:INVESTIGATION_TASK_DELIVERY={ useWorktree, openPR, prCompletion: MERGE_ON_GREEN }— the UI-queued task matches the first two and omits the third.isInvestigationTask()keys onmetadata.isInvestigation(with a legacy headline-prefix fallback). A UI-queued task matches neither.buildInvestigationFingerprint()is the durable dedup key consumed by the reaper (cosTaskStore.js) and the retry decision (services/investigationRetry.js).Consequences for a UI-queued investigation:
agentErrorAnalysiscan file an auto-investigation of the investigation.createCosTaskSchema(server/lib/cosValidation.js) has noisInvestigationfield, so Zod strips any client attempt to set one — this cannot be fixed client-side.Scope
isInvestigationboolean (or a smallinvestigation: { source, fingerprint }object) tocreateCosTaskSchema, routed bycosTaskStore.addTaskintometadata.isInvestigationexactly as the server-side producer does — the client supplies the flag, never a hand-crafted fingerprint.QueueInstallInvestigationButton(client/src/components/install/QueueInstallInvestigationButton.jsx) set the flag, and reconcile itsINSTALL_INVESTIGATION_DELIVERYconstant withINVESTIGATION_TASK_DELIVERY— including whether a user-initiated install investigation should also carryprCompletion: merge-on-green(a UI-queued repair is user-initiated, so review-then-merge may be the better default; make the call and document it).isInvestigationTask(), is deduped against a matching auto-filed one, and does not trigger a meta-cascade when it fails.Acceptance criteria
isInvestigationTask().INVESTIGATION_TASK_DELIVERY, or deliberately different with the reason recorded in code).Related to #5981.