[Fix] The completion check skips every task delegated from a Session - #3083
Conversation
|
No code issues found. See task
Reviewed 293dae1 |
| and( | ||
| eq(taskMessages.taskId, taskId), | ||
| eq(taskMessages.eventType, ACP_ENVELOPE_EVENT_TYPES.UserPrompt), | ||
| sql`coalesce(${taskMessages.metadata} ->> 'visibleInTranscript', 'true') <> 'false'`, |
There was a problem hiding this comment.
Removing this filter also admits the harness's hidden UserPrompt records. For example, submitPrompt() persists the completion-gate reminder with visibleInTranscript: false; on the next gate pass it becomes a follow-up request. That can make the judgment evaluate its own remediation instructions and repeatedly flag an otherwise completed task. Keep filtering those system-injected/reminder prompts while allowing the delegated opening request, and add a regression test for a hidden completion-gate reminder.
There was a problem hiding this comment.
The source check does not cover the hidden continuations sent through drainQueuedPrompts(). Provider-error/rate-limit retries, visual-proof recovery, and plan-exit continuations are enqueued with visibleInTranscript: false but no source; the drain persists them as UserPrompt rows without a source. With the visibility SQL filter removed, these messages still enter followUps and can influence a later completion judgment. Preserve an origin/source for queued harness prompts (or otherwise exclude them) and add coverage for one queued hidden continuation.
There was a problem hiding this comment.
This is still possible after a queue restore: RuntimePromptQueue.restore() rebuilds each message without copying source. A reconnect, or a shouldBlockPrompt/shouldReconnect replay, therefore drains the hidden continuation without its opencode-* marker and lets it enter completion-gate follow-ups. Preserve source in restore() and cover a restored hidden continuation.
There was a problem hiding this comment.
Copying source through restore() fixes the reconnect path, but the predicate only excludes opencode-* sources. run-task.ts also delivers hidden environment-setup notices with source: 'environment-setup'; handleSendMessage() persists those as UserPrompt rows. They now pass isHarnessPrompt() and are included as completion-gate follow-ups, so the judge can still receive a platform notification as user work. Exclude known non-user hidden prompt sources (or retain a reliable request-origin marker) and cover this path.
|
Addressed with a |
Problem
First live observation of the turn-end completion check from #3071, on the nightly deployment: the harness ran it at turn end and the API answered
skippedin 101 ms, before any judgment call.A task delegated from a Session receives its request as a hidden
<request>prompt (visibleInTranscript=false). The request loader filtered hidden prompts out, found no request, and skipped. That is most tasks.Change
The loader reads every stored user prompt. Hidden ones are requests too: a delegated task's opening prompt is one, and the harness never persists its own reminders as prompts, so nothing else can get in. Test added with a hidden opening prompt.
Validation
task-completion-gate.test.ts(11),pnpm lint:fast,pnpm check-types:fast,pnpm knip.