Repository navigation
chore(loop): isolated double review for pr-review - #72
Conversation
The pr-review stage claimed two independent reviewers but ran a single pi process in one session, so both lenses shared one context and one model. pi has no sub-agent mechanism, so skills/review/SKILL.md's "spawn two reviewer agents" could not be satisfied by the engine. runPi() gains a --tools allowlist and buildPrompt() a reviewSlot. For pr-review, entry.mjs now calls runDoubleReview() (shared/review.mjs), which runs two pi processes with separate --session-dir, a different --model for the second lens (LOOP_REVIEW_MODEL, else the first different DeepSeek model) and --tools read,grep,find,ls,bash. mergeReviews() accepts only when both approve and never counts a missing verdict as approval (retry for transient, failed otherwise), so the two verdicts meet in exactly one place. Host change; the owner's reviewed merge is the checker.
The skill told the agent to spawn two reviewer agents, which pi cannot do. It now describes the host mechanism: two isolated reviewer processes (separate sessions, different models, read-only tools) whose verdicts the host merges, and states that "read-only" means no edit/write tools rather than a filesystem sandbox. Norms-layer proposal; the owner merges it.
|
Use one model - deepseek/deepseek-v4-flash |
|
Modify pr to use one model - deepseek/deepseek-v4-flash |
Coverage
|
|
Loop pr-review — request-changes Reviewer a — correctness & regression (model Reviewer A — Correctness & regression (isolated run, lens A) Verdict: request-changes (confidence: high). The mechanism works — verified first-hand with a
Reviewer b — standards, safety & maintainability (model Reviewer B — standards, safety & maintainability: request-changes
|
Closes #71
loop-task: #71
Why
skills/review/SKILL.mdrequired two independent reviewers, butpr-reviewran onepiprocess in one session: reviewers A and B were two passes of the same context and the same model. pi has no sub-agent mechanism (@earendil-works/pi-coding-agent@0.85.1, Design Principles), so "spawn two reviewer agents" could not be satisfied by the engine and the isolation the norms promised was nominal.What
Option A from the issue — two runs in one job. Options B (workflow matrix) and C (
pi-subagents) both need.github/workflows/**or a new dependency, which the job token cannot push.scripts/loop/shared/agent.mjs:runPi()gains a--toolsallowlist;buildPrompt()gainsreviewSlot(per-reviewer report/result files<rid>.reviewer-<slot>.*, names lens A/B, states the read-only allowlist, suppresses the product-stage commit/push instructions). AddsREADONLY_REVIEW_TOOLS,pickReviewModel,reviewerResultName,mergeReviews,sumUsage.scripts/loop/shared/review.mjs(new):runDoubleReview()launches twopiprocesses with separate--session-dir(…/reviewer-a,…/reviewer-b), a different--modelfor the second lens (LOOP_REVIEW_MODEL, else the first different DeepSeek catalogue entry:flash→pro) and--tools read,grep,find,ls,bash, then merges their verdicts.scripts/loop/entry.mjs:pr-reviewcallsrunDoubleReview; the merged verdict replaces the single-agentresult.outcomepath. Every other stage is unchanged.skills/review/SKILL.md(norms proposal): describes the host-driven mechanism instead of "spawn two reviewer agents", and states that "read-only" means noedit/writetools, not a filesystem sandbox.scripts/loop/README.md: documents the mechanism (new "Isolated double review" subsection,LOOP_REVIEW_MODELenv fact, defect-log entry D35).mergeReviewsaccepts only when both approve (accepted); otherwiserejected. A reviewer that produced no verdict is never counted as approval — a transient engine exit isretry, anything elsefailed. The two verdicts meet in exactly one place.Because the read-only allowlist has no
write/edittool, each reviewer writes its report and result file with abashheredoc; the prompt says so explicitly.Verification
LOOP_ENGINE_CMD), 32/32 checks: exactly two invocations, separate session dirs, different models, both carrying--tools read,grep,find,ls,bash, and the accept / request-changes / missing-verdict merge paths. The captured argv showed--session-dir …/reviewer-avs…/reviewer-band--model deepseek/deepseek-v4-flashvsdeepseek/deepseek-v4-pro.node --checkon the three edited.mjshost files: OK.pnpm lint0 warnings/0 errors;pnpm fmt:checkclean;pnpm build+pnpm check:typesexit 0; Azure + TOS signature oracles passed;pnpm exec vitest run --browser.headlesswithpnpm serve→ 24 files passed, 255 passed / 26 skipped.Review boundary
The
scripts/loop/**change is a loop host PR — the owner's reviewed merge is the checker.skills/review/SKILL.mdis a norms-layer proposal and must not be merged by the loop; the owner approves both in this one PR. No signer,src, dependency or workflow file is touched.