Skip to content

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.
  • #1048fullsend run and trigger resources are not linked; revives fragile post-run-link ideas.
  • #863 / #529post-run-link was dropped during workflow_call shim 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 .fullsend run.

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.ymlreusable-{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).

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.ymlreusable-*.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 .fullsend runs; 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 in dispatch.yml (ADR 0034) remains.
  • Adding or removing org-specific agent workflows requires editing dispatch.yml directly; 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.