Skip to content

[Bug] Safe retry is blocked by unknown exposed tool boundaries before provider progress #912

@Astro-Han

Description

@Astro-Han

What happened?

A production build still showed the conservative interruption message:

The connection was interrupted, and PawWork could not prove whether external side effects were possible.

The session export shows the terminal request failed with an OpenAI Service Unavailable before first provider progress. No assistant output started, no tool input started, no tool call materialized, and no tool execution started. However, incident recovery still downgraded the run to ask_user_before_retry because the global side-effect boundary proof was incomplete: 10 exposed tools were classified as unknown.

This means a run that appears dynamically safe to retry is blocked by static unknown exposed-tool metadata, even when none of those tools were called.

Which area seems affected?

Model harness, prompts, tools, or session mechanics

How much does this affect you?

Makes a workflow harder, but there is a workaround

Steps to reproduce

  1. Open PawWork production build 0.0.0-prod-202605251621.
  2. Start a session with the normal tool set exposed.
  3. Hit a provider transport failure before first provider progress, such as OpenAI Service Unavailable.
  4. Inspect the session export / incident diagnostics.
  5. Observe that the terminal attempt has no visible output and no tool activity, but recovery still asks the user before retrying because side_effect_facts_complete is false.

Observed export facts from pawwork-session-mighty-cactus-2026-05-26-01-33-38.json:

{
  "classification": "external_stream_disconnect",
  "summary_key": "external_stream_disconnect.transport_failure",
  "provider_progress_seen": false,
  "visible_output_seen": false,
  "tool_input_started": false,
  "tool_call_materialized": false,
  "tool_execution_started": false,
  "unsafe_side_effect_started": false,
  "retry_safety": {
    "recommendation": "candidate_safe_auto_retry",
    "reason": "no_visible_output_or_tool_execution"
  },
  "side_effect_facts_complete": false,
  "side_effect_boundary_snapshot": {
    "exposed_tool_count": 16,
    "unknown_tool_count": 10,
    "proof_result": "incomplete",
    "proof_reason": "unknown_tool_boundary"
  },
  "incident": {
    "recovery": {
      "recommendation": "ask_user_before_retry",
      "reason": "side_effect_facts_incomplete"
    },
    "missing_provenance": ["side_effect.boundary_unknown"]
  }
}

Relevant code path:

  • packages/opencode/src/session/processor.ts: sideEffectBoundarySnapshot() marks the exposed tool set incomplete when any exposed tool effect is unknown.
  • packages/opencode/src/session/run-incident/policy.ts: !terminalFacts.side_effect_facts_complete returns ask_user_before_retry before the later retryable-transport auto-retry path can run.
  • packages/opencode/src/session/processor.ts: side_effect_facts_incomplete maps to the conservative user-facing interruption message.

What did you expect to happen?

If the terminal attempt failed before first provider progress and no output/tool activity occurred, PawWork should auto-retry once or show the safer early-transport-failure message. Unknown exposed tools should not block safe retry when no tool input started, no tool call materialized, and no tool execution started.

PawWork version

0.0.0-prod-202605251621

OS version

macOS 25.5.0

Can you reproduce it again?

Only once so far

Diagnostics

Session export inspected locally:

/Users/yuhan/Downloads/pawwork-session-mighty-cactus-2026-05-26-01-33-38.json

Potential fix directions:

  • Minimal: add an early recovery fast path for retryable transport failures before first provider progress with no visible output and no tool activity, bypassing incomplete exposed-tool boundary proof unless provider-executed/external boundaries are present.
  • Cleaner follow-up: separate static offered-tool boundary completeness from dynamic attempt-side-effect possibility, so recovery policy is based on what actually happened before interruption.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium prioritybugSomething isn't workingharnessModel harness, prompts, tool descriptions, and session mechanics

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions