Skip to content

Active-reasoning veto misses resumed reasoning outside the {thoughts, code} content_type allowlist (fail-open) #1

Description

@StartupBros

evaluateProTurnCompletion's active-reasoning veto only treats a node as "still reasoning" when both conditions hold:

(message.content?.content_type === "thoughts" ||
  message.content?.content_type === "code") &&
message.metadata?.reasoning_status === "is_reasoning"

(src/pro-final.ts, current main at 12ed925a5.)

If a resumed-reasoning node carries reasoning_status: "is_reasoning" but a content_type other than thoughts/code, the veto doesn't see it. A terminal-shaped interim text produced before that node then passes every other check (reasoning_ended precedes it, it is the only terminal leaf) and gets returned as {done: true, ...} — a false-positive terminal on a mid-reasoning progress text.

This reproduces the exact failure the function's design comment says it exists to prevent: "Pro can emit several short progress texts carrying both flags and then resume reasoning."

Reproduction

A mapping with:

recap(reasoning_ended)
  -> terminal-shaped interim text
    -> resumed reasoning {
         content_type: "reasoning",
         reasoning_status: "is_reasoning"
       }

Current result (executed against a logic-identical plain-Node port of pro-final.ts):

{
  "done": true,
  "finalText": "Quick take: looks fine at a glance.",
  "finalMessageId": "msg-interim",
  "modelSlug": "gpt-5-6-pro",
  "finishReason": "stop"
}

Expected: done: false.

Suggested fix

const activeReasoning = turnMessages.filter(
  ({ message }) => message.metadata?.reasoning_status === "is_reasoning",
);

That is deliberately more conservative: reasoning_status is the state signal; content_type names the node kind. Dropping the kind allowlist prevents new/renamed reasoning node types from failing open. It may reject additional ambiguous mappings (safe false negatives), but it cannot newly accept an in-progress turn.

I reproduced this red/green in a Vitest regression: the test fails before the one-line change (expected true to be false) and passes after. Happy to open a small PR with the fix and regression test if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions