Source and scope checkpoint¶
Workflow (Exact Commands)¶
For allowed GitHub reads, run the direct collector under current effective network and filesystem grants or request runtime approval for the complete owning command when required capability is unavailable. No separate workflow consent is needed. Apply GitHub Read Execution; runtime permission and denial remain authoritative.
Permission recovery precedes terminal reporting: Complete the entry metadata reader and PR State Preflight before collector permission handling. For an admitted OPEN PR, before collection, resolve required network and write access using GitHub Read Execution. Missing or unknown access with requests allowed requires the five-field brief and a runtime approval request for the complete collector, not profile setup or an unavailable report. A github-network error alone does not prove denial: inspect current grants and safe diagnostics, request missing capability if permitted and not already denied, then resume collection after approval. Preserve the failed attempt in its run directory and use a fresh run directory for approved recollection. An actual denied request or non-overridable restriction stops this route; never request equivalent access again or broaden destinations. Apply the unavailable gate only after permitted recovery is exhausted or unavailable.
Apply the same capability recovery to required later GitHub reads, including the final PR-state check. Reuse observed permission requirements for the complete owning reader; do not repeat a known default-permission failure or infer a denial from a missing capability. A recovered read resumes the first unmet review checkpoint with retained valid source and reviewer evidence. Preparation, batching or report repair alone does not require recollection or a new user turn.
When runtime permissions show network access enabled and the helper's required paths writable, omit sandbox_permissions and justification on the direct helper call; give no approval brief. Apply GitHub Read Execution even when the active profile name is omitted. A missing label or failed lookup does not mean disabled access; do not run codex execpolicy list to detect a profile. Preserve explicit destination restrictions and check report, .git, and checkout paths separately where applicable.
Entry: resume or previous completed review¶
First apply PR State Preflight for PR scope, including resumed PR work, before prior-report lookup, run creation, collector permission requests or any dependent workflow. Use the retained canonical PR URL on resume. Stop immediately for a currently closed or merged PR; preserve the existing run and local work. The metadata reader owns entry permission recovery and failure diagnostics; collector recovery below applies only after an OPEN state is admitted.
Resolve the metadata reader's profile-or-approval route before the first read, and finish permitted reader permission recovery before reporting entry blocked. Use GitHub Read Execution to distinguish missing capability from an actual denial, then continue this same review after a successful state check.
Resolve this entry before creating or promoting another run. An explicitly resumed incomplete run keeps its frozen source and valid evidence: recover the first unmet checkpoint, without another continuation question or fresh collection solely to repair bookkeeping. Revalidate source receipts and gates when their inputs changed; an unavailable required capability still stops that operation.
When a requested existing report fails lookup, validation or its next consumer (an older result, an unpromoted candidate or a resumed remediation inventory), read and apply Report compatibility and recovery before treating it as missing; lookups that succeed do not load it. The reference preserves the version-reader assessment, the evidence-preserving repair rules, and the interrupted-check/ordering Continue or Skip exception before the other New review, Resume last one and Stop recovery choices.
Previous completed review lookup¶
For a new invocation, resolve identity for all PR input forms before prior-report lookup or run allocation:
- A canonical PR URL supplies the lookup identity directly.
- For a number or
#number, runPLUGIN_ROOT/bin/python PLUGIN_ROOT/shared/select-git-remote.py --canonical-pr-url <positive PR number> --cwd <repository>and retain its printed canonical URL. It selects valid GitHuborigindespite fork remotes, or the sole GitHub remote iforiginis absent; stop if no safe default identity exists. This reads local configuration without contacting GitHub. - For the current-branch PR, obtain one temporary identity file through
PLUGIN_ROOT/bin/python PLUGIN_ROOT/shared/github_read.py --out <temporary identity file> -- gh pr view --json url,statefrom the invoking repository, under the existing GitHub-read boundary. Validate its returnedurland currentstatethrough PR State Preflight; this one read satisfies both identity and state entry checks. Do not create a review run for identity lookup. This metadata is not a completed review or fresh source proof. An identity-read failure after permitted reader permission recovery stops dependent entry work with its diagnostic; never guess an identity or treat denied access as a missing prior report.
Inspect PLUGIN_ROOT/bin/python PLUGIN_ROOT/shared/find-review-report.py --help, use --target <canonical PR URL> against this repository's review reports, and revalidate any returned path with --result <path>. Local review reuse requires an exact prior result path from this session and matching scope/revision; do not infer it from timestamps. Only a validated assessed completed report for the intended target is eligible. Archives, unavailable/closed results, unpromoted candidates, superseded runs and mismatched local revisions are ineligible. A lookup miss or rejection is not a source defect; retain its diagnostic and apply Report compatibility and recovery for a requested existing report before choosing fresh work. A new review request without requested report reuse proceeds fresh; an explicit resume keeps its producer checkpoint. Do not create a run just to perform this lookup.
If an eligible completed report exists and the user has not already chosen, ask once: Reuse completed review or Run fresh review, recommending fresh when current source has not been verified. Reuse emits the existing --complete-run validated final bytes, identifying its recorded revision and limits; it makes no current-head freshness claim. Fresh continues at step 01. Reuse an explicit fresh/reuse answer and retain it across resume. For a new review request without requested report recovery, no eligible completed report means fresh review without a question. A failed requested-report recovery instead returns to the Incomplete review decision; it never silently starts a full rerun. Never resurrect an older report behind a newer incomplete run or treat a prior completed report as proof of today's PR head.
Approved inert fixtures¶
Before native review input is frozen, the parent may admit an inert test fixture occurrence only after verifying it is inert and obtaining explicit user approval. Record each decision in the optional review-routing.json inert_fixture_admissions list with input_sha256, match_start, match_end, match_sha256, approval_evidence, and rationale. Offsets are Python character offsets; both hashes are lowercase 64-character SHA-256 of UTF-8 bytes for the exact input and matched occurrence. Evidence and rationale must be nonblank and pass strict scanning. Store admission metadata outside untrusted source; frozen plans retain declarations and hashes but do not authenticate human approval. A changed context, new occurrence, or overlapping match requires separate approval. Admission covers native direct, paged/challenge, and batch review input only. Real credentials remain refused; outputs, logs, failure and retry explanations, and portable or isolated runtime contexts remain strictly scanned. Never infer admission from placeholders or paths, or whitelist a pattern. Historical direct-plan versions 1 and 2 remain readable with their original scanning and admission contracts; new direct plans use version 3.
If strict failure-telemetry scanning blocks an in-place retry because an admitted fixture appeared in the original task, preserve the failed evidence and start a fresh review with a neutral task and axis that do not copy the fixture. Rediscover and obtain approval for the new context-bound admissions; re-review any coverage that cannot be reused. This recovery is not guaranteed if later reviewer telemetry also contains the fixture. Never redact or exempt failure telemetry to make a retry pass.
For an opaque sensitive-material rejection, the parent may rerun the same review_prepare.py prepare arguments with --discover-fixtures. Valid synchronized routing is required; discovery does not change routing, freeze plans, dispatch reviewers, print source text, or return hashes. It returns input IDs and character spans for scanner matches. In version 3, direct-plan:file:<ordinal> identifies one complete source snapshot record in canonical plan JSON, and direct-diff:section:<ordinal> identifies one complete Git diff section; ordinals start at zero. direct-plan:remainder:<ordinal> and direct-diff:remainder:<ordinal> cover all remaining bytes. Components retain exact UTF-8 slices and bind the artifact root, artifact path, source root and original byte range. Every version-3 direct input also binds shared non-source review metadata: run and parent identity, reviewer assignments and selections, model choice, brief and role-card digests, independence evidence, comparison scope, actual source revision and verified comparison base (including a base obtained from a PR receipt). Verify that metadata as part of the complete input. Aggregate diff and source-content hashes are excluded from this shared identity; unrelated sibling content is separately scanned and does not enlarge component verification. The complete original aggregate is strictly scanned before partitioning, and any match crossing a component boundary is refused. Historical versions retain aggregate direct-plan and direct-diff inputs; direct-task:<role>, direct-brief:<role>, and direct-role-card:<role> identify the delivered task, brief and role card. Each run-owned direct input is framed with its class, role when applicable, artifact root and path, and verified source root; its UTF-8 body remains unchanged. Moving the run or changing an input's identity requires a fresh binding and approval. direct-source:<ordinal> identifies an individual selected UTF-8 source file, framed with its verified source root and repository-relative path; enumerate the sorted snapshot records before excluding missing or non-UTF-8 entries, and recheck that mapping after any inventory change. paged:<role> and source-context:<role> identify complete role inputs; batch:source-NNN:<role> identifies a generated source fragment. Discovery is local parent-owned work, not an authorization for a reviewer or untrusted source to inspect secrets.
Before exporting any binding, inspect the complete current input by verifying its complete component closure and the deterministic generator: for a version-3 plan file component, its complete source snapshot record, component identity and canonical JSON serialization; for a version-3 diff component, its complete Git section and component identity; for a remainder component, all its original bytes and component identity; for a historical aggregate direct plan, the source snapshot, source and selection metadata, context descriptors, independence evidence, brief references and JSON serialization; for a role input, the role card, brief axis and evidence, all assigned source records, matching diff or untracked notices, and generator transformations. A batch fragment also depends on its role card, prefix, UTF-8 slicing and generated coordinates. Every component is an independent scanner input: verifying one does not attest its siblings or authorize an aggregate fingerprint. Reuse component inspection only when its exact bytes and identity remain current. Comparing scanner matches alone is insufficient: a private-key header can be followed by unknown key material. If any component cannot be verified as safe, do not attest or export that input.
For selected verified inputs, create a parent-owned JSON selection file with schema_version: 1 and inputs: each entry has input_id, complete_input_verified: true, nonblank verification_evidence, and matches. Include every scanner match in that input, including overlaps, as pattern_index, match_start, match_end, and match_sha256; derive expected match hashes locally from independently known inert material, without printing unknown matches or hashes. Run the same preparation with --export-fixture-bindings <selection-file> instead of discovery. The helper checks the current generated input and all expected matches before returning binding proposals; it does not grant admission, authenticate the attestation or consent, or modify routing. Expected-hash equality is a success/failure oracle, so this operation is trusted parent-only. Obtain explicit user approval, add the approved proposals with authentic evidence and rationale to review-routing.json, and rerun ordinary preparation. Unselected or changed input remains refused.
Direct-plan matching operates on serialized JSON, so an expected match can include escaped newlines or JSON punctuation beyond the source literal. For a verified source snapshot record, derive expected matches from that complete record encoded with the producer's sorted, indented JSON serialization, rather than hashing a bare source substring. Confirm every derived match against its discovered pattern and span; do not assume the same boundary for other plan components. If the parent cannot verify a match or its complete input safely, leave it unselected and refused.
01: Create run directory¶
Run create_run.py --skill code-review per ../../../shared/helper-cli-contract.md and retain its printed timestamped path literally. A local review keeps that path for its complete lifecycle. A fresh PR review begins there after entry identity resolution; an identity/state-read failure stops before workflow run allocation and retains its temporary reader diagnostic.
02: T0 mechanical scope gate¶
For local scopes, inspect PLUGIN_ROOT/bin/python PLUGIN_ROOT/shared/collect_diff.py --help; collect normalized scope, optional target, and literal <run-directory> path.
For working-tree and path, also use the collector's --review-worktree mode with the invoking repository and <run-directory>/local-source output. It preserves the caller's branch, index, and files while freezing changed tracked/untracked bytes in a detached worktree; retain its review-worktree.json, source snapshot, and staged patch. Inspect source and run authorized checks from the recorded review_worktree, restricting a path review to its selected scope. Caller edits after collection do not update reviewed evidence. Run --verify-review-worktree against that same output after checks and before promotion; source drift fails the review. The intentionally dirty local mirror uses its retained collector receipt for source-bound gates instead of clean-PR --expected-head; never run those gates against the invoking checkout. Keep gate artifacts outside reviewed source; process-working-directory checks do not provide source-bound proof.
If a retained local receipt or patch no longer matches the current collection format, preserve that run and automatically start a fresh authorized review in a new run directory. Recollect the source and regenerate dependent review and gate evidence; do not rewrite the older receipt or ask the user to repair it.
For commit, review the requested Git revision specification, such as COMMIT^!, BASE..HEAD, or BASE...HEAD. Freeze the original revision expression into exact commit IDs before creating a detached worktree at the reviewed tip. For a three-dot range, freeze its merge base; for a single commit, freeze its parent (or empty-tree object for the initial commit). Pass the frozen comparison base as --expected-diff-base and the reviewed tip as --expected-head. Keep the collected diff and requested comparison identity; never reinterpret a relative revision expression after changing checkout. Use clean-head gate guards for this committed-source worktree. A worktree isolates the caller's edits but is not an immutable filesystem: preserve source checks through final acceptance.
PR collection¶
For PR scope, inspect PLUGIN_ROOT/bin/python PLUGIN_ROOT/shared/collect_pr.py --help. Use the canonical URL already resolved at entry as the collector target; do not repeat numeric/current-branch identity resolution after creating the run. A user-supplied URL takes precedence and must pass the collector's canonical PR URL and configured-remote validation. Collect into the literal <run-directory> with --checkout --checkout-mode review; fresh collection must establish current source and PR evidence under the existing collector boundary.
Apply PR Collection Runtime Boundary before collector execution. Do not create or modify runtime approval rules files.
After successful authoritative pr.json collection, run create_run.py --skill code-review --promote-pr-run <run-directory> and capture its single printed final path. The promotion derives the authoritative PR number from pr.json, allocates .reports/codex/code-review/pr-<number>/run-<NNN>/, and moves the complete run without overwriting another run. Use the printed promoted path literally for every later helper, artifact, specialist context, result, and final handoff. Never reconstruct the numbered path or keep writing to the temporary path.
If collection fails before authoritative PR identity exists, keep the timestamped run as an unavailable diagnostic. It is not an assessed PR review and must not be promoted. Existing flat timestamped runs remain discoverable historical artifacts; do not migrate them.
Run the direct owning collector per GitHub Read Execution. Its nested GitHub CLI, HTTPS fallback, checkout, and Git fetch traffic remain bound by the collector contract. An explicit runtime denial or non-overridable restriction stops the collection attempt; diagnose the active permissions and exact command without broadening access or retrying the denied command. Report core collection failure through the existing unavailable-evidence gate.
PR evidence has two tiers.
- Core evidence:
gh pr viewmetadata including contributor description/body, authoritative base-repository identity, refreshed target ancestry, exact local PR head, and diff derived with localgit diff <base>...<head>after SHA verification. - Supplemental evidence: GraphQL review-thread resolution state and derived diff statistics.
Collector and source boundary:
- The collector delegates remote GitHub state reads to
github_read.py, which usesghas opaque local credential broker: it never invokesgh auth, reads token/keychain state, or writes CLI failure output to artifacts. - That read-only boundary permits audited view commands, REST GET, and GraphQL query operations; public HTTPS fallback cannot establish private PR evidence.
- A classified core command failure is recorded in
command-failure.jsonwhen diagnostics exist.
Checkout and source requirements:
- Fresh source is agent's responsibility before review. The collector fetches and verifies the exact PR head, then review mode uses
git worktree add --detachat that immutable commit in an isolated worktree. It does not callgh pr checkout, switch the invoking branch, update PR branch refs, or need the invoking worktree to be clean. Fork, historical, and public-fallback collection fetch base repository'srefs/pull/<number>/head; documented public fallback remains conditional, not default. Never consume mutableFETCH_HEADafter another fetch: use the captured verified commit IDs. - A routine refresh or missing local PR branch is work to perform, not human blocker. Use refreshed target ref directly; do not switch to or merge target merely for reading. Review does not need
git pull, merge, reset, tracking repair, or forced checkout. - Inspect source and run source-dependent checks only in the exact detached path recorded by
<run-directory>/local-checkout.json;diff.patchmust recorddiff_source=verified-local-checkoutprovenance there. Use absolute run-artifact paths after changing execution workdir to that review worktree. A SHA in the receipt alone does not prove that tests ran against it. - Retain a failed or dirty review worktree for diagnosis; do not automatically discard it. A later cleanup may remove only a collector-owned, verified clean worktree after durable review evidence exists, never by broad path deletion.
- Never reconstruct changed source from
curl,raw.githubusercontent.com, orhead-files/snapshots. - If isolated worktree creation or local-diff verification fails, fail instead of reviewing remote raw files. Do not offer detached review source as a remediation destination.
- Do not retry with
--forceunless user explicitly confirms after receiving force reason and overwrite risk.
PR fallback¶
When gh pr view metadata fails, public unauthenticated HTTPS fallback is eligible only when all of these hold:
- The failure is
github-network,github-auth,github-rate-limit, orcommand-timeout. - The checkout target is trusted: canonical PR URL must match a configured GitHub remote; a numeric target is bound to valid GitHub
origin, or the sole GitHub remote whenoriginis absent.
Ambiguous or unsafe targets, permission failures, not-found failures, and unclassified failures remain fail-closed.
Fallback behavior:
- The review-only fallback normalizes limited PR metadata, then uses verified
refs/pull/<number>/headref for detached checkout and derives local diff; it never establishes private PR evidence and is never available to code-remediate. online-review-summary.jsonmust list unavailable fallback evidence as sorted IDs.- Raw GitHub CLI stderr is never persisted; terminal diagnostics may include safe
failure_reasonenum alongside non-secret classification metadata.
Classify scope¶
Classify diff; write <run-directory>/scope.txt:
TRIVIAL: no public API/config/security/ML behavior touched, \<3 files, \<50 changed lines.LOCAL: one subsystem or 3-7 files; local context explains behavior.BROAD: 8+ files, cross-subsystem change, dependency/config change, or unclear ownership.HIGH_RISK: release, security, auth, credentials, deserialization, data pipeline, ML tensor math, CI/CD, or migration behavior, based on evidence beyond public-API touch alone.
Risk categories determine review depth and specialist preference; they do not grant execution permission or independently prove sandbox, approval policy, or provenance. Public API compatibility remains normal T1 review axis and may elevate tier when verified breaking, migration, or release evidence requires it.
PR source and triage¶
For scope=pr, merge-oriented code review is limited to an OPEN PR. collect_pr.py can also collect historical evidence for merged or closed PR, including its diff, online discussions, refreshed current target state, and exact checked-out PR head; that raw collector evidence is useful for diagnosis but must not receive merge recommendation or feed code-remediate.
- Core evidence includes
pr.json,pr-routing.json,remote-selection.json,target-branch.json,worktree-preflight.json,local-checkout.json, and locally deriveddiff.patch. Online evidence includes comments, reviews,review-threads.json,unresolved-review-threads.json, andonline-review-summary.json. - Selected remote matches base repository from PR URL. Fresh target must equal or descend from PR-recorded base (
expected_base_is_ancestor=true); advancement is integration context, never PR finding or merge blocker. Genuine divergence fails open-PR collection; historicaltarget-branch.jsonmay record it. - Verify isolated source state independently of HEAD equality: block unresolved index, tracked edits, and untracked source files in the review worktree. Preserve unrelated edits in the invoking worktree and record them only as context; they cannot be treated as reviewed PR source. Repeat source-state checks after worktree creation.
- Review worktree HEAD exactly matches metadata;
pr-routing.jsonandlocal-checkout.jsonincludeforce_policyproving no automatic forced checkout. Run tests from the recorded worktree, not from the invoking repository checkout. - Report the detached review worktree path and verified revision in the handoff. A matching SHA verifies source, not ownership of a future commit. A review receipt is not a remediation receipt: direct an authorized remediation continuation through a fresh
code-remediatePR collection with--checkout-mode remediate, which must trygh pr checkout <canonical PR URL>and verify its attached branch before edits or commits. If that command fails, remediation may use only its verified same-repository original-branch route; fork remediation may use the shared bounded adversarial recovery loop only on explicit user request. Do not imply review checkout is already the intended commit destination. - Treat unresolved online threads/comments as candidate findings until triaged valid, duplicate, out-of-scope, or already fixed. Never triage a concern as stale: an outdated anchor or line drift does not prove it gone, so follow it into current code. If GraphQL review-thread collection fails or is incomplete, continue source review with empty normalized thread arrays,
review-threads-error.txt,review_threads_status=unavailable, explicit partial-online-triage notes, and confidence gapPR review-thread resolution status was unavailable; online review triage may be incomplete.Never convert that supplemental gap into PR finding or merge blocker by itself.
Embedded review findings¶
Read the complete parent body of each review/comment, including nested <details>, suppressed comments, nitpicks, and outside-diff suggestions. Enumerate every nested finding before deduplication; Comments generated, inline-thread counts, and a summary verdict do not measure embedded obligations. Use <parent-id>#finding-<ordinal> in body order starting at 1 as a local source identity, not a GitHub comment ID. Preserve each exact finding body, code/suggestions, location, and the collected parent evidence path; retain the unsplit parent in reviews.json or comments.json.
In Online Review Triage, record parent IDs, advertised per-section counts when present, every fragment identity, and its individual disposition or owning canonical finding. Reconcile counts before deduplication; unexplained omissions block complete-triage claims and remain explicit confidence gaps. Without advertised counts, inspect the entire body and retain the enumeration. Check each suggestion against current code; the bot's suppressed/duplicate label is not a disposition. Group only independently evidenced same obligations across rounds or bots, preserving all source identities and locations; same file or line alone cannot justify merging. Give distinct obligations separate findings. A summary that merely repeats them is not an additional finding. A changed parent body requires fresh enumeration; do not silently reuse identities from an older snapshot. Carry the complete fragment mapping into remediation provenance.
Collection failure and conflicts¶
Commit review retains binary patch payloads in the frozen comparison. Treat Git's line-delimited, C-quoted path inventory as encoded paths: decode it before matching names to source or coverage, including paths with escaped control characters. Changed gitlinks and selected gitlink source fail closed because the snapshot cannot capture nested repository source; retain that limitation rather than claiming complete review.
If files.txt and untracked.txt are empty with no explicit target, fail before gates. If scope=pr and pr-error.txt exists, fail with captured reason through the Terminal review-unavailable output gate below and do not begin T1/T2 source review.
Terminal review-unavailable output gate: A core T0 PR collection failure is process failure, not review result. When scope=pr and pr-error.txt exists, read and apply collection-failure.md before writing any output or retrying the collector; successful collection does not load it. The reference preserves the unavailable-output prose, result.json and confidence contract, the all-not-applicable check profile, the evidence inspection, and the recovery rules per failure class.
For an existing merge or conflict in the invoking worktree, diagnose it read-only with the evidence named in Code Remediate's existing-conflict guidance: unmerged paths, MERGE_HEAD when present, and current HEAD. Report the observed state in plain English. A review-only run never finishes, aborts, or resolves that merge, never asks for that authorization, and never infers source-edit authority from a review request; the finish/abort/defer choice belongs to code-remediate, so name it as the next step in the handoff. Review inspects its own detached worktree, so an invoking-worktree conflict does not block collection or source review: continue through normal completion gates and record the conflict as context, never as a PR finding. If collection itself fails, explain that separate failure and the exact remaining recovery decision.
PR close screening¶
Terminal close gate (PR only): After successful T0 collection for an OPEN PR and before structural context or T1/T2, screen PR goal, description, minimal verified diff evidence, authoritative project policy/history, and linked upstream evidence for one conclusive proposal-level close reason. This is disposition decision, not source review. If evidence is inconclusive, continue to T1/T2; never close from suspicion, reviewer preference, contributor identity, AI authorship/style, or merely related change.
Use exactly one close code:
| Code | Conclusive evidence | Insufficient alone |
|---|---|---|
FALSE_GOAL |
The stated goal contradicts citable invariant, specification, domain fact, or verified current behavior. | Implementation disagreement, stale wording, or unverified claim. |
BREAKING_CONDUCT |
Direct evidence that contribution is intentionally malicious or adversarial by design, such as backdoor, exfiltration, or supply-chain attack. | An accidental security bug, poor code, suspicion, or inferred intent. |
WRONG_SCOPE |
A documented roadmap, maintainer decision, ADR, or contribution boundary directly excludes proposed goal. | Size, mixed files, or undocumented preference. |
WRONG_PROVENANCE |
A documented license or rights requirement and objective evidence of incompatible or unresolvable provenance conflict. | Fork ownership, code similarity, unknown provenance, or missing CLA/DCO signature that project permits contributor to fix. |
DUPLICATE |
A verified merged change or resolved upstream issue already supplies same still-applicable outcome. | A similar title, overlapping files, related open work, or same issue area. |
UNADDRESSED_REVERT |
The PR semantically reintroduces reverted change and does not address documented reason for that revert. | File overlap, patch similarity, or revert title alone. |
SPAM |
Objective irrelevant, promotional, repeated-submission, or non-substantive evidence shows no bona fide project change. | A small change, missing tests, low quality, or AI-generated content by itself. |
ARCHITECTURE_VIOLATION |
The proposal directly contradicts documented current architectural principle. | Style preference, abstraction concern, or reasoning that requires detailed source review. |
A close decision requires confidence >= 0.90, two distinct evidence sources, recorded counterevidence/falsification check, and binding to verified current PR head. Public-HTTPS fallback evidence cannot close because its confidence cap is 0.89. For WRONG_PROVENANCE, missing required CLA/DCO signature remains normal blocking item unless documented project policy makes conflict terminal. For BREAKING_CONDUCT, accidental security defect remains normal blocking finding; only evidenced by-design harm reaches this gate.
On close, skip structural context, T1, T2, specialist routing, detailed findings, severity classification, and normal recommendation step. Write review-notes.md with Review Decision: close, source findings not assessed, detailed review skipped, exact close reason, summary, rationale, evidence, counterevidence checked, and GitHub mutation: not performed. Emit status=pass for successfully completed workflow, zero findings, review_status=closed, and close_decision={"schema_version": 1, "code": "<CODE>", "advisory_only": true, "head_sha": "<verified PR head>", "summary": "<summary>", "rationale": "<rationale>", "evidence": [{"claim": "<observed fact>", "source": "<artifact, repository path, or authoritative URL>"}], "counterevidence_checked": ["<falsification check>"]}. Include at least two distinct evidence entries. Omit review_decision, recommendations, follow-up, review routing, specialist artifacts, and assessed findings tables; the terminal handoff still renders its compact status table. Run shared gates with detailed-review checks marked not applicable and the review gate validating close artifact, then run both artifact validators. This result only advises user to close; never close, comment on, merge, or otherwise mutate GitHub.
Linked evidence¶
Referenced GitHub evidence: Use the collected current PR body first. If a linked PR or issue is material to a finding, proposal-level close, or compatibility claim, read its canonical identity through installed github_read.py under the same active-profile/runtime approval rules. Browser-cache absence is not evidence that GitHub content is unavailable. Retain the reader's classified failure when access genuinely fails; do not repeat denied requests. An unneeded link is an explicit scope exclusion, not an unresolved prerequisite or a reason to lower confidence in independently established source findings.
Review environment¶
Review environment: Resolve declared checks from the reviewed project's instructions, configuration, and existing environments before assigning missing-tool gaps. A detached worktree does not copy .venv. Use run_gates.py --project-env <absolute existing virtual environment> with the verified PR/commit --worktree; execute the project's declared checker entrypoint, such as its configured pre-commit hook, rather than assuming bare mypy src/. Reusing an environment does not permit imports from the invoking checkout: retain the existing PR pytest import-origin proof. Check that pre-commit's hook environment is provisioned before execution; prepare missing declared tools deliberately through the parent under Project Dependency Preparation, retaining actual filesystem, network and code-execution boundaries. A genuinely absent required checker remains a failed prerequisite with the exact attempted environment and command; an unconfigured checker is not applicable. Never install dependencies into the project or global environment, silently skip a required check, or lower assertions to manufacture a passing gate. Complete environment bootstrap follows Project Dependency Preparation below. A remaining claim blocked by a Python package absent or installed outside the reviewed head's declared specifier follows Ephemeral Dependency Evidence instead of becoming a missing-tool gap: a non-executing wheel fetch into the run directory, then a separate test run over that overlay that never shares the fetch's escalation. A package newly declared by the reviewed head but absent from the review base is a new dependency finding, never an overlay; a package only named by the base CI is not a new PR dependency, but remains ineligible for this overlay. For that overlay, a name the review base or the user routes anywhere but the default index, or whose routing cannot be determined, keeps the gap with reason non-default index dependency <name> and is never fetched.
Before leaving a required check unresolved, inspect the complete declared bootstrap, runtime, existing project environments and pre-commit cache, including installed project metadata and isolated subprocess imports. A dependency overlay alone does not install the reviewed distribution. Reuse an eligible environment with source-origin proof or let the parent prepare a disposable task-local environment under Project Dependency Preparation. A review that requires executable gates already authorizes eligible declared preparation; do not ask a bootstrap-consent question just because packages are absent. Verify the complete lane, including runtime dependencies, test groups/extras and compatible interpreter. Request only an actual missing runtime capability under its owning boundary, then resume this run's same source-bound checks without another review invocation. Continue independent inspection while an actual decision is pending. Do not install globally, change the invoking environment, substitute a released package for reviewed source, or execute project build code outside its authorized sandbox. A denial or genuinely unavailable preparation retains the actual failed check, exact recovery condition and truthful completed review; never convert a missing environment into source rejection, null source judgment or a skipped applicable check.
Failing hooks¶
Failing hooks: Apply the diagnosis and PR and target hook comparison contract. Run applicable pinned hooks on isolated disposable source copies when they may autofix; retain source identity, exit status and before/after diff. Autofix capability alone never justifies an unexecuted lint/format gap. If CI reports an error but its details are inaccessible, retain that remote state and still perform feasible local diagnosis and checks; local success does not clear the remote check. Compare exact revisions without changing the invoking checkout; retain failed or unavailable gates. This read-only review does not authorize source/config repairs; hand those to authorized remediation.
Python structural context¶
Structural context (required for Python diffs): after diff is collected, probe codemap-py once for changed-symbol blast radius: PLUGIN_ROOT/bin/python PLUGIN_ROOT/shared/codemap_adapter.py context --category review --root <reviewed-source-root> --diff-file <run-directory>/diff.patch --out <run-directory>/codemap-context.json. <reviewed-source-root> is the verified source checkout: local-checkout.json.worktree for PR review, the review_worktree in review-worktree.json for local working-tree/path review, or the detached checkout at the verified reviewed tip for commit review. The adapter uses run-owned index and telemetry destinations by default for this review CLI, with provider coordination retained beside the chosen index; keep the run outside the verified source checkout and reuse its public destination overrides for follow-ups. Preserve explicit overrides and frozen selection, and verify that any explicit destination does not change the frozen source inventory. Never alter source ignore rules or receipts to hide cache writes. The parent runs this query serially before specialist preparation; a supporting provider automatically prepares that checkout's own canonical index from its current source bytes, including the frozen local mirror's unstaged content. This cache preparation never authorizes source edits, staging, commits, or mechanical invocation of scan-codebase. Never substitute the invoking checkout's index; preserve an older provider's missing-index, incompatible, or root_mismatch outcome and use bounded source inspection under the shared contract. Never run diff-impact without --diff-file: in a detached review worktree it compares the tree with itself and reports zero changed files. Running it is mandatory whenever files.txt lists a .py path; untracked-only and .pyi-only changes are outside the diff file the provider reads. Relative --root/--diff-file resolve against your working directory. The artifact keeps the bounded diff-impact answer (changed modules, risk, unmapped files, test impact); every changed Python file unmapped, or any deleted Python module (the provider never reads it, so its importers stay unchecked), is degraded with its reason. The review validator rejects a fresh candidate for a Python diff with no artifact, a skipped one, one whose --diff-file was not <run-directory>/diff.patch, or one whose status, reasons, or query disagree with what ran. Per ../../../shared/codemap-contract.md, provider absence/incompatibility stays non-fatal — the artifact records status and reason, then continue with T1/T2 as scoped by scope.txt alone. Before recording a PATH miss as provider absence, resolve an available active Codemap skill path/install record and pass its exact plugin root via --provider-root; never glob installed caches or choose a newest version. Reuse CODEMAP_BIN when explicitly configured; select an existing compatible CODEMAP_PYTHON when the provider requires a newer Python. A degraded artifact names each cause in status_reasons; carry them as structural-evidence limits, never as reviewed-source coverage. Persist diff-impact evidence once here; T2 specialist fan-out (step 04) includes <run-directory>/codemap-context.json in each triggered context pack. A role whose axis needs a structural fact this artifact leaves open gets at most 3 targeted follow-ups under the contract's Specialist follow-up queries rule; the parent owns these follow-up queries, so run them before preparation and cite each codemap-followups/<role>-<NN>.json in that role's brief.
03: T1 primary diff review¶
Blind blueprint first, when declared tier is not TRIVIAL and the change adds behavior or public API (T0 evidence: PR body/title, files.txt, numstat.txt — not diff content). Before opening diff.patch or any changed file at head, read only PR title/body, linked issue bodies, and files.txt names; write <run-directory>/blind-blueprint.md: the problem restated in two lines, then your own blueprint-level solution — approach, key data structures/functions, edge cases — one page maximum, no code. Then open diff.patch for the axes below. Where diff and blueprint diverge: a divergence with a concrete defect and a required change becomes a canonical finding record; one that a prior decision, constraint, or incident could explain becomes a question to the author under No-Finding Residual Risks — never a Findings row, whose contract requires required_change and a status. Same thread means ordering-only isolation, not context isolation; add Confidence Gaps line Blind blueprint written before diff in the same context; anchoring reduced, not eliminated. Skip the blueprint for pure refactor, style, docs, dependency, or CI changes and when PR body and issues give no usable problem statement; record the skip reason in Scope, never invent a problem statement.
Review axes, in order:
- API and behavior regressions.
- Test coverage and edge-case gaps.
- Error handling and logging.
- Project coding principles: changed code follows applicable
AGENTS.mdlayers for simplicity, readability, reproducibility, short reusable units without low-value argument-remapping wrappers, guard clauses or earlyreturn/yield/continue, project docstring-style detection, concise purpose docstrings, and inline comments only for non-trivial implementation blocks. - Security, data, ML, CI/CD, or release risks signaled by T0.
- Documentation or migration gaps caused by behavior/API changes.
Blocking defaults guide merge judgment; they are not automatic labels:
| Category | Default | Nuance |
|---|---|---|
| CI red or failing check | blocking | Only major or required-check failure. Note single flaky-looking rerun blip without automatically blocking. |
| Missing test coverage for new or changed logic | blocking | Require coverage proportional to changed contract and regression risk. |
| Accidental security bug | blocking | Evidenced by-design harm is terminal BREAKING_CONDUCT at close gate. |
| Breaking API change without deprecation or migration path | blocking | Require project-compatible transition before merge. |
| Missing docs for new or changed public behavior | blocking | Missing CHANGELOG entry alone is not blocking and may be completed through release workflow. |
| Performance regression | contextual | Block unexplained regression against recent releases; do not block when correctness fix necessarily removes invalid prior speed. |
| Merge conflicts | not blocking | Conflict resolution belongs to code-remediate; review does not gate on conflict alone. |
| Incomplete implementation | blocking | Includes TODOs in changed paths, missing expected error handling, or unfinished public contract. |
| Missing CLA/DCO signature | blocking only when the project requires it | Verify a CLA/DCO bot check or explicit contribution policy first; without such a requirement it is not applicable. |