Skip to content

ci(sdlc): add agent dispatch harness, disabled by default - #4163

Open
dearsimanovich-epam wants to merge 3 commits into
developmentfrom
feat/port-agent-tooling
Open

dearsimanovich-epam wants to merge 3 commits into
developmentfrom
feat/port-agent-tooling

Conversation

@dearsimanovich-epam

@dearsimanovich-epam dearsimanovich-epam commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description:

Infrastructure for running local skills as PR gates, ported from ai-dial-chat. Nothing runs when
this merges
— the one real agent manifest ships disabled, so this PR is independent of the skills it
would eventually invoke.

This PR was originally the combined port of all agent tooling. It has been narrowed to the CI harness
only; the rest is split into #4164 (opsx upgrade), #4165 (validator / MCP / a11y), and #4166 (skills).

Issues:

  • No tracking issue — infra work. Happy to file one and retitle.

Design

An agent is a manifest plus a skill reference — there is no per-agent prompt. agents/<name>/agent.yml
names a local skill and a tool allowlist; match-agents.py discovers the manifests matching the caller's
event and validates each against a JSON schema; one matrix runs them all with per-agent needs: waits,
so a dependent starts when its upstream finishes rather than when a whole round does.

This means the reviewer logic lives in the same skill you invoke locally — CI and local review can't
drift apart.

Piece Purpose
dispatch-pr.yml trigger-specific entrypoint (PRs to development)
dispatch-core.yml reusable pipeline: trust gate → discover → run matrix
run-agent.yml per-agent runner: manifest parse, env/secret injection, artifact chaining
actions/pr-trust-gate classifies PR source; rejects trust-path edits and added symlinks
actions/run-claude-stage runs one agent, normalizes its output envelope
claude/scripts/*.py agent matching, findings aggregation, SARIF, inline comments, output scrubbing
claude/schemas/*.json manifest + stage-message contracts

Disabled on arrival

The only real manifest ships as agents/_code-review/. The underscore prefix is the harness's own
mechanism for a manifest the dispatcher skips — match-agents.py globs agents/*/agent.yml and ignores
underscore-prefixed directories. Verified locally: with this tree, the dispatcher matches zero agents.

Activation is a deliberate one-line rename, with prerequisites documented in the file itself:

git mv agents/_code-review agents/code-review

…once the code-review-and-quality skill exists (#4166), the DIAL secret/vars are set, and this is on
the default branch.

Adaptations from the source repo

  • Trigger branches retargeted development-1.0development.
  • SARIF informationUri pointed at this repository.
  • dispatch-schedule.yml deliberately not ported — it would run a daily cron matching zero agents,
    since the Snyk/Jira agent family it exists for is not ported. Worth adding when a scheduled agent does.
  • The Snyk/dependency/security-monitor agent family is omitted: one is hardcoded to a specific EPAM Jira
    filter with its own secret, one is a fixture whose planted findings reference apps/chat-api paths,
    and one embeds a hardcoded NestJS/React/Express stack filter.

Verification

All local, since nothing can dispatch until this is on the default branch:

  • every workflow and composite action parses as YAML; all internal uses: ./… refs resolve
  • all seven Python scripts compile
  • match-agents.py schema-validates the manifest, skips _template, honours the
    STAGE_CODE_REVIEW_ENABLED kill switch, and matches zero agents in the shipped (disabled) state

The harness also already proved itself on this PR's earlier revision: the trust gate ran and
correctly rejected it —

M2 reject: 37 trust-path edit(s), 9 symlink(s). A PR that touches agent-trust files (or adds symlinks) cannot run the AI agents — it is a config-poisoning / prompt-injection vector.

Ops setup required before anything dispatches

  1. Secret DIAL_API_KEY; vars DIAL_CORE_URL, DIAL_ROUTE_PATH, optionally DIAL_MODEL.
  2. A security-review GitHub environment (for claude-security-review.yml, which is label-gated).
  3. Presence on the default branch — GitHub registers schedule / workflow_dispatch only from there.

Known consequence worth a decision

pr-trust-gate rejects any PR that touches .claude/**, .github/workflows/**, agents/**, or adds
a symlink
. Since adding a rule in this repo requires adding a mirror symlink, every future agent-config
PR will get no agent review. That's the correct posture for a prompt-injection vector, but it's worth
choosing deliberately: dispatch-core.yml carries commented-out trust_label support to opt back in
with a maintainer-applied label.

Breaking Changes: none — no workflow does anything until an agent is enabled and secrets exist.

Checklist:

  • the pull request name complies with Conventional Commits
  • the pull request name ends with (Issue #<TICKET_ID>) — no tracking issue for this work

Comment thread .github/workflows/run-agent.yml Dismissed
Infrastructure for running local skills as PR gates, ported from ai-dial-chat.
The design is a manifest plus a skill reference: `agents/<name>/agent.yml` names a
local skill and a tool allowlist, match-agents.py discovers the manifests matching
the caller's event, and one matrix runs them with per-agent `needs:` waits rather
than round barriers. No per-agent prompt.

**Nothing runs on merge.** The only real manifest ships as `agents/_code-review/`,
and the underscore prefix is how the dispatcher skips it — verified locally, the
dispatcher matches zero agents. That keeps this PR independent of the skills it
would invoke, and makes activation a deliberate one-line rename with the
prerequisites listed in the file.

Adaptations from the source repo: trigger branches retargeted to `development`,
SARIF `informationUri` pointed at this repo, and `dispatch-schedule.yml`
deliberately omitted — it would run a daily cron matching zero agents, since the
Snyk/Jira agent family it existed for is not ported.

Verified locally: every workflow and action parses, all internal `uses: ./` refs
resolve, all seven Python scripts compile, match-agents.py schema-validates the
manifest and honours the STAGE_CODE_REVIEW_ENABLED kill switch.

Ops setup is required before anything can dispatch: the DIAL_API_KEY secret,
DIAL_CORE_URL / DIAL_ROUTE_PATH vars, a security-review environment, and presence
on the default branch — GitHub registers schedule and workflow_dispatch triggers
only from there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dearsimanovich-epam dearsimanovich-epam changed the title chore(infra): port agent tooling from ai-dial-chat ci(sdlc): add agent dispatch harness, disabled by default Aug 12, 2026
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.

3 participants