Skip to content

[Fix] Flatten submit_automation_work_items to one work item per call - #116

Merged
daniel-lxs merged 1 commit into
developfrom
fix/harden-automation-work-items-tool
Jul 10, 2026
Merged

[Fix] Flatten submit_automation_work_items to one work item per call#116
daniel-lxs merged 1 commit into
developfrom
fix/harden-automation-work-items-tool

Conversation

@daniel-lxs

@daniel-lxs daniel-lxs commented Jul 10, 2026

Copy link
Copy Markdown
Member

Problem

Staging ci-failure-triage task 0urhx5qrifwj7 (grok-4.5 on opencode-server) correctly diagnosed the GHCR CI failure, then failed ~15 consecutive submit_automation_work_items calls and looped for over an hour without submitting anything. Slack report: https://roomote-dev.slack.com/archives/C0AJZ8TR6T1/p1783709608450479

The failed calls cycled through:

  • readinessMessage rejected as too_big (>500 chars) — reasoning monologue leaked into the optional field, and one bad optional field rejected the whole submission
  • workItems sent as a JSON string instead of an array, items missing required fields
  • 400 "Act automation work items must include executionPrompt." from the platform API — the tool schema marks executionPrompt optional, so the requirement only surfaced as a generic post-round-trip error

Same failure class as the manage_environments empty-arguments fix (#8): some models can't reliably emit deeply nested tool arguments. The fix that worked there was simplifying the schema, not validating harder.

Change

submit_automation_work_items now takes one flat work item per call — scalar params only, called once per work item. The worker wraps the item into the platform API's existing workItems array; the API contract is unchanged.

  • executionPrompt, targetRepositoryFullName, and targetEnvironmentId are required in the advertised schema, so models see the real contract up front instead of a post-hoc 400
  • workspaceReadiness and readinessMessage are removed: the platform derives readiness from targetEnvironmentId and rejects bare_repo for act items, so an automation could never legitimately set them — readinessMessage (the field that wedged the staging loop) was pure dead weight on this tool
  • disposition stays as an optional enum(['act']) because the scan prompts instruct models to pass it; the handler hardcodes act (and suggest now fails with a crisp enum error)

Testing

  • New automation-work-items-tool-schema.test.ts: valid item accepted, every field is a flat string/enum (regression guard against re-nesting), the act-item requirements are schema-required, disposition compat, uuid validation, and the params→API mapping
  • submit-automation-work-items.test.ts and tool-descriptions.test.ts pass unchanged; tsc --noEmit, prettier, eslint clean

Follow-ups (not in this PR)

  • Scan prompts still describe batch submission wording ("submit up to 3 work items with...") — still correct since the model just calls the tool N times, but the disposition/suggestion-rejection wording could be cleaned up per the prompt-editing policy
  • submit_task_suggestions keeps the old nested array shape and could get the same flattening
  • No retry cap on scans: a model that keeps failing tool calls still loops; worth a separate guard

🤖 Generated with Claude Code

Automation scans (e.g. ci-failure-triage on staging) were getting stuck in
long retry loops because some models cannot reliably emit this tool's
nested arguments: the workItems array was sent as a JSON string, fields
were dropped, reasoning text leaked into optional fields, and the act-item
requirements only surfaced as an opaque platform-API 400 after the round
trip. Same failure class as the manage_environments fix (#8): the cure is
a simpler schema, not stricter validation.

- The tool now takes one flat work item per call (scalar params only) and
  is called once per work item; the worker wraps it into the platform
  API's existing workItems array
- executionPrompt, targetRepositoryFullName, and targetEnvironmentId are
  required in the advertised schema, so models see the real contract
  instead of a post-hoc 400
- disposition is retained as an optional enum(['act']) for prompt
  compatibility and hardcoded to act in the handler; workspaceReadiness
  and readinessMessage are removed entirely -- the platform derives
  readiness from targetEnvironmentId and rejects bare_repo for act items,
  so those fields could never be legitimately set (readinessMessage was
  the field that wedged the staging loop)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@daniel-lxs
daniel-lxs force-pushed the fix/harden-automation-work-items-tool branch from 7c87e9e to 0b4699a Compare July 10, 2026 19:18
@daniel-lxs daniel-lxs changed the title [Fix] Harden submit_automation_work_items against mangled model arguments [Fix] Flatten submit_automation_work_items to one work item per call Jul 10, 2026
@daniel-lxs
daniel-lxs merged commit 6c61dd8 into develop Jul 10, 2026
1 check passed
@mrubens
mrubens deleted the fix/harden-automation-work-items-tool branch July 12, 2026 04:19
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