feat: surface OpenCode provider limit errors (#2167)
This commit is contained in:
+90
@@ -0,0 +1,90 @@
|
||||
---
|
||||
id: "01-capture-opencode-error-diagnostics"
|
||||
title: "Capture OpenCode error diagnostics"
|
||||
status: done
|
||||
wave: 1
|
||||
depends_on: []
|
||||
plan: "plan.md"
|
||||
spec: "../../specs/agent-stall-recovery/spec.md"
|
||||
---
|
||||
|
||||
# Task 01: Capture OpenCode error diagnostics
|
||||
|
||||
## Acceptance
|
||||
|
||||
- Every managed OpenCode ACP command enables `--print-logs --log-level ERROR`,
|
||||
while other managed agent commands remain unchanged.
|
||||
- Agentctl delivers cleaned live stderr lines to an optional consumer without
|
||||
blocking child-process drainage or changing the bounded recent-stderr API.
|
||||
- For OpenCode, generic logs, recent-stderr, and nonzero-exit events contain
|
||||
only the parser's safe provider-message projection; unrecognized records are
|
||||
excluded so workspace URLs and identifiers cannot leak through the fallback
|
||||
error path.
|
||||
- The OpenCode parser accepts only foreground `stream error` records and
|
||||
returns allowlisted, URL-free provider/model/message/timestamp/reset fields;
|
||||
background, malformed, and unrelated records are rejected.
|
||||
|
||||
## Verification
|
||||
|
||||
- `cd apps/backend && go test ./internal/agent/agents ./internal/agentctl/server/process ./internal/agentctl/server/adapter/transport/acp -run 'Test(OpenCode|ManagedNPMRuntime|Manager.*Stderr|ManagerProcessExit|ParseOpenCode)'`
|
||||
|
||||
Use TDD: command-contract, stderr-delivery, and parser tests must fail before
|
||||
their production changes are added.
|
||||
|
||||
## Files likely touched
|
||||
|
||||
- `apps/backend/internal/agent/agents/opencode_acp.go`
|
||||
- `apps/backend/internal/agent/agents/opencode_acp_test.go`
|
||||
- `apps/backend/internal/agent/agents/managed_npm_runtime_test.go`
|
||||
- `apps/backend/internal/agent/agents/ACP_BRIDGE_VERSIONS.md`
|
||||
- `apps/backend/internal/agent/runtime/lifecycle/manager_launch_test.go`
|
||||
- `apps/backend/internal/agentctl/server/adapter/adapter.go`
|
||||
- `apps/backend/internal/agentctl/server/process/manager.go`
|
||||
- `apps/backend/internal/agentctl/server/process/manager_test.go`
|
||||
- `apps/backend/internal/agentctl/server/adapter/transport/acp/opencode_stderr.go`
|
||||
- `apps/backend/internal/agentctl/server/adapter/transport/acp/opencode_stderr_test.go`
|
||||
- `apps/backend/internal/agentctl/types/streams/provider_error.go`
|
||||
- `apps/backend/internal/agentctl/types/streams/agent.go`
|
||||
|
||||
## Dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Parallelism
|
||||
|
||||
Sequential. Task 02 consumes the parser, consumer, and safe provider-error
|
||||
contract introduced here.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Spec sections `Correlated terminal diagnostics`, `Diagnostic contract`, and
|
||||
diagnostic failure-mode scenarios
|
||||
- ADR-2026-08-02 stderr ownership, correlation, and sanitization rules
|
||||
- Existing `Manager.readStderr`, `StderrProvider`, `ManagedNPMRuntimeSpec`, and
|
||||
ACP adapter construction patterns
|
||||
|
||||
## Risks
|
||||
|
||||
- `readStderr` is a process-liveness boundary; consumer delivery must remain
|
||||
non-blocking, including when the bounded provider-diagnostic channel is full.
|
||||
- The parser must not preserve the OpenCode workspace URL or identifiers found
|
||||
in the observed `error.error` suffix.
|
||||
- The generic process-exit path must consume only the safe OpenCode projection;
|
||||
raw stderr must never appear in logs, the recent-stderr ring, or exit events.
|
||||
|
||||
## Output contract
|
||||
|
||||
Report RED assertions, exact argv, normalized field allowlist, rejected record
|
||||
cases, test results, files changed, blockers, and risks. Mark this task `done`
|
||||
and update its plan checkbox in the same conversation.
|
||||
|
||||
## Results
|
||||
|
||||
The managed command contract, optional stderr consumer, parser privacy,
|
||||
bounded-channel, and nonzero-exit projection cases all have focused
|
||||
regressions. OpenCode now uses `acp --print-logs --log-level ERROR`; the parser
|
||||
keeps only the validated foreground
|
||||
session/provider/model/message/timestamp/reset fields and rejects title,
|
||||
`small=true`, malformed, unrelated, or incomplete records. The focused
|
||||
verification passed with 26 tests across three packages; the full backend
|
||||
suite also passed.
|
||||
Reference in New Issue
Block a user