Skip to content

refactor(dispatcher): extract SKILL.md bash to dispatcher-tick.sh + lib-dispatch.sh - #71

Merged
zxkane merged 1 commit into
mainfrom
feat/dispatcher-skill-slim
May 9, 2026
Merged

refactor(dispatcher): extract SKILL.md bash to dispatcher-tick.sh + lib-dispatch.sh#71
zxkane merged 1 commit into
mainfrom
feat/dispatcher-skill-slim

Conversation

@zxkane

@zxkane zxkane commented May 9, 2026

Copy link
Copy Markdown
Owner

Summary

PR-3 of the pipeline-docs plan. Pure refactor — behavior preserved byte-for-byte.

skills/autonomous-dispatcher/SKILL.md slimmed from 438 lines (224 of which were inline bash) to 114 lines of prose. The dispatcher agent now invokes a single command per cron tick:

bash "$PROJECT_DIR/scripts/dispatcher-tick.sh"

That script orchestrates Steps 1–5 in one process. All gh/jq logic lives in the new lib-dispatch.sh as composable helpers.

What changed

New files:

  • skills/autonomous-dispatcher/scripts/lib-dispatch.sh — 13 helper functions (count_active, list_new_issues, check_deps_resolved, count_retries, mark_stalled, extract_dev_session_id, pid_alive, fetch_pr_for_issue, ci_is_green, pr_idle_seconds, last_reviewed_head, label_swap, was_just_dispatched).
  • skills/autonomous-dispatcher/scripts/dispatcher-tick.sh — single entry point. Sources lib, runs all 5 steps in one process with JUST_DISPATCHED as a normal in-process bash array.
  • tests/unit/test-lib-dispatch.sh — 19 new unit tests for the helpers.
  • docs/designs/dispatcher-skill-slim.md — design canvas.

Modified:

  • skills/autonomous-dispatcher/SKILL.md — 438 → 114 lines, prose + delegation only.
  • docs/pipeline/dispatcher-flow.md — cite new helper names per step.
  • .github/workflows/ci.yml — extend ShellCheck to new scripts.
  • tests/unit/test-{pid-guard,retry-counter-reset,skip-redundant-review,stale-alive-with-pr}.sh — point at new scripts instead of SKILL.md, regression-guard intent preserved.

Behavior preservation (verified byte-for-byte)

Code reviewer ran a side-by-side comparison against main and confirmed:

  • [INV-04] Reviewed-HEAD trailer regex — identical
  • [INV-05] retry-counter cutoff query — identical
  • [INV-06] crash-keyword regex — identical (Task appears to have crashed \\(no PR found\\)\|process not found)
  • [INV-09] JUST_DISPATCHED skip rule — preserved
  • [INV-10] strict > 300s idle gate — logically equivalent (> 300 then SIGTERM ⇔ <= 300 then continue)
  • All comment phrasings byte-identical (the [INV-06] keyword contract depends on this).
  • mktemp CWE-377 mitigation, fail-closed semantics, cross-platform date, PID re-verify before SIGTERM — all preserved.

Surfaced bug: issue #70

PR-3 unit testing surfaced a real latent bug in the original SKILL.md: extract_dev_session_id uses (?P<id>...) (Python-style regex) which jq 1.6+ Oniguruma rejects. Resume mode was probably never extracting session IDs in production. Filed as #70. PR-3 preserves the bug byte-for-byte (test asserts the broken behavior so a future fix triggers test failure as intended). Fix bundled into PR-4.

Pipeline Docs (CONTRIBUTING.md Rule 1)

  • Touches `skills/autonomous-dispatcher/scripts/*.sh` and `skills/autonomous-dispatcher/SKILL.md` (watched paths). Also touches `docs/pipeline/dispatcher-flow.md` (cite new helper names) → gate passes.

Test Plan

  • All 12 unit tests pass locally (existing 11 + new test-lib-dispatch.sh with 19 sub-tests = 90/90 individual asserts).
  • `shellcheck -S error` clean on all dispatcher scripts including the two new ones.
  • Code review pass (covered: behavior preservation byte-for-byte, bug(dispatcher): Dev Session ID regex uses Python-style named group, fails on jq 1.6+ #70 disclosure, test regression-guard intent, set-e interaction, slimmed SKILL.md completeness).
  • Will visually re-verify slimmed SKILL.md renders correctly on github.com after merge (no mermaid in this PR but cross-links should resolve).

Out of scope (deferred)

Issue PR
#58 readlink-vendor (lib-agent.sh) PR-4
#61 MERGED dependency check PR-4
#70 Dev Session ID regex PR-4
#59 resume-on-completed-session PR-5
#60 wall-clock timeout PR-5
#67 INV-15 SIGTERM race separate PR
#62 multi-repo dispatch PR-6

…ib-dispatch.sh

PR-3 of the pipeline-docs plan. Pure refactor — behavior preserved.

skills/autonomous-dispatcher/SKILL.md slimmed from 438 lines (224 of which
were inline bash code blocks the agent re-typed each tick) to 114 lines of
prose. The dispatcher agent now invokes a single command per tick:

    bash "$PROJECT_DIR/scripts/dispatcher-tick.sh"

That script orchestrates Steps 1-5 in one process, with JUST_DISPATCHED
as a normal in-process bash array. All gh/jq logic lives in the new
lib-dispatch.sh as composable helpers (count_active, list_new_issues,
check_deps_resolved, count_retries, mark_stalled, extract_dev_session_id,
pid_alive, fetch_pr_for_issue, ci_is_green, pr_idle_seconds,
last_reviewed_head, label_swap, was_just_dispatched).

New files:
  - skills/autonomous-dispatcher/scripts/lib-dispatch.sh        (helpers)
  - skills/autonomous-dispatcher/scripts/dispatcher-tick.sh     (entry)
  - tests/unit/test-lib-dispatch.sh                             (19 tests)
  - docs/designs/dispatcher-skill-slim.md                       (canvas)

Modified:
  - skills/autonomous-dispatcher/SKILL.md  (438 -> 114, prose only)
  - docs/pipeline/dispatcher-flow.md  (cite new helper names per step)
  - .github/workflows/ci.yml  (extend ShellCheck to new scripts)
  - tests/unit/test-{pid-guard,retry-counter-reset,skip-redundant-review,
    stale-alive-with-pr}.sh  (point at dispatcher-tick.sh + lib-dispatch.sh
    instead of SKILL.md; preserve regression-guard intent)

Behavior preservation:
  - Same labels at same transitions, same comment phrasings (the [INV-06]
    keyword contract depends on this, byte-for-byte).
  - Same retry-counter cutoff rule [INV-05], same JUST_DISPATCHED skip
    [INV-09], same strict > 300s idle gate [INV-10], same fail-closed
    semantics on jq/date errors, same mktemp CWE-377 mitigation.
  - All 12 unit tests pass (existing 11 + new test-lib-dispatch.sh).
  - shellcheck -S error clean on all dispatcher scripts.

PR-3 unit testing surfaced a real latent bug in the original SKILL.md:
extract_dev_session_id used Python-style (?P<id>...) regex syntax which
jq 1.6+ rejects with "Regex failure: undefined group option". Filed as
issue #70. PR-3 PRESERVES this bug byte-for-byte (one-char fix would
mix refactor with behavior change); test asserts the broken behavior
explicitly. Fix bundled into PR-4.

Out of scope:
  - #58 readlink-vendor (lib-agent.sh, separate file) - PR-4
  - #59 resume-on-completed-session (new gate) - PR-5
  - #60 wall-clock timeout (lib-agent.sh) - PR-5
  - #61 MERGED dependency check (mixes refactor + fix) - PR-4
  - #62 multi-repo dispatch (major) - PR-6
  - #67 INV-15 SIGTERM race (wrapper-side) - separate PR
  - #70 Dev Session ID regex (mixes refactor + fix) - PR-4

@amazon-q-developer amazon-q-developer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review Summary

This refactoring successfully extracts dispatcher logic from SKILL.md into dedicated scripts, improving testability and maintainability. However, 7 critical defects block merge:

Critical Issues (Must Fix):

  1. Portability Bug: grep -oP (Perl regex) fails on macOS/BSD, breaking dependency detection
  2. Word Splitting Bug: Unquoted $deps iteration causes incorrect parsing of multiple dependencies
  3. Security Risk (CWE-377): Predictable /tmp PID file paths create race condition vulnerability
  4. Missing Error Handling: All 4 GitHub API query functions (list_new_issues, list_pending_review, list_pending_dev, list_stale_candidates) lack error handling, causing script crashes on API failures instead of graceful degradation

Positive Aspects:

  • Comprehensive unit test coverage with 90 assertions
  • Proper preservation of behavior contracts (INV-04 through INV-10)
  • Excellent documentation of known issue #70
  • Clean separation of concerns with helper functions

Action Required: Address the 7 critical defects above before merge. The portability and error handling issues will cause production failures on non-GNU systems and during GitHub API outages.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread skills/autonomous-dispatcher/scripts/lib-dispatch.sh
Comment thread skills/autonomous-dispatcher/scripts/dispatcher-tick.sh
Comment thread skills/autonomous-dispatcher/scripts/dispatcher-tick.sh
Comment thread skills/autonomous-dispatcher/scripts/lib-dispatch.sh
Comment thread skills/autonomous-dispatcher/scripts/lib-dispatch.sh
Comment thread skills/autonomous-dispatcher/scripts/dispatcher-tick.sh
Comment thread skills/autonomous-dispatcher/scripts/dispatcher-tick.sh
@zxkane
zxkane merged commit 810ba46 into main May 9, 2026
4 checks passed
@zxkane
zxkane deleted the feat/dispatcher-skill-slim branch May 9, 2026 09:07
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