41. Synchronous workflow_call for event-driven agent dispatch
Date: 2026-05-20
Status
Accepted (static stage routing partially superseded by ADR 0061; synchronous workflow_call property preserved via dynamic matrix jobs)
Context
The per-org event path still fans out from dispatch.yml to stage workflows (code.yml, review.yml, …) via gh workflow run and on: workflow_dispatch (ADR 0026, ADR 0031). That hop is asynchronous: the dispatch job exits when GitHub accepts the API call, not when the agent finishes. GitHub Actions does not link the dispatched run to the caller in the UI — operators see unrelated top-level runs in .fullsend with no parent workflow, which makes it hard to answer “is the agent still running?” from a PR or issue and hard to debug failures.
While the workflow_dispatch API can return run details (run ID/URLs), it does not provide a native caller→callee run relationship in the Actions UI, and closing the loop still requires extra plumbing (posting links, polling, etc.).
Operational pain is documented across multiple issues:
- #504 — enrolled-repo shim can show green before review finishes or posts PR feedback.
- #896 — agent runs lack structured source/destination metadata; correlation requires log parsing.
- #1048 —
fullsend runand trigger resources are not linked; revives fragilepost-run-linkideas. - #863 / #529 —
post-run-linkwas dropped duringworkflow_callshim migration; run links no longer posted on triggers. - #272 — no lifecycle indicators (emoji reactions) on trigger comments/issues/PRs.
- #957 / #988 — “working on this” comments without reliable failure follow-up when dispatch and agent runs are decoupled.
- #837 — failed review runs should update PR status comments.
- #763 — post-run feedback should come from the agent App, not GitHub Actions bot identity.
- #872 / #934 — silent failures when users cannot find the right
.fullsendrun.
Band-aids (extra comments, annotations, emoji, separate post-run-link jobs) fight the async model. Per-repo mode already uses a synchronous workflow_call chain (reusable-dispatch.yml → reusable-{stage}.yml; ADR 0033, PR #799). Per-org should converge on the same property for the event-driven path.
Cross-repo shim → .fullsend is already workflow_call (ADR 0029, ADR 0034). This ADR targets only in-config-repo dispatch from dispatch.yml to agent stages.
This decision assumes the token mint model from ADR 0029: stage workflows obtain credentials via OIDC exchange rather than relying on config-repo secrets being visible to the enrolled-repo caller context.
ADR 0026 Option C introduced runtime # fullsend-stage: scanning so org-specific agent workflows could be wired without editing dispatch.yml. Static workflow_call jobs in dispatch.yml are incompatible with that model. This ADR drops dynamic agent discovery rather than replacing it with compile-time tooling. After agent architecture is revised to support ADR 0038, we may revisit this decision and re-evaluate whether a discovery mechanism is needed.
Options
Option A: Keep workflow_dispatch + marker scan (status quo)
Preserves dynamic # fullsend-stage: discovery and nesting reset (ADR 0031). Does not fix UI correlation or “dispatch succeeded ≠ agent done” (#504).
Option B: Static workflow_call jobs in dispatch.yml (recommended)
Replace the scan/gh workflow run loop with conditional workflow_call jobs in dispatch.yml, aligned with reusable-dispatch.yml (ADR 0033). Each stage workflow is wired explicitly; adding or removing an agent workflow requires editing dispatch.yml.
Option C: Mitigations only (annotations, comments, reactions)
Implement #896, #1048, #272 without changing dispatch mechanism. Reduces pain but leaves orphan runs and early-success dispatch jobs.
Decision
For event-driven agent dispatch (webhook → shim → routing → agent), eliminate workflow_dispatch and gh workflow run between dispatch.yml and stage execution. Use Option B: static workflow_call jobs in dispatch.yml.
Drop the dynamic agent discovery introduced in ADR 0026 Option C — remove the runtime # fullsend-stage: scanner and the marker convention. Do not add compile-time sync tooling as a substitute.
workflow_dispatch remains allowed for non-event entry points only (e.g. repo-maintenance.yml, manual prioritize, admin/CLI triggers).
Prefer dispatch.yml → reusable-*.yml@* where possible to reduce workflow_call nesting depth (GitHub currently allows up to ten levels).
After agent architecture is revised to support ADR 0038, re-evaluate whether a discovery mechanism is needed.
Consequences
- PR/issue observers can use one Actions run to see agent completion without hunting orphan
.fullsendruns; mitigates #504, #896, #1048, and the silent-failure cluster (#957, #988); notification UX may still need follow-up issues. - Supersedes ADR 0026 Option C for the event path, including dynamic
# fullsend-stage:discovery; centralized routing indispatch.yml(ADR 0034) remains. - Adding or removing org-specific agent workflows requires editing
dispatch.ymldirectly; the single-file marker pattern from ADR 0026 is gone. - Per-org and per-repo dispatch shapes converge; enrolled-repo shims may need
needs:/ concurrency review (#504). - Discovery may be revisited after ADR 0038 agent architecture changes land.
Implementation note (#981)
Per-repo concurrency follow-up (#504) is addressed in workflow configuration; the dispatch shape in this ADR is unchanged.
