che-pair
Increment pair-review skeptic during che-act. Invoked by che-act at the END of each vertical slice (SPEC §4.5 F0..FN), it reviews the slice diff against the TASK ENVELOPE + SPEC §1 deferred list + the
SKILL.mdskills/che-pair/SKILL.md
GitHubChe — Pair Review (the increment skeptic)
SHARED REFERENCES (CANONICAL — do NOT duplicate the body here):
- Simplicity Bias + ordered solution-selection:
engineering-contracts§1- Diff-review criteria (Mode B, local worktree):
che-code-reviewskill- LEAN/YAGNI overengineering scanner (CHECK 5, L1-L13):
che-scope-checkerskill- Security / PII patterns:
che-complianceskill- Bounded-retry precedent:
che-ship§0.9.5 (domain gates refuse a 3rd attempt)
A skeptical reviewer subagent that validates the developer's work at each vertical-slice boundary
during che-act §2 — a pair-programming checkpoint. It shifts quality left WITHOUT replacing
che-ship, which keeps the full-repo pass. Its value is the distinct mandate (opposite bias to
the developer) and the narrow, frozen lens set — not a tone of voice.
§1 WHEN IT RUNS (trigger)
- Invoked by
che-act§2 at the END of each vertical slice (SPEC §4.5F0..FN), when that slice's tests are green. - NEVER per edit, never mid-slice. One review per coherent increment.
- NOT at che-ship. Ship keeps its own full-repo gates (§0.9.1-§0.9.4); this is a different, lighter granularity.
§2 INPUT (small context — never the whole repo)
- The slice diff (
git diffsince the slice started). - The TASK ENVELOPE (blast radius, ACs, reuse mandate).
- SPEC §1 (Goal + the
Non-goals (deferred by design)list). engineering-contracts§1 (the Simplicity Bias).
Passing the whole repository is a bug: the pair reviews the increment, not the codebase.
§3 LENSES (FROZEN — in this order; no new lens mid-slice)
- Scope — nothing outside the envelope; nothing the SPEC §1 deferred.
- Simplicity — Simplicity Bias; premature completeness (
che-scope-checkerL13). - Architecture & boundaries — repo pattern, layering, no leaked implementation details.
- Security / PII —
che-compliancepatterns. - Usability — observable behaviour vs the AC.
- Style — repo conventions.
A new criterion is a SPEC change, never a new review round.
§4 FINDING CONTRACT
Each finding is {id, severity, file, line, lens, cited_rule, suggested_fix, auto_fixable}.
idis stable =lens + file + line + cited_rule. A resolved id is never re-raised.- Citation required: a finding MUST cite the specific rule / AC / lens violated. No citation → invalid → it cannot block.
- Deferred check: if the finding is about something the SPEC §1 marked
deferred by design, it is NOT a finding.
§5 ENFORCEMENT (severity gate)
| Severity | Action |
|---|---|
| CRITICAL | Block. Dev fixes before advancing. NEVER overridable. |
| HIGH | Block. Dev fixes, OR override with a verbatim justification logged to decisions.log. |
| MEDIUM / LOW | Log and defer. Never blocks. |
Tie-break on a judgement call with no clear rule: the developer proceeds (bias toward the smallest increment); the disagreement is logged. The skeptic only stops the line with hard evidence.
§6 LOOP BOUNDS (anti-infinite-loop — non-negotiable)
- Max 2 rounds per slice (review → dev fixes → re-review). A 3rd round is refused by the runner, not left to judgement.
- No-progress stop (before the cap): if round 2's finding set is not a strict subset of round 1's (minus resolved ids), STOP.
- Fix is scoped to the finding — no new code beyond the flagged item.
- Frozen lenses + stable ids — no moving goalposts.
- On stop → escalate (§7). Never a silent round 3.
- Per-slice ceiling (absolute): at most 2 review rounds + 1 escalation rerun = 3 passes per slice. The 4th pass is refused by the runner. Escalation A consumes the escalation rerun; a second stop on the same slice allows only B or C — never another rerun.
§7 ESCALATION MENU (on stop — never a silent loop)
- A = dev fixes manually and re-runs the slice once (consumes the single escalation rerun; a second stop on the same slice allows only B or C).
- B = override with a verbatim justification logged to
decisions.log(HIGH only; CRITICAL is never overridable). - C = back to SPEC — the scope was wrong, not the code.
§8 OUTPUT
- Findings report per slice, written as a worktree artifact (never inside the worktree, never the
fallback):
eval "$(che compute_paths "$WORKTREE_ROOT" "$SESSION_ID" --cwd "$PWD")"PAIR_REPORT="$(che output_path report pair-review "$RELATED_ID" workspace md)"→$CHE_WORKSPACE_SHARED/reports/<related_id>/<YYYYMMDD-HHMMSS>-pair-review.md- Write it with the content on stdin:
che write_file_atomic "$PAIR_REPORT" <<'REPORT_EOF' … REPORT_EOF.
decisions.logentries viache decision_append:PAIR_REVIEW(verdict/rounds/counts, path),PAIR_OVERRIDE(HIGH only),PAIR_ESCALATION(on stop).- Returns control to
che-act§2 with{verdict, rounds, blocking_findings[]}.
§9 WHAT IT IS NOT
- Not a style linter — repo linters do that.
- Not the ship gate —
che-ship§0.9.1-§0.9.4 remains the full pass. - Not configurable — the round cap is fixed at 2; a configurable cap invites "just one more round" and reintroduces the loop.