Files
Skills/implement
Brummel 22aafe892a fix(workflows): fail fast on a malformed args carrier instead of misreporting it
Both workflow scripts destructured object-form `args` behind `args || {}`
only. A named-workflow invocation can deliver `args` as a string; a
non-empty string is truthy, so every carrier field silently read
`undefined` and the failure surfaced far from the cause: implement-loop
dispatched its plan-index agent against "Read the plan at undefined" and
stopped only via a mislabelled NEEDS_CONTEXT after burning agent calls;
compiler-driven-edit briefed its edit agent with "EDIT: undefined" and
mapped the agent's refusal onto the straddle-rule BOUNCE to specify —
a mechanics failure dressed as a design finding.

Guards now run before any agent dispatch, mirroring the existing
malformed-input pattern (the task_range guard):

- A string carrier is first JSON-parsed: a JSON-serialized object
  carrier (a stringifying caller or substrate layer that still authored
  the documented object form) is accepted; free text does not parse to
  an object and is rejected.
- A carrier that is not an object (string, number, boolean, array) is a
  distinct infra BLOCKED naming the received type (compiler-driven-edit:
  kind bad-carrier) — never a bounce, never NEEDS_CONTEXT.
- Missing or blank required fields fail fast by name, per mode:
  standard iter_id+plan_path, mini iter_id+red_test_path+cause_summary,
  compiler-driven-edit edit_description+def_site. implement-loop also
  rejects an unknown mode, since the required-field set keys off it.

String-form args are NOT a documented interface — the only invocation
examples in the plugin are object-form (implement/SKILL.md); the issue's
free-text-passthrough fix part was dropped on that ground (triage
verification on the issue). implement/SKILL.md now also documents the
infra early-exit end-report shape (minimal {status, iter_id, reason},
no BLOCKED.md, no blocked_detail) in the Iron Law exceptions, Step 2,
and Step 4's no-file special case.

Verified: both scripts pass node --check (async-wrapped, as the Workflow
substrate runs them) and a 17-case stub-agent harness — malformed
carriers block with zero agent dispatches; valid and JSON-serialized
object carriers reach the first agent unchanged.

closes #24
2026-07-09 11:14:03 +02:00
..