docs: rework design after prior-art review

Red Hat's MIT ai-code-review already implements phases 1-2 (four forge clients,
six providers, CI integration, repo context file). Adds a research writeup,
inserts Phase 0 (evaluate it before building), and folds in seven requirements
the original design missed — chiefly prior-comment synthesis, without which our
own 1.7-runs-per-PR assumption means every push re-posts dismissed findings.

Amends implementation tasks 4, 5, 6, 9, 10 and gates the subagent briefs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Ye1KNFMkkUtmzTypHXkoK
This commit is contained in:
Marcos
2026-08-04 17:27:15 +00:00
parent 8d690f5717
commit 8a4239a9d9
6 changed files with 501 additions and 1 deletions
@@ -12,6 +12,73 @@
---
## ⚠️ Read this before dispatching Task 1
A prior-art review on 2026-08-04 found Red Hat's MIT-licensed `ai-code-review`
(https://gitlab.com/redhat/edge/ci-cd/ai-code-review) already implements Phases 12 of
this design: four forge clients, six AI providers, CI integration, a committed
repo-context file. **Phase 0 of the design is now "evaluate that tool for a week."**
See `docs/research/2026-08-04-prior-art-ai-code-review.md`.
Do not start Task 1 until Phase 0 concludes we are building standalone. If it concludes we
extend an existing base instead, most of the tasks below become unnecessary and the
project starts at the tier engine, analyzer bus, and analytics layer.
The amendments in the next section apply **whichever** path we take.
## Amendments (2026-08-04, post prior-art review)
Apply these on top of the task steps below. Where an amendment conflicts with the original
task text, the amendment wins.
**Task 4 (tier engine)** — add deterministic skip conditions before the path and size
rules, since they are free and catch cases the original rules miss:
- `ReviewContext` gains `isDraft: boolean`, `authorIsBot: boolean`, `commitSubject: string`,
`branch: string`, `labels: string[]`.
- `classify()` takes the context, not just the file list. New rules, highest precedence:
draft MR → `trivial` / `rule:draft`; `/^\s*(wip|draft)\b/i` on the commit subject →
`rule:wip_commit`; `wip/` branch prefix → `rule:wip_branch`; bot author →
`rule:bot_author`; a configured skip label → `rule:skip_label(<name>)`.
- Tests: one per rule, plus one asserting a **risk-path change in a draft MR still skips**
decide that deliberately and encode it (a draft is explicitly not ready for review; the
risk path will be caught when it opens).
**Task 5 (config)** — add keys: `skipLabels: string[]` (default `["skip-review"]`),
`maxChars: number` (provider-aware default, 150000 for Anthropic), `maxFiles: number`
(default 100), `excludePatterns: string[]` (lockfiles, minified, `dist/**`, `node_modules/**`,
`__pycache__/**`), `teamContextFile: string | null`, `dryRun: boolean`. Environment
variables become a config layer between the file and CLI flags: **CLI > env > file >
defaults** — CI systems supply secrets and URLs by environment, and the original design
had no way to receive them.
**Task 6 (analyzer runner)** — the prompt builder takes an optional `priorContext: string`
and, when present, includes it under a heading instructing the model not to repeat points
already made or explicitly rejected. Phase 1 always passes `undefined`; Phase 2 fills it.
Adding the parameter now costs one line and avoids reshaping the prompt module later.
**Task 6 (input clamp)** — before building the prompt, truncate the joined diff at
`config.maxChars` and drop files matching `excludePatterns`. When truncation happens, say
so in the prompt (`[diff truncated at N characters]`) rather than silently sending a
partial diff, and record it on the run record.
**Task 9 (run record)** — add `skipped: boolean`, `truncated: boolean`, and
`synthesis_cost_usd: number` (0 in Phase 1) to `RunRecord` and `toWireFormat`. Adding
fields later means old JSONL lines lack them, which breaks the analytics queries that are
the point of the format.
**Task 10 (CLI)** — add `--dry-run`, which uses a mock `ModelClient` returning a fixed
finding. This lets a team wire up the pipeline and verify plumbing before an API key
exists, and it makes the end-to-end test runnable in CI without network access.
**New Phase 2 task (not in this plan) — review-context synthesis.** Fetch all prior
comments including resolved ones, compress with a Haiku-class model, pass the result to
analyzers as `priorContext`. This is the highest-value item in the whole backlog: without
it, our own 1.7-runs-per-PR cost assumption means every push re-posts findings a human
already dismissed. Plan it before Phase 2's Gitea adapter work is considered done.
---
## Ground rules for the implementer
- **TDD, strictly.** Write the failing test, watch it fail, write the minimum code, watch it pass, commit. A step that says "run it and see it fail" is not decoration — a test that passes before the implementation exists is a broken test.