Skip to content

fix(agent): normalize neutral Task action placeholders - #1852

Merged
bobleer merged 1 commit into
GCWing:mainfrom
bobleer:bob/fix-task-neutral-placeholders
Jul 29, 2026
Merged

fix(agent): normalize neutral Task action placeholders#1852
bobleer merged 1 commit into
GCWing:mainfrom
bobleer:bob/fix-task-neutral-placeholders

Conversation

@bobleer

@bobleer bobleer commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Normalize semantically empty optional fields at the regular Task input boundary.
  • Treat null, blank strings, and default false values as omitted when they carry no action intent.
  • Keep rejecting real action conflicts such as a non-empty agent_id on spawn or a non-empty subagent_type with fork_context=true.
  • Add regression coverage for fresh spawn, forked spawn, send-input, and cancel payloads produced from the flat action schema.

Root Cause

This is not caused by managed worktree execution.

The failing call was rejected by Task argument validation before workspace resolution or subagent creation. Its model-generated payload included neutral placeholders for fields that do not apply to the selected action:

{
  "action": "spawn",
  "agent_id": "",
  "fork_context": true,
  "subagent_type": ""
}

The regular Task tool intentionally uses one flat schema for spawn, send_input, and cancel. Some models serialize unused optional properties instead of omitting them. The validator previously treated raw key presence as intent, so an empty agent_id was incorrectly rejected as a spawn conflict.

Historical managed-worktree sessions successfully spawned subagents with clean payloads, and the existing worktree inheritance test confirms that a fresh subagent receives the parent managed-worktree binding correctly.

Design

The public tool schema and action model remain unchanged. Parsing now uses semantic optional values:

  • blank optional strings and null are absent;
  • default false toggles are absent when an action forbids that toggle;
  • non-empty strings, true, and other concrete values remain present and are validated normally.

This keeps strict action invariants while making the boundary robust across model providers.

Verification

  • pnpm run fmt:rs
  • cargo test -p bitfun-core validate_input_ -- --nocapture (25 passed)
  • cargo test -p bitfun-core neutral_ -- --nocapture (4 passed)
  • cargo test -p bitfun-core fresh_subagent_inherits_matching_parent_worktree_binding -- --nocapture (1 passed)
  • cargo check --workspace
  • node scripts/check-core-boundaries.mjs
  • git diff --check

@bobleer
bobleer merged commit 6e3d0ef into GCWing:main Jul 29, 2026
7 checks passed
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