feat(factory): five review skills + a per-review cost model

Skills — the primary now loads conditionally (each one is input tokens), per a
load table in pragent.md:

- attention-tiering: classify every PR trivial/lite/full/oversized BEFORE
  reading anything, and cap file reads, linter runs and subagent fan-out per
  tier. This is the cost governor; the other skills defer to its budget.
- linter-playbook: per-ecosystem detect-and-run commands scoped to changed
  files, the never-install rule, and how to turn a diagnostic into a finding
  instead of pasting tool output.
- security-lens: the inline security checklist for when @security isn't worth
  delegating, built around a source -> sink test each finding must pass.
- malicious-change: hostile-PR detection — injection aimed at the reviewer,
  install/CI-time hooks, obfuscated payloads, dependency confusion, logic
  backdoors. Complements the runtime containment added in the previous commit:
  that stops the agent being hijacked, this makes it report the attempt.
- comment-craft: how to write problem/fix/suggestion so a maintainer can act in
  one read, and what to cut.

pilot/cost_model.py — prices a review against published Claude and OpenAI rates
(fetched 2026-08-18). Prompt sizes are measured from the factory files rather
than guessed; per-tier workloads come from the tiering budgets. The model is
explicit about the thing that actually dominates an agent loop: the whole
conversation is resent every step, so caching moves ~2.3x of the bill.

Blended over a 5/35/55/5 mix with caching on: ~$0.61/PR on Opus 5 or GPT-5.6
Sol, ~$0.24 on Sonnet 5 or Terra, ~$0.12 on Haiku 4.5, ~$0.02 on Luna. At 350
PRs/month that's ~$212 / ~$85 / ~$43 / ~$8.50.

Tests: 101 -> 122.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B11e8TZZxJyzHW7jj7KWUN
This commit is contained in:
Marcos
2026-08-18 04:53:49 +00:00
parent 8c491a7626
commit 30d2a3d7da
10 changed files with 1025 additions and 15 deletions
+17 -5
View File
@@ -20,8 +20,13 @@ opencode.json provider (headroom → glm-5.2:cloud), model, lsp, pe
tests.md subagent — missing/weak test coverage lens (dormant)
perf.md subagent — N+1 / O(n²) / hot-path lens (dormant)
skills/
review-methodology/SKILL.md severity rubric, what to report, anchoring rules
review-methodology/SKILL.md severity rubric, what to report, anchoring, trust boundary
findings-schema/SKILL.md the exact output JSON shape
attention-tiering/SKILL.md trivial/lite/full/oversized + the budget each tier gets
linter-playbook/SKILL.md per-ecosystem check commands + turning diagnostics into findings
security-lens/SKILL.md inline security checklist + the source→sink test
malicious-change/SKILL.md hostile-PR detection: injection at the reviewer, install hooks, backdoors
comment-craft/SKILL.md how to write problem/fix/suggestion so a maintainer can act
commands/
review.md /review slash command (local interactive use)
README.md this file
@@ -45,10 +50,17 @@ flowchart TD
## Lean by default
The `pragent` primary does the whole review in one pass for small/medium diffs
(no subagent calls). It delegates to `@security` / `@tests` / `@perf` subagents
ONLY on large (>~400 lines) or security-sensitive diffs. Token cost scales with
PR size. Subagent recursion is capped by the primary's `steps` budget.
`attention-tiering` is the cost governor: it classifies every PR as `trivial` /
`lite` / `full` / `oversized` before any file is read, and each tier caps file
reads, linter runs, and subagent fan-out. The `pragent` primary does the whole
review in one pass for small/medium diffs (no subagent calls) and delegates to
`@security` / `@tests` / `@perf` ONLY at `full`/`oversized` when the lens has
real surface. Skills are loaded conditionally for the same reason — each one is
input tokens. Subagent recursion is capped by the primary's `steps` budget.
`pilot/cost_model.py` turns those tier assumptions into a per-PR and per-month
cost figure for any provider — run it after changing the factory to see what the
change costs.
`--pure` is passed at runtime so the reviewer doesn't load the host user's heavy
global opencode plugins (supermemory/dcp/morph/pty) which hang cold-start. In the