You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add the interactive Approval Loop (ADR-0003). With --post, the orchestrator hands Findings to a Node script that walks them one at a time, asking accept / edit / skip per Finding; with --post --yes decisions are auto-filled; without --post the script is never invoked. The loop is resumable across Ctrl-C via state at <cwd>/.unic-pr-review/<key>/state.json and a self-ignoring .gitignore written on first use.
This slice keeps the ADO Writer out: the loop just walks Findings and writes approved.json to disk. The actual ADO writes come in the next slice.
Per US 17 / ADR-0003: --post in a non-TTY context without --yes aborts cleanly (exit 2) so the plugin never silently posts unreviewed Findings in CI.
Acceptance criteria
scripts/approval-loop.mjs reads findings.json, walks each Finding interactively (a/e/s keys), and writes approved.json (the Findings the reviewer accepted, with any edits applied).
scripts/lib/cache-paths.mjs exports getApprovalStateDir(key) returning <cwd>/.unic-pr-review/<key>/ and creates <cwd>/.unic-pr-review/.gitignore containing * on first use so the directory is never tracked.
Key derivation: sha16(pr-url) in ADO modes, sha16(cwd + ' ' + branch) in Pre-PR mode.
--post without --yes in a non-TTY context exits 2 with a clear message before reading state.
--yes auto-fills every decision as accept but still writes state (single code path).
Resume: when the state file already exists, the loop skips any non-pending Findings.
Head-SHA mismatch on resume → prompts the user "code has changed since this review was generated — start fresh or continue with stale findings?" with a --reset flag to force fresh.
After successful Writer run (later slice signal), the per-key directory is deleted. On Ctrl-C / error, the directory is preserved.
Parent
docs/issues/unic-pr-review/PRD.mdWhat to build
Add the interactive Approval Loop (ADR-0003). With
--post, the orchestrator hands Findings to a Node script that walks them one at a time, askingaccept/edit/skipper Finding; with--post --yesdecisions are auto-filled; without--postthe script is never invoked. The loop is resumable across Ctrl-C via state at<cwd>/.unic-pr-review/<key>/state.jsonand a self-ignoring.gitignorewritten on first use.This slice keeps the ADO Writer out: the loop just walks Findings and writes
approved.jsonto disk. The actual ADO writes come in the next slice.Per US 17 / ADR-0003:
--postin a non-TTY context without--yesaborts cleanly (exit 2) so the plugin never silently posts unreviewed Findings in CI.Acceptance criteria
scripts/approval-loop.mjsreadsfindings.json, walks each Finding interactively (a/e/skeys), and writesapproved.json(the Findings the reviewer accepted, with any edits applied).scripts/lib/cache-paths.mjsexportsgetApprovalStateDir(key)returning<cwd>/.unic-pr-review/<key>/and creates<cwd>/.unic-pr-review/.gitignorecontaining*on first use so the directory is never tracked.sha16(pr-url)in ADO modes,sha16(cwd + ' ' + branch)in Pre-PR mode.state.jsonshape:{ pluginVersion, createdAt, mode, key, headSha, iteration?, findings: [...] }where each Finding carries{ id, severity, confidence, filePath, startLine, endLine, title, body, suggestion?, decision: 'pending'|'accept'|'edit'|'skip', editedBody?, decidedAt? }. Stable Finding ordering: severity bucket → file → startLine → stable id.--postwithout--yesin a non-TTY context exits 2 with a clear message before reading state.--yesauto-fills every decision asacceptbut still writes state (single code path).pendingFindings.--resetflag to force fresh.tests/approval-loop.test.mjscovers: state-file shape, accept/edit/skip transitions, resume from partial state, head-SHA mismatch prompt, non-TTY abort,--yesbulk-accept (still writes state), cleanup on completion. Tests pipe scripted stdin.Blocked by