Skip to content

fix(cloud-agent-next): preserve classified assistant terminal failures - #4659

Open
eshurakov wants to merge 1 commit into
mainfrom
eshurakov/cloud-agent-improvements
Open

fix(cloud-agent-next): preserve classified assistant terminal failures#4659
eshurakov wants to merge 1 commit into
mainfrom
eshurakov/cloud-agent-improvements

Conversation

@eshurakov

Copy link
Copy Markdown
Contributor

Summary

Production failure analysis (2026-07-19 → 21) found every sampled agent_activity / assistant_error run was really a model-gateway rejection (402 insufficient credits, free-tier 429, managed-provider 5xx), but two lossy steps collapsed explicit wrapper codes before PostgreSQL reporting: CloudAgentSession overwrote every failed message.updated terminal transition with assistant_error, and queue-reports.ts remapped payment_required / model_missing back to generic phase-based codes.

  • Preserve classified terminal failures: one shared assistant terminal classifier (classifyAssistantTerminalFailure) returns a structured failure code plus bounded safe message, used by both message.updated and fatal-wrapper ingest. payment_required and model_missing now persist unchanged; everything else stays assistant_error. Credit detection no longer uses exact-string matching, so appended gateway bodies (Payment Required: {...}, negative-balance text) classify correctly — raw gateway bodies still never reach reports or logs.
  • DB: permit the four new stage/code pairs in CloudAgentRunFailureClassifications and drop the duplicated cloud_agent_session_runs_failure_classification_check constraint (drop-only migration 0191) instead of maintaining a second copy of the classification matrix in the database.
  • SQLite prefix lookup: replace LIKE 'prefix%' with literal substr(entity_id, 1, length(prefix)) = prefix, removing the pattern engine implicated in LIKE or GLOB pattern too complex flush failures; %/_ in prefixes are now data, not patterns.
  • Wrapper health diagnostics: malformed wrapper responses now log status, content type, byte length, SHA-256 fingerprint, and a per-request correlation ID (x-kilo-request-id) — never the body. The wrapper wraps /health in a top-level error boundary returning a bounded structured HEALTH_CHECK_FAILED response carrying the same correlation ID.
  • e2e harness: new classified-failure-report lifecycle scenario (payment / model) asserting terminal classification and safe diagnostic in the persisted run row, plus a fake-LLM model-missing scenario.

Deployment order: apply migration 0191 before deploying the worker that emits the new stage/code pairs.

Verification

  • No manual end-to-end run: the local fake-LLM e2e scenario requires the full local Worker + Docker sandbox stack and is a manual harness, so it was added but not executed here. Behavior is covered by new unit and integration tests (see Reviewer Notes).

Visual Changes

N/A

Reviewer Notes

Automated checks run locally, all passing:

  • cloud-agent-next unit tests (2233 passed; one unrelated load-sensitive git-hook test timed out once under parallel load and passes consistently in isolation), integration tests (210 passed), typecheck (tsgo + wrapper), lint (0 problems)
  • pnpm drizzle check (migration consistency) and packages/db/src/schema.test.ts (37 passed; note the web jest config does not discover packages/db tests without a roots override — pre-existing, reproduced on main)
  • worker-utils tests (300 passed) for the CloudAgentRunFailureClassifications change
  • pnpm format:changed / git diff --check clean

Reviewer focus: the classifier regexes in safe-failure-projection.ts (they only ever emit allowlisted messages), the curl -w response-metadata marker parsing in ExecCurlWrapperTransport, and the drop-only migration.

Comment thread services/cloud-agent-next/src/session/safe-failure-projection.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 5 Issues Found | Recommendation: Address before merge

Executive Summary

smoke.ts calls killSandboxFamily/waitForSandboxFamilyGone in its stale-container cleanup block but no longer imports them, which will throw a ReferenceError whenever the harness starts with leftover containers from a prior run.

Overview

Severity Count
CRITICAL 1
WARNING 1
SUGGESTION 3
Issue Details (click to expand)

CRITICAL

File Line Issue
services/cloud-agent-next/test/e2e/smoke.ts 29 killSandboxFamily/waitForSandboxFamilyGone used later in the file but removed from imports — ReferenceError on stale-container cleanup

WARNING

File Line Issue
services/cloud-agent-next/test/e2e/sandbox-control.ts 270 waitForSandboxCleanupQuiescence checks the timeout deadline before the stability window, causing a false-negative when both conditions are met on the same tick

SUGGESTION

File Line Issue
packages/worker-utils/src/cloud-agent-queue-report.ts 39 Duplicate agent_activity/payment_required and model_missing classification entries added
services/cloud-agent-next/test/e2e/README.md 143 States the matrix creates "fourteen" sessions; DEFAULT_MATRIX has fifteen entries after this PR's additions
services/cloud-agent-next/src/kilo/wrapper-client.ts 367 Missing curl -w metadata marker silently falls back to status 200 instead of surfacing a diagnostic failure
Files Reviewed (30 files)
  • docs/superpowers/specs/2026-07-22-cloud-agent-e2e-health-design.md - 0 issues
  • packages/worker-utils/src/cloud-agent-queue-report.ts - 1 issue
  • services/cloud-agent-next/src/agent-sandbox/cloudflare/cloudflare-agent-sandbox.ts - 0 issues
  • services/cloud-agent-next/src/agent-sandbox/cloudflare/cloudflare-agent-sandbox.test.ts - 0 issues
  • services/cloud-agent-next/src/kilo/wrapper-client.ts - 1 issue
  • services/cloud-agent-next/src/kilo/wrapper-client.test.ts - 0 issues
  • services/cloud-agent-next/src/session/queries/events.ts - 0 issues
  • services/cloud-agent-next/src/session/safe-failure-projection.ts - 0 issues (prior regex over-match finding verified fixed)
  • services/cloud-agent-next/src/session/safe-failure-projection.test.ts - 0 issues
  • services/cloud-agent-next/src/shared/wrapper-http.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/queue-reports.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/queue-reports.test.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/report-store.test.ts - 0 issues
  • services/cloud-agent-next/src/websocket/ingest.ts - 0 issues
  • services/cloud-agent-next/src/websocket/ingest.test.ts - 0 issues
  • services/cloud-agent-next/test/e2e/README.md - 1 issue
  • services/cloud-agent-next/test/e2e/auth.ts - 0 issues
  • services/cloud-agent-next/test/e2e/client.ts - 0 issues
  • services/cloud-agent-next/test/e2e/fake-llm-server.ts - 0 issues
  • services/cloud-agent-next/test/e2e/lifecycle.ts - 0 issues
  • services/cloud-agent-next/test/e2e/run.ts - 0 issues
  • services/cloud-agent-next/test/e2e/sandbox-control.ts - 1 issue
  • services/cloud-agent-next/test/e2e/smoke.ts - 1 issue
  • services/cloud-agent-next/test/integration/session/events.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/client-session-tracking.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/fake-llm-server.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/lifecycle-preparation.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/sandbox-control.test.ts - 0 issues
  • services/cloud-agent-next/wrangler.jsonc - 0 issues
  • services/cloud-agent-next/wrapper/src/server.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/server.test.ts - 0 issues

Fix these issues in Kilo Cloud

Previous Review Summaries (3 snapshots, latest commit 05739c0)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 05739c0)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 2
Issue Details (click to expand)

SUGGESTION

File Line Issue
services/cloud-agent-next/src/session/safe-failure-projection.ts 86 Negative-balance regex may misclassify unrelated "balance" mentions as payment_required
docs/superpowers/specs/2026-07-22-cloud-agent-e2e-health-design.md 40 Design doc states quiescence needs two seconds, but the implementation (smoke.ts) and README both use five seconds
Files Reviewed (34 files, incremental)
  • docs/superpowers/specs/2026-07-22-cloud-agent-e2e-health-design.md - 1 issue
  • services/cloud-agent-next/src/agent-sandbox/cloudflare/cloudflare-agent-sandbox.ts - 0 issues
  • services/cloud-agent-next/src/agent-sandbox/cloudflare/cloudflare-agent-sandbox.test.ts - 0 issues
  • services/cloud-agent-next/test/e2e/README.md - 0 issues
  • services/cloud-agent-next/test/e2e/client.ts - 0 issues
  • services/cloud-agent-next/test/e2e/lifecycle.ts - 0 issues
  • services/cloud-agent-next/test/e2e/sandbox-control.ts - 0 issues
  • services/cloud-agent-next/test/e2e/smoke.ts - 0 issues
  • services/cloud-agent-next/test/unit/client-session-tracking.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/lifecycle-preparation.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/sandbox-control.test.ts - 0 issues
  • services/cloud-agent-next/wrangler.jsonc - 0 issues
  • services/cloud-agent-next/src/session/safe-failure-projection.ts - 1 issue (carried forward, unresolved)

Fix these issues in Kilo Cloud

Previous review (commit 07d0a00)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 2
Issue Details (click to expand)

SUGGESTION

File Line Issue
services/cloud-agent-next/src/session/safe-failure-projection.ts 86 Negative-balance regex may misclassify unrelated "balance" mentions as payment_required
docs/superpowers/specs/2026-07-22-cloud-agent-e2e-health-design.md 40 Design doc states quiescence needs two seconds, but the implementation (smoke.ts) and README both use five seconds
Files Reviewed (34 files, incremental)
  • docs/superpowers/specs/2026-07-22-cloud-agent-e2e-health-design.md - 1 issue
  • services/cloud-agent-next/src/agent-sandbox/cloudflare/cloudflare-agent-sandbox.ts - 0 issues
  • services/cloud-agent-next/src/agent-sandbox/cloudflare/cloudflare-agent-sandbox.test.ts - 0 issues
  • services/cloud-agent-next/test/e2e/README.md - 0 issues
  • services/cloud-agent-next/test/e2e/client.ts - 0 issues
  • services/cloud-agent-next/test/e2e/lifecycle.ts - 0 issues
  • services/cloud-agent-next/test/e2e/sandbox-control.ts - 0 issues
  • services/cloud-agent-next/test/e2e/smoke.ts - 0 issues
  • services/cloud-agent-next/test/unit/client-session-tracking.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/lifecycle-preparation.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/sandbox-control.test.ts - 0 issues
  • services/cloud-agent-next/wrangler.jsonc - 0 issues
  • services/cloud-agent-next/src/session/safe-failure-projection.ts - 1 issue (carried forward, unresolved)

Fix these issues in Kilo Cloud

Previous review (commit cbd5b8e)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The classifier and diagnostic-safety guarantees hold up across all reviewed paths (no raw gateway bodies reach logs/reports, migration is a safe drop-only change, SQLite prefix substr replacement is parameterized and equivalent to the old LIKE match); the only finding is a low-risk over-matching regex in the new negative-balance heuristic.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
services/cloud-agent-next/src/session/safe-failure-projection.ts 86 Negative-balance regex may misclassify unrelated "balance" mentions as payment_required
Files Reviewed (27 files)
  • packages/db/src/migrations/0191_curious_trish_tilby.sql - 0 issues
  • packages/db/src/migrations/meta/0191_snapshot.json - 0 issues
  • packages/db/src/migrations/meta/_journal.json - 0 issues
  • packages/db/src/schema.ts - 0 issues
  • packages/worker-utils/src/cloud-agent-queue-report.ts - 0 issues
  • services/cloud-agent-next/src/kilo/wrapper-client.test.ts - 0 issues
  • services/cloud-agent-next/src/kilo/wrapper-client.ts - 0 issues
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts - 0 issues
  • services/cloud-agent-next/src/session/queries/events.ts - 0 issues
  • services/cloud-agent-next/src/session/safe-failure-projection.test.ts - 0 issues
  • services/cloud-agent-next/src/session/safe-failure-projection.ts - 1 issue
  • services/cloud-agent-next/src/shared/wrapper-http.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/queue-reports.test.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/queue-reports.ts - 0 issues
  • services/cloud-agent-next/src/telemetry/report-store.test.ts - 0 issues
  • services/cloud-agent-next/src/websocket/ingest.test.ts - 0 issues
  • services/cloud-agent-next/src/websocket/ingest.ts - 0 issues
  • services/cloud-agent-next/test/e2e/README.md - 0 issues
  • services/cloud-agent-next/test/e2e/auth.ts - 0 issues
  • services/cloud-agent-next/test/e2e/client.ts - 0 issues
  • services/cloud-agent-next/test/e2e/fake-llm-server.ts - 0 issues
  • services/cloud-agent-next/test/e2e/lifecycle.ts - 0 issues
  • services/cloud-agent-next/test/e2e/run.ts - 0 issues
  • services/cloud-agent-next/test/e2e/smoke.ts - 0 issues
  • services/cloud-agent-next/test/integration/session/events.test.ts - 0 issues
  • services/cloud-agent-next/test/unit/fake-llm-server.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/server.test.ts - 0 issues
  • services/cloud-agent-next/wrapper/src/server.ts - 0 issues

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-5 · Input: 74 · Output: 22.3K · Cached: 2.7M

Review guidance: REVIEW.md from base branch main

Comment thread docs/superpowers/specs/2026-07-22-cloud-agent-e2e-health-design.md Outdated
Squashed from five branch commits:

- Preserve classified assistant terminal failures (payment_required,
  model_missing) through to PostgreSQL reporting with a shared
  terminal classifier, bounded wrapper health diagnostics, and a
  literal substr failure lookup replacing the SQLite LIKE prefix match
- Design and implement reliable e2e health checks: warm-reuse
  preparation classification, bounded stable-absence cleanup
  verification, created-session tracking, and raised dev sandbox
  max_instances for the full 15-row matrix
- Destroy isolated sandboxes when deleting their only session
- Require account context for negative-balance credit detection
- Align e2e health design quiescence window with implementation
@eshurakov
eshurakov force-pushed the eshurakov/cloud-agent-improvements branch from 05739c0 to 8d9dd19 Compare July 22, 2026 20:13
killSandboxFamily,
listSandboxContainers,
waitForSandboxFamilyGone,
removeSandboxFamily,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: killSandboxFamily and waitForSandboxFamilyGone are removed from this import but are still called later in the file

The "clean stale sandbox containers from previous runs" block (around lines 136-137, unchanged by this diff) still calls killSandboxFamily(container) and waitForSandboxFamilyGone(container, 30_000), but this import statement no longer imports either symbol (only removeSandboxFamily, sandboxFamilyKey, and waitForSandboxCleanupQuiescence are now imported from ./sandbox-control.js). This will throw a ReferenceError on module load/execution whenever stale containers exist from a prior run — a common occurrence for this harness — crashing smoke.ts before the matrix even starts. Both symbols are still exported from sandbox-control.ts, so re-adding them to this import should fix it.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

while (true) {
const containers = await listSandboxContainers(executeDocker);
const observedAt = now();
if (observedAt > deadline) return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Deadline check runs before the stability check, causing a false-negative on the exact tick quiescence is reached

In waitForSandboxCleanupQuiescence, if (observedAt > deadline) return false; executes at the top of every loop iteration, before the postBaselineSandboxes.length === 0 / observedAt - absentSince >= stableMs check below. If the stability window (stableMs) is satisfied on the same poll tick that also crosses deadline, the function still returns false, declaring cleanup "unstable" even though the required continuous-absence window was actually met. This is a source of rare flaky failures in the smoke harness when cleanup finishes right at the timeout boundary. Consider checking stability before the deadline short-circuit (or checking deadline only after evaluating postBaselineSandboxes).


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

{ failureStage: 'agent_activity', failureCode: 'model_missing' },
{ failureStage: 'agent_activity', failureCode: 'wrapper_error_after_activity' },
{ failureStage: 'agent_activity', failureCode: 'payment_required' },
{ failureStage: 'agent_activity', failureCode: 'model_missing' },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Duplicate classification entries

Lines 38-39 ({ failureStage: 'agent_activity', failureCode: 'payment_required' } / 'model_missing') duplicate lines 35-36 added by the same PR. Since CloudAgentRunFailureClassifications feeds a Set-based validator, the duplicates are functionally harmless, but they look like an unintended copy-paste and should be removed for clarity.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

tsx services/cloud-agent-next/test/e2e/smoke.ts
```

The dev `SandboxSmall` capacity is 16 because this matrix creates fourteen

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Session count doesn't match the matrix

This states the matrix creates "fourteen" isolated sessions, but DEFAULT_MATRIX in smoke.ts has fifteen entries (including the two new classified-failure-report rows added by this PR), each creating one session. The capacity math (16 vs demand) still holds, but the stated count should read "fifteen".

Suggested change
The dev `SandboxSmall` capacity is 16 because this matrix creates fourteen
The dev `SandboxSmall` capacity is 16 because this matrix creates fifteen

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

headers: { 'Content-Type': 'application/json' },
const stdout = result.stdout ?? '';
const markerIndex = stdout.lastIndexOf(responseMetadataMarker);
if (markerIndex === -1) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: Missing response-metadata marker silently falls back to a 200 status

If the curl -w marker is absent from stdout (e.g., truncated output or an unexpected exec transport issue), this returns status: 200 by default, masking what could actually be a failed request. Given this PR's explicit goal of surfacing wrapper failure diagnostics rather than hiding them, treating a missing marker as a diagnostic/parse failure (e.g., 500) would be more consistent with that goal.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant