Problem
The /review_prs command (.abca/commands/review_prs.md) documents Stage 2 with an illustrative Workflow sketch (lines ~142–164) that the operator regenerates per invocation. That sketch iterates the PR descriptors with args.map(...) directly.
In practice the Workflow harness may deliver args to the script as a JSON-encoded string rather than a parsed array — even when the caller passes a genuine JSON array in the Workflow tool call. When that happens the script throws immediately:
Error: args.map is not a function ('args.map' is undefined)
before any review agent spawns. Because the skill is (correctly) a sketch that gets regenerated each run, every regeneration risks re-hitting this footgun. Observed live during the carve S1–S8 stacked-PR review train (2026-07-28): the first Workflow launch died in ~7ms with agent_count: 0; a one-line defensive unpack fixed it and the resumed run proceeded normally.
Why not freeze the whole script into the skill
The sketch is intentionally adaptable — N==1 skips the Workflow, arg modes differ (explicit list vs. review-requested:@me vs. NL filter), and diff baselining differs for a stack (each PR vs its parent branch) vs. a flat batch (each vs main). Freezing a full script would bake away that variance and pull orchestration mechanics back into a skill that deliberately stays a thin orchestrator. So the fix is a doc hardening, not a canned script.
Proposed fix (small, docs-only)
In the Stage-2 sketch, unpack defensively before iterating and add a half-sentence caveat:
// Workflow may deliver `args` as a JSON string; tolerate either form.
const prs = typeof args === 'string' ? JSON.parse(args) : args
const results = await parallel(prs.map((pr) => () => agent(...)))
Add one line to the Notes / Stage-2 prose noting that Workflow args can arrive JSON-encoded, so generated scripts should normalize before .map.
Scope
- Docs only:
.abca/commands/review_prs.md.
- No code, no CDK, no agent-runtime change.
- Self-sufficiency bar for the skill is preserved: a competent agent regenerating the script from the prose will no longer trip on the string/array ambiguity.
Acceptance criteria
Problem
The
/review_prscommand (.abca/commands/review_prs.md) documents Stage 2 with an illustrativeWorkflowsketch (lines ~142–164) that the operator regenerates per invocation. That sketch iterates the PR descriptors withargs.map(...)directly.In practice the
Workflowharness may deliverargsto the script as a JSON-encoded string rather than a parsed array — even when the caller passes a genuine JSON array in theWorkflowtool call. When that happens the script throws immediately:before any review agent spawns. Because the skill is (correctly) a sketch that gets regenerated each run, every regeneration risks re-hitting this footgun. Observed live during the carve S1–S8 stacked-PR review train (2026-07-28): the first Workflow launch died in ~7ms with
agent_count: 0; a one-line defensive unpack fixed it and the resumed run proceeded normally.Why not freeze the whole script into the skill
The sketch is intentionally adaptable — N==1 skips the Workflow, arg modes differ (explicit list vs.
review-requested:@mevs. NL filter), and diff baselining differs for a stack (each PR vs its parent branch) vs. a flat batch (each vsmain). Freezing a full script would bake away that variance and pull orchestration mechanics back into a skill that deliberately stays a thin orchestrator. So the fix is a doc hardening, not a canned script.Proposed fix (small, docs-only)
In the Stage-2 sketch, unpack defensively before iterating and add a half-sentence caveat:
Add one line to the Notes / Stage-2 prose noting that
Workflowargs can arrive JSON-encoded, so generated scripts should normalize before.map.Scope
.abca/commands/review_prs.md.Acceptance criteria
args(string-or-array) before.map.