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:
@@ -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 1–2 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.
|
||||
|
||||
Reference in New Issue
Block a user