feat(pipeline): dispatcher refactor — ast-grep funnel + citation validator + coverage lint#27
Merged
Merged
Conversation
…dator + coverage lint
Phase 4-8 of the original task — the dispatcher unlock. The 124-rule
index now has a real pipeline consuming it.
ARCHITECTURE
Before: commands/pr-review.md loaded specific docs (Step 2.5 hardcoded
table) and dispatched a fixed 4-agent list (Step 4). Each agent
re-implemented its own pattern detection on top of reading its
specific doc — no use of rules/index.json or rules/<lang>/*.yml.
After: dispatcher invokes a thin mechanical-funnel agent
(ast-grep-runner), receives findings grouped by Owner, then dispatches
per-Owner judgment-tier adjudication concurrently. Citation validator
drops findings citing missing rule IDs. Coverage lint catches drift
between docs, index, and YAMLs at precommit time.
WHAT'S IN THIS PR
1. agents/ast-grep-runner.md (new) — single-responsibility mechanical
funnel. Reads rules/index.json, runs ast-grep per YAML, parses
JSON output, groups findings by Owner. Never invokes LLM tools;
never modifies files. Defined output contract so the dispatcher
can pipe it directly to per-language agents.
2. commands/pr-review.md (rewritten Step 2.5 + Step 4) — now:
- Step 4a: invoke ast-grep-runner → findings grouped by Owner
- Step 4b: per-Owner concurrent dispatch with adjudication prompt
containing the pre-filtered findings + judgment-tier rule IDs
the agent owns
- Step 4c: context-specific convention reads (kept teamvault /
k8s-binary / k8s-manifest / changelog mappings as before — these
are file-pattern triggers, not rule-id-driven)
- Step 4d: citation validation via scripts/validate-citations.sh
Per-Owner dispatch fans out concurrently — N agents see N
independent finding sets, no serialization.
3. scripts/validate-citations.sh (new) — filters review-output
findings against rules/index.json's rule_id set. Drops findings
with missing IDs, logs offenders to stderr, exits non-zero if any
drops occurred (so the dispatcher captures the drift signal but
still consolidates the validated subset).
4. scripts/check-coverage.sh (new) — coverage lint. Three checks:
a) every rule's enforcement-cited rules/<lang>/<file>.yml path
resolves to an existing file
b) every rules/<lang>/*.yml is referenced by exactly one index
entry (catches orphan YAMLs after rule renames)
c) every YAML's id: field matches an index entry's id (catches
rename drift between doc and YAML)
Same shape as PR #13's check-index.
5. Makefile — precommit chain extended:
precommit: check-links check-json check-index check-coverage
New check-coverage target wraps the script.
6. Three per-language agents (go-error, go-time, go-context)
simplified to expect pre-filtered findings + judgment-tier rule
ownership. The rest of the agents continue working in the
legacy 'scan + judge' mode for now and migrate in follow-up PRs
— the dispatcher tolerates both shapes during the transition
(agents that re-scan emit findings; the runner's pre-filtered
set just doesn't overlap with theirs).
OPERATIONAL NOTES
- The dispatcher refactor is the original Phase 4-8 unlock from
[[Refactor coding pr-review to doc-driven rules pipeline]]. With
124 rules in the index and 15 mechanical YAMLs across rules/go/,
the pipeline has real material to operate on from day one.
- Smoke testing the dispatcher end-to-end against an old PR is the
next step before this lands on master; smoke fixtures live as
judgment in /coding:pr-review invocations.
- Per-language agents not yet migrated (the other ~25) continue
to work in legacy mode — adding their dispatcher-shaped prompt
is a 30-min change per agent, parallelizable.
make precommit clean (links + JSON + check-index + new check-coverage).
bborbe
added a commit
that referenced
this pull request
Jun 2, 2026
…re agents Completes the dispatcher refactor follow-ups. commands/code-review.md — Step 4 now mirrors commands/pr-review.md's dispatcher shape (PR #27): 4a ast-grep-runner mechanical funnel; 4b per-Owner concurrent adjudication; 4c context-specific convention reads; 4d citation validation via scripts/validate-citations.sh. Conditional/full-mode agents that don't yet have RULE blocks (license, readme-quality, shellcheck, context7, go-version-manager, go-tooling) continue on the legacy direct-invoke path until their conventions land as canonical rules. 10 per-language agents migrated to the dispatcher contract — added 'When invoked by the dispatcher' section + Source of truth pointer to rules/index.json + citation discipline note: - go-quality-assistant - go-architecture-assistant - go-factory-pattern-assistant - go-http-handler-assistant - go-metrics-assistant - go-security-specialist (preserves toolchain fallback for findings outside the rule-base scope) - go-test-quality-assistant - godoc-assistant - python-architecture-assistant - python-quality-assistant Total agents on dispatcher contract: 13 (3 from PR #27 + 10 here). Remaining 18 agents are utility / auditor / file-existence-check agents that don't enforce rules/index.json owners — they don't need dispatcher contract migration. Legacy mode preserved on every migrated agent — agents tolerate both shapes during the rollout (dispatcher invocation + direct slash-command-style invocation). make precommit clean (links + JSON + check-index + check-coverage).
This was referenced Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 4-8 of the original task (the dispatcher unlock). With 124 rules in the index and 15 mechanical YAMLs,
/coding:pr-reviewnow consumes the rule base via a 3-layer pipeline:What's in this PR
agents/ast-grep-runner.md(new) — single-responsibility mechanical funnel; readsrules/index.json, runs ast-grep per YAML, parses JSON output, groups findings by Owner. Read-only, no LLM tools, defined output contract.commands/pr-review.md(rewritten Step 2.5 + Step 4) — dispatcher invokes the runner, fans out per-Owner adjudication concurrently, validates citations, then consolidates. Keeps the context-specific convention reads (teamvault / k8s-binary / k8s-manifest / changelog) intact.scripts/validate-citations.sh(new) — filters review findings against the index's rule_id set; logs drift to stderr.scripts/check-coverage.sh(new) — coverage lint catching three drift modes: enforcement-cited YAML missing, orphan YAML not in index, YAML id mismatch with index.Makefile—precommitchain extended:check-links check-json check-index check-coverage.Why one PR vs five
Each phase is small individually (<100 LOC) but they reference each other: the dispatcher cites the runner's output contract, the citation validator references the dispatcher's flow, the coverage lint shares the schema discipline. Splitting into 5 PRs would multiply the review-cycle cost without buying review clarity (each PR depends on the prior to make sense).
Test plan
Follow-ups noted in task page