Code Remediate
See the fixed recurrence and root-cause policy and reasoning-progress escalation policy for repeated-obstacle handling; record and validate reasoning-progress.json before another cycle after escalation trigger.
Run linear code remediation to close findings.
Input Schema
{
"findings_source": "optional path, explicit list, review for the current-session assessed review, or +review/+report/report/latest to auto-select the newest matching PR review report; omit with a bare PR target to use current online review items",
"mode": "optional report|pr|auto; infer pr for bare number, #number, or PR URL",
"target": "optional shorthand target number, issue/PR URL, path, or current branch",
"pr_target": "optional PR number, PR URL, or current branch PR when mode=pr",
"remediation_scope": "optional all|critical|high|medium|low|comma-separated severities|comma-separated selection indexes; ask before editing when omitted",
"target_scope": "required path/module",
"done_when": "selected findings are fixed/resolved and unselected critical/high findings are explicitly deferred"
}
Workflow (Exact Commands)
01: Create Run Directory
Run create_run.py --skill code-remediate per ../../shared/helper-cli-contract.md.
02: Normalize input and optional report findings
Shorthand rules:
- Canonical in-session report:
$code-remediate review => mode=report, REQUESTED_REPORT=true, FINDINGS_SOURCE=latest-assessed-current-session-review. It resolves to the latest assessed code-review result created in the current session. Reuse the exact prior artifact path recorded in this session; do not scan reports or infer a PR target. Do not collect PR evidence or fetch online review comments. If no assessed current-session review result is available, fail with current-session-review-report-required and instruct the user to run $code-review <target> first or supply a report path.
- Canonical online-only PR:
$code-remediate #123 => mode=pr, PR_TARGET=123, REQUESTED_REPORT=false, FINDINGS_SOURCE=none. Accepted bare PR forms are: bare number, #number, PR URL, and natural-language bare PR targets; they collect current online items and verified local checkout without a prior review report.
- Natural-language online-only aliases:
remediate 123, remediate #123, remediate PR 123, and remediate <github-pr-url> use same bare-PR route.
- Canonical report-backed PR:
$code-remediate #123 +review => mode=pr, PR_TARGET=123, REQUESTED_REPORT=true, FINDINGS_SOURCE=latest-matching-review-report.
matching-review-incomplete:<run-directory> means identified review retained notes but never produced promoted result or candidate. First explain in plain English that preliminary evidence exists but review did not complete; then state Review handoff blocked, link that retained run, and name exact failed checkpoint with evidence-backed next action. Return to producer completion checkpoint and perform permitted diagnosis yourself; do not claim no review was performed, consume notes as validated result, select older verdict, or switch to online-only intake. This applies across sessions as well as within one session. A newer malformed result similarly blocks stale assessed fallback.
- Compatibility alias:
$code-remediate #123 +report => mode=pr, PR_TARGET=123, REQUESTED_REPORT=true, FINDINGS_SOURCE=latest-matching-review-report; $code-remediate #123 +report compatibility alias has same report lookup.
- Natural-language aliases:
remediate 123 report, remediate #123 report, and remediate PR 123 report => mode=pr, PR_TARGET=123, REQUESTED_REPORT=true, FINDINGS_SOURCE=latest-matching-review-report.
remediate <github-pr-url> report => mode=pr, PR_TARGET=<github-pr-url>, REQUESTED_REPORT=true, FINDINGS_SOURCE=latest-matching-review-report.
- An explicit review result path combined with PR target sets
REQUESTED_REPORT=true; bare PR target has no implicit report path.
- Bare PR and report-backed PR routing are distinct: explicit
+review, +report, report aliases, and report paths retain report-plus-online behavior; absence of report source selects online-only intake and never falls back to report lookup.
- If
+review, +report, report, latest, latest-report, or review-report replaces path, find newest matching result across canonical .reports/codex/code-review/pr-<number>/run-<NNN>/result.json and legacy flat .reports/codex/code-review/<timestamp>/result.json artifacts whose sibling pr.json has same PR number/URL as PR_TARGET.
- When
REQUESTED_REPORT=true, no matching code-review report means the requested assessed findings are missing. Explain that first, then ask for an existing report path or permission to run $code-review <target> if not already authorized. A matching-review-unavailable-rerun-code-review result means PR collection failed before any assessed review; do not use it as findings input. Inspect that run's classified error and retained checkout diagnostics, perform permitted recovery, and rerun collection only when the diagnosed cause or external state supports it; ask only for the specific missing access or decision. A matching-review-closed-not-remediable result is a terminal close disposition with no source findings; do not remediate it or fall back to an older assessed report. A matching-review-candidate-unpromoted:<path> result requires the bounded same-session recovery below; do not fall back to an older assessed report.
- When canonical matching PR runs exist, select greatest parsed numeric
run-<NNN> index. Otherwise select greatest parsed legacy flat timestamp. Never rely on lexical glob order, modification time, or directory traversal order; record selected path in <run-directory>/findings-input.txt.
When FINDINGS_SOURCE=latest-matching-review-report, inspect python PLUGIN_ROOT/shared/find-review-report.py --help, resolve PR_TARGET against .reports/codex/code-review, and assign printed path to FINDINGS_SOURCE. The helper searches explicit canonical nested PR runs plus legacy flat timestamped runs; no migration is required. It filters explicit review_status=unavailable diagnostics, so older assessed review remains eligible when newer collection failure exists. A newer review_status=closed result instead blocks older findings because close disposition is current and non-remediable. Before accepting explicit review result path as findings input, invoke same helper with --result <path>; it rejects unavailable results with rerun instruction, closed results with matching-review-closed-not-remediable, and candidate paths with matching-review-candidate-unpromoted:<path>. A bare PR target must not run this helper, scan prior review reports, or require a code-review artifact.
For matching-review-candidate-unpromoted:<path>, recover only when the candidate's specialist-manifest.json names the same parent thread as the current remediation session. Run the review-specific validator, then the shared validator, against that exact candidate and its review run directory; promote it to result.json only after both validators pass, then rerun the finder and use the promoted result. Never consume result.candidate.json directly. If either validator fails, persist its exact stderr code in <run-directory>/review-candidate-validation.txt, including manifest-invalid-attempt-count:<role> when applicable, and return to the code-review manifest preflight checkpoint for one evidence-preserving repair from retained specialist and rollout records. Never invent missing attempt provenance or retry a specialist for artifact bookkeeping. After a repaired manifest passes --manifest-only, rerender/rewrite the candidate as required and retry both validators once. If exact evidence cannot repair the run or either validator still fails, do not promote the candidate, rerun the full review, or fall back to an older assessed report; stop with the exact error and candidate path. This recovery has no waiting loop and makes no remote mutation.
When FINDINGS_SOURCE exists, copy its exact bytes to <run-directory>/findings-input.txt with filesystem tool. Do not depend on shell variable retaining that source path. For bare PR online-only intake, do not create <run-directory>/findings-input.txt; set CODE_REMEDIATE_METADATA.review_report_intake.requested_report=false and every report-item counter to 0.
For mode=pr, inspect python PLUGIN_ROOT/shared/collect_pr.py --help; collect PR_TARGET into <run-directory>/pr with checkout enabled for current online evidence, target/head refresh, local checkout.
In runtimes with network sandboxing, execute the complete collector command with approved external network access from its first attempt under ../../shared/native-skill-contract.md. Before requesting it, state:
Action and purpose: collect current PR evidence before remediation.
External capability: read-only GitHub access plus documented local checkout.
Credential behavior: gh is opaque local credential broker.
Filesystem and worktree effects: write collection artifacts and may update local checkout.
Retry policy and safe denial outcome: one classified recovery only, otherwise remediation uses its core collection-failure path.
- For Codex exec, set
sandbox_permissions="require_escalated" on the collector with a narrow read-only GitHub justification; never request a broad python approval prefix. Apply the other shared runtime and denial boundaries. A direct approval for gh pr view does not cover gh spawned by the collector: the outer collector command owns its nested GitHub CLI, HTTPS fallback, checkout, and Git fetch traffic. The PR request authorizes asking, never bypassing runtime approval.
- If an agent-caused unapproved attempt returns
github-network before any user approval request or denial, rerun that same complete collector command once through the runtime's external-network approval mechanism before treating collection as terminal. This recovery exists only for that pre-denial sandbox mistake; after the user denies approval, the current turn stops and the retry is forbidden. Only after that approved collector attempt fails, external-network approval is unavailable, or the user denies it may remediation apply its core collection-failure path; never repeat more than one approved recovery attempt.
github_read.py is plugin-wide GitHub data boundary: do not invoke gh outside it.
- It uses
gh as opaque local credential broker, never invokes gh auth, reads token/keychain state, or persists GitHub CLI failure output.
- It permits only audited built-in view groups (
gist, issue, pr, project, release, repo, ruleset, run, workflow), REST GET, and GraphQL queries; no remote mutation is permitted.
- Its public HTTPS fallback cannot establish private PR evidence.
Core and supplemental evidence:
collect_pr.py treats PR identity/body plus exact local source as core evidence: it uses numbered fork-aware gh pr checkout <number> when needed, verifies PR head SHA, and derives diff.patch locally. Its worktree-preflight.json permits unrelated tracked edits and blocks only paths checkout would overwrite.
- GraphQL review-thread resolution status is supplemental; if unavailable, collector writes empty normalized thread arrays plus
review-threads-error.txt and continues.
- Record that online-triage coverage gap in
action-items.md, result confidence gaps, and unresolved/deferred closure rationale; never treat it as code finding or silently claim complete thread triage.
- On core collection failure, use
<run-directory>/pr/pr-error.txt, <run-directory>/pr/worktree-preflight.json, and <run-directory>/pr/command-failure.json when present to distinguish classified process failure from source-review findings; for dirty-worktree overlap, name exact overlapping_paths first; do not treat it as merge recommendation.
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, or command-timeout.
- The checkout target is trusted: canonical PR URL must match configured GitHub remote; numeric target requires exactly one distinct configured GitHub repository identity.
Ambiguous or unsafe targets, permission failures, not-found failures, and unclassified failures remain fail-closed.
Fallback behavior:
- The fallback normalizes limited PR metadata, then uses verified
refs/pull/<number>/head ref for detached checkout and derives local diff; it never establishes private PR evidence.
online-review-summary.json must list unavailable fallback evidence as sorted IDs.
- Raw GitHub CLI stderr is never persisted; terminal diagnostics may include safe
failure_reason enum alongside non-secret classification metadata.
Findings intake:
- For
mode=report, normalize only the review report after confirming it is assessed. Reject review_status=unavailable and review_status=closed; the latter is a close disposition without source findings. Do not read, collect, or infer any <run-directory>/pr/ evidence.
- For
mode=pr, always normalize <run-directory>/pr/comments.json, <run-directory>/pr/reviews.json, <run-directory>/pr/review-threads.json, and <run-directory>/pr/unresolved-review-threads.json.
- When
REQUESTED_REPORT=false, those current online records are complete findings source. Do not read or infer review report, and do not require prior assessed artifact. If no online item is actionable after triage, continue through documented none-selectable path instead of requesting code-review.
- When
REQUESTED_REPORT=true, additionally normalize <run-directory>/findings-input.txt. Treat review report as closure contract, not only code findings: before editing normalize report findings, failed checks_failed, follow_up, review_decision.required_next_work, confidence gaps, confidence-recovery remaining limits, and no-finding residual risks into report-origin action items.
- Use local checkout in
<run-directory>/pr/local-checkout.json as authoritative source for code triage/edits and require its verified-local-checkout diff provenance.
- Refresh both target and PR head yourself before conflict/review-item resolution;
<run-directory>/pr/target-branch.json and <run-directory>/pr/pr-head-fetch.json must record fetched tips, including fork PRs. The primary checkout remains gh pr checkout <number>; preliminary fork pull-ref fetch makes its commit available for safe checkout comparison. Routine freshness is agent-owned work, not request for user to pull branches. Use fetched target ref directly; separate local target checkout is unnecessary.
- Checkout artifacts include
force_policy; if checkout fails or does not match PR head, record forced-checkout-not-attempted. Inspect classified failure, retained command/checkout diagnostics, and current branch/head yourself; continue permitted safe recovery, stopping only before forced retry, loss of user changes, unavailable access, or unresolved identity. If fresh fetched evidence proves PR moved, recollect metadata once and verify rebuilt bundle under existing authorization. Report actual expected/observed IDs and next action, never generic "repair checkout" instructions.
- If core metadata, target refresh, checkout, or local diff fails, record failure; continue with supplied report only when user accepts stale online-review coverage and no code edits are required, else fail.
- If only supplemental review-thread resolution status is unavailable, continue with explicit partial-coverage evidence and do not infer that any thread is resolved.
- Never inspect/edit PR code from
curl, raw.githubusercontent.com, or copied head-files/ snapshots; raw-file snapshot rejection: snapshots are rejected.
03: Understand PR Intent, Then Resolve Merge Conflicts
For mode=pr, required before action-items.md, resolution-scope.md, or report/PR-review code changes. Establish clean PR and latest target implementation before conflict markers make worktree noisy.
Read remote_ref from <run-directory>/pr/target-branch.json with JSON parser and retain exact printed value as <base-remote-ref>. Run git merge-base HEAD <base-remote-ref> as argv, retain its single printed value as <merge-base>, and write that value to <run-directory>/pr/merge-base.txt. Run these argv commands separately and write stdout to named artifacts:
git diff --stat <merge-base>..HEAD → <run-directory>/pr/pr-intent.diffstat
git diff --name-only <merge-base>..HEAD → <run-directory>/pr/pr-intent-files.txt
git diff --stat <merge-base>..<base-remote-ref> → <run-directory>/pr/target-since-merge-base.diffstat
git merge-tree <merge-base> HEAD <base-remote-ref> → <run-directory>/pr/merge-tree.txt
Record each command's exit status; unavailable evidence is gap, never implied clean result.
Write <run-directory>/merge-prestage.md sections before attempting merge:
## PR And Target Refresh: PR number/head, target branch, fetched target hash, local checkout hash, evidence paths.
## Clean PR Implementation Context: intended change, changed files, key invariants, clean-PR-implied tests/docs.
## Target Branch Context: relevant fetched-target details, especially likely collision files.
## Conflict Risk: mergeability, merge-tree signal, both-side changed files, conflicts present/likely/absent.
## Resolution Strategy: reconcile PR intent and target implementation for each conflict/likely collision before review/report findings.
## Merge Execution: conflict decision, authorization state, merge command/status, resolved paths, verification, and evidence path.
Write <run-directory>/pr/merge-resolution.json with schema_version, conflicts_detected, status, authorization, base_remote_ref, target_oid, pre_merge_head, post_merge_head, merge_commit, resolved_paths, unmerged_paths, and evidence. Use status=not-needed and authorization=not-required when fresh evidence proves no conflict. Do not merge target merely to refresh conflict-free PR.
If conflicts are present or likely, resolve them as PR integration before normalizing or addressing any report/online-review item:
- Use already-recorded clean PR purpose, invariants, target changes, and per-file resolution strategy as primary context. Inspect
git show <base-remote-ref>:<path> and nearby tests where needed; conflict markers are secondary evidence only.
- A generic remediation request does not authorize local merge commit. Show target ref/OID, intended merge, collision files, resolution strategy, and overwrite/commit effect. Ask for explicit authorization to create local target-merge commit:
Authorize this local merge and commit? (yes / no). Ask only when that exact action is not already authorized. A no leaves the merge unapproved. Record authorization=explicit-input|user-confirmed; if authorization is absent or runtime cannot ask, stop with target-merge-authorization-required before review-item work.
- After authorization, run
git merge --no-commit --no-ff <base-remote-ref> with retained literal ref. Never rebase, force checkout, or rewrite history as substitute.
- Resolve only merge collisions, preserving recorded PR intent atop fetched target implementation. Do not combine review-comment fixes unless same lines cannot otherwise form coherent merge; record unavoidable coupling in
<run-directory>/closure-log.md.
- Verify
git diff --name-only --diff-filter=U is empty, run smallest collision-relevant tests, then create authorized merge commit using ../../shared/commit-response-template.md and required Co-authored-by: Codex <codex@openai.com> trailer. Record pre/post HEAD, merge commit, resolved paths, tests, and empty unmerged-path list in merge-resolution.json and ## Merge Execution.
Do not create action-items.md, resolution-scope.md, or edit for report/online-review finding until merge-resolution.json is not-needed or completed, worktree has no unmerged paths, and no merge is in progress. If merge resolution or its verification fails, stop; do not hide conflict behind finding remediation.
If checkout starts dirty, conflicted, or partially merged, fail or ask cleanup before editing. Never use existing conflicted worktree as primary truth.
04: Normalize Findings Before Editing
Structural context (optional): when target_scope names Python module, also probe codemap-py once for changed-symbol/caller impact: python PLUGIN_ROOT/shared/codemap_adapter.py context --category review [--target <qname>] --out <run-directory>/codemap-context.json. Per ../../shared/codemap-contract.md, absence/incompatibility is non-fatal — continue normalizing available report and/or online findings evidence. Persist result once here; specialist owners assigned in step 06 receive <run-directory>/codemap-context.json in their context pack, never fresh query.
Write <run-directory>/action-items.md starting with ## Review Item Resolution Table, before prose. Normalize by canonical obligation, not by each report mention. For structured reviews, consume each review_findings record once using report [<report-json>#<finding-id>]; copy its title, summary, required change, evidence and closure evidence. Historical ID/severity-only or Markdown reviews remain readable: identify one primary finding/action record and attach other views of that same finding as related_mentions, never independent source records. Consolidate only matching canonical finding IDs within one report or independently evidenced same obligation; shared closure text, test command or source location alone never justifies merging distinct findings. A genuinely independent gate or confidence obligation remains separate item. Do not weaken report validation or certify historical failed results.
Every source has one owning item. Preserve genuinely independent report and fresh-online evidence with exact references, bodies and evidence paths. An online comment already attached to finding must not also be ingested as second duplicate row; record its duplicate/corroborating relationship in owning item's expanded record. Multiple different sources for same obligation may share item; never drop provenance. Each report source carries finding_id when known; optional related_mentions retains repeated summary/action/confidence locations without increasing source counts. Render primary sources as report [<report-file>:<line>], report [<report-json>#<finding-id>], or online [<comment|thread|review-id>]. Keep full source records in metadata and expanded item records: category, stable source ID, location or general, complete body, evidence path or report-only. No counts, representative sources, ellipses or artifact links may replace required evidence. Before asking for selection, run executable inventory gate in step 05; handwritten counts are not acceptance evidence.
When online-review-summary.json reports pr_metadata_transport=public-https-fallback, list sorted unavailable_evidence IDs github_provided_file_list, mergeability, review_decision, reviews, and top_level_comments in action-items.md and online action evidence, and add exact confidence gap Public HTTPS PR metadata fallback omitted evidence: <sorted IDs>. Substitute that sorted list into <sorted IDs>. The final remediation confidence is capped at 0.89; carry gap and its closure state through action-items.md, result metadata, and unresolved/deferred evidence.
For mode=pr, check every report/PR-review item against PR intent and changed diff before triage:
direct-diff: references PR-changed file/hunk/behavior.
pr-intent: connects to PR purpose, acceptance criteria, review decision, requested change, even outside touched hunk.
adjacent: touches nearby code/tests/docs/config/verification needed for safe merge.
unknown: current evidence cannot determine relation.
unrelated: no connection to PR intent, changed files, adjacent verification, or merge readiness after local PR-context inspection.
Write relation in action table and every expanded item. direct-diff, pr-intent, adjacent, unknown are never out-of-scope; keep valid/needs-clarification and selectable unless resolved, already-fixed, or already-applied evidence closes them. If current PR cannot close one, record unresolved, deferred, or required follow-up; never downgrade to out-of-scope. User can select, defer, or explicitly rule it into PR.
When REQUESTED_REPORT=true, include non-code report-origin review obligations:
- failed
checks_failed, including missing independence, full gates, lint, type, test, confidence gates
follow_up, especially needs-independent-review
review_decision.required_next_work and merge/readiness blockers
- confidence gaps, confidence-recovery remaining limits, no-finding residual risks blocking acceptance
Report-origin obligations default in scope for +review, +report, report, or review-report path. Never mark out-of-scope merely because closure needs independent reviewer, installed tool, CI/full-gate run, or unavailable local environment. Mark valid/needs-clarification, keep selectable, leave unresolved/user-deferred until closure evidence. out-of-scope only for item proven unrelated to requested report/PR/target after citing evidence; never use it to silence failed gates/follow-up.
After resolution table, add ## Review Report Intake: whether report was requested, total report-origin items, report-origin review-gate/follow-up items, selectable review-gate/follow-up items, and report-origin out-of-scope count. When REQUESTED_REPORT=false, record requested report: false and 0 for every report count. The out-of-scope count must be 0 unless item is proven unrelated to requested report/PR/target.
Required table columns:
- selection index: numeric selectable;
- non-selectable
- input item: stable input row id, report id, PR comment id, review id, thread id, source location
- item name: short human-readable finding/review obligation/gate/comment/thread name
- item type:
code|test|docs|review-gate|confidence-gap|pr-comment|pr-review|pr-thread|unresolved-pr-thread|ci|typing|lint|security|performance|process|other
- sources: ordered compact unique pointers rendered as
report [<report-file>:<line>], report [<report-json>#<finding-id>], or online [<comment|thread|review-id>]; join multiple records with one plain ASCII space and never append locations, bodies, evidence paths, resolutions, summaries, or online URLs
- item id or source location
- source category:
report|online; online covers PR comments, reviews, threads, and unresolved threads while item type preserves detailed online subtype
- fetched evidence path, or
report-only
- PR/diff relation:
direct-diff|pr-intent|adjacent|unknown|unrelated
- severity
- summary
- triage status:
valid|resolved|duplicate|stale|out-of-scope|already-fixed|already-applied|needs-clarification
- resolution:
implemented|resolved|rejected|stale|not-applicable|duplicate|already-fixed|already-applied|needs-clarification|unresolved
- owner/status:
todo|fixed|resolved|deferred|unresolved|not-selected|not-actionable
- resolved how:
[O<row-position>]; immediately below table define [O<row-position>] <how/why resolved/unresolved/deferred/not applicable>
- evidence: closure evidence or unresolved rationale as
[E<row-position>]; immediately below table define [E<row-position>] <complete evidence, unresolved rationale, owner action, or next action>
After table add ## Final Resolution Summary:
- what was requested
- ingested entries total
- resolved or already-closed entries total
- implemented entries total
- unresolved entries total
- deferred/not-selected entries total
- not-applicable/stale/duplicate/rejected entries total
- one sentence: all selected local actionable items closed or not
Then add ## Final Resolution Table Completeness:
- ingested entries total
- final table rows total
- omitted entries total: must be
0
- selectable/non-selectable row totals
- triage status counts
- resolution status counts
- source records total
- represented source records total
- omitted source records total: must be
0
- grouped items total
CODE_REMEDIATE_METADATA.final_resolution_table has same item and source counts plus items, ordered machine-readable source for durable and final-chat tables. Each item contains non-empty input_item_id, item_name, item_type, severity, triage_status, resolution_status, owner_status, resolved_how, and evidence, plus boolean selectable and non-empty ordered sources list. Each source contains kind=report|online, source_id, location, body, and evidence; (kind, source_id) is unique across items. A report source_id is <report-file>:<line> or <report-json>#<finding-id>; online source_id is its stable comment, thread, or review ID, never URL. Preserve source order, full bodies, and unique IDs. Render the Review Item Resolution Table and Final Outcome Table from this list. Their Sources cells contain only ordered compact pointers; full source records remain in metadata and expanded item records. The durable table uses [O<n>] and [E<n>] cells and defines their complete resolved_how and evidence text immediately below table. The final handoff maps cells mechanically as input_item_id, severity, item_name, every compact source reference joined in source order, resolution_status — [O<n>], and [E<n>] — owner/status: owner_status; its table details list contains ordered O<n>/E<n> definitions. No later prose rewrite may change those values. Fail before output if durable table and items disagree, compact pointer or detail symbol is missing or changed, expanded source detail is missing, omitted_source_records_total is nonzero, source counts disagree, final table omits or changes item, counts fail to account for every row, or any row lacks disposition. CODE_REMEDIATE_METADATA.final_resolution_table.required_columns lists input item, item name, item type, sources, triage status, resolution, owner/status, resolved how, evidence.
Closure evidence for report-origin obligation must match type:
- independent review: independent specialist/maintainer output path plus updated metadata proving independence, or unavailable rationale
- full gates: clean full-gate/CI result path, or workspace/environment-prevented rationale
- type/lint/test environment: installed-environment command log, or missing executable/dependency rationale
- confidence gap: closing evidence, or explicit unresolved/deferred record
After table, keep expanded item record for every remediation item:
- finding id or source location
- severity
- source and fetched evidence path
- every contributing
report|online source ID, location, complete body, and evidence path
- PR/diff relation and evidence
- summary
- exact affected files
- expected closure evidence
- triage status:
valid|resolved|duplicate|stale|out-of-scope|already-fixed|already-applied|needs-clarification
- resolution:
implemented|resolved|rejected|stale|not-applicable|duplicate|already-fixed|already-applied|needs-clarification|unresolved
- owner/status:
todo|fixed|resolved|deferred|unresolved
- unresolved rationale, when applicable
For ambiguous finding/thread/comment, inspect referenced local/checked-out code; sharpen to action item or needs-clarification before edits. If fetched PR evidence marks comment/thread resolved, table it as triage/resolution resolved, cite fetched evidence, state current PR marks it resolved; do not create implementation follow-up. If requested change already exists locally, mark triage/resolution already-applied, cite code evidence, no follow-up. Never fix duplicate, stale, out-of-scope, already-fixed, already-applied, or resolved comments; record triage evidence.
05: Ask For Resolution Scope Before Editing
Before code changes, build <run-directory>/resolution-scope.md with ## Resolution Scope Selection. Selectable list includes every non-closed work-requiring finding; omits fetched online PR comments/threads currently resolved. Omit resolved online PR items from selection; keep them in action-items.md only as non-selectable audit rows, selection index -; omit-resolved-online rule.
Write <run-directory>/selection.json before prompting or accepting explicit scope: schema_version=1, selected_indexes=null while awaiting input, and items in stable ledger order. Each item copies input_item_id, item_name, item_type, severity, selectable, and complete ordered sources from normalized ledger, plus nonempty summary and closure_evidence. Classify report-origin non-code gate/follow-up obligations as review-gate or confidence-gap; intake counts derive from these types, not words in titles. Include nonselectable items for identity/count reconciliation; only selectable items appear as choices. A confirmed selection is list of numeric selection indexes, not finding IDs. No-selectable uses [] without pretending user selected anything.
Report identity defaults to its source file path, so different reports may reuse finding IDs. When different files are verified views of same report, give their sources same explicit report_id; do not use shared directory as identity. Selection input/output must be distinct files; output symlinks and aliases are rejected before writing.
Set selection.json.presentation_version=3 and add a short, concrete resolution_proposal to each selectable item. Inspect python PLUGIN_ROOT/shared/final_handoff.py selection --help, then run its selection action with --input <run-directory>/selection.json --out-scope <run-directory>/resolution-scope.md. Failure blocks the prompt and edits. The helper validates unique item/source/canonical-finding ownership and any declared totals before writing. It renders # | Severity | Finding | Resolution proposal | Sources. Sources are derived tags such as report ×1; online ×2, counting genuine source records only; never fill the overview with paths, IDs, bodies or repeated mentions. Each ID-only detail group adds Context, Done when, and every genuine evidence reference once. Use Finding for the named problem, not a synonymous Issue label; context explains the failure without repeating title/proposal. Related mentions are labeled separately. Historical presentations retain their original rendering.
Before selection, say Awaiting selection; never imply pending findings were deliberately deferred. After explicit choice, update selected_indexes, rerun helper, and record CODE_REMEDIATE_METADATA.resolution_scope.presentation_version=3, matching selection.json. Final validation checks exact rendered bytes, confirmed/deferred indexes and unchanged item/source inventory. Preserve version-2 and legacy scope validation for historical runs.
Selectable items:
- include triage
valid
- include
needs-clarification only when next step is clarification/code inspection, not implementation
- include report-origin failed checks, follow-ups, required next work, confidence gaps, residual risks unless cited evidence closes them
- include PR/review items related to PR intent, changed diff, adjacent verification, unknown relation unless cited evidence closes them
- exclude triage/resolution
resolved, duplicate, stale, out-of-scope, already-fixed, already-applied
- exclude fetched online PR comments/threads marked resolved in current PR evidence
Terminal Scope Context Contract
Before accepting explicit scope or prompting for one, complete pre-edit <run-directory>/resolution-scope.md document. It must contain, in this order:
## Resolution Scope Selection.
- Helper-derived pending/confirmed state and actual item/source counts. Keep selection source, exact prompt or explicit-input note, confirmation, severity groups and resolved-online omission counts in
CODE_REMEDIATE_METADATA.resolution_scope and durable ledger, not hand-edited generated Markdown.
- The complete short selection table, followed by visually separated ID-only detail group for every selectable item. Do not abbreviate supporting context, closure evidence or genuine source references; do not repeat table's finding name or proposal.
For omitted remediation_scope, record pending state before prompting: selection source: user-prompt, exact prompt below, user selection confirmed before editing: false, and no selected indexes or severity groups. Retain resolved online items as nonselectable inventory entries and documented omitted count; do not add them to choice table.
Read the complete <run-directory>/resolution-scope.md through the filesystem tool and render it unabridged before any scope prompt or edits. Immediately append Full report: <run-directory>/action-items.md; do not use shell output or a persisted path variable to assemble this context.
The Full report path must appear immediately after unabridged scope context and target <run-directory>/action-items.md, complete normalized resolution report. The link supplements scope context; do not replace context with a Selectable items: summary, shortened numbered list, artifact link, or ellipsis. The rendered table must let user choose from full item id/source, severity, summary, and closure evidence without opening another file.
Immediately after the terminal command returns, emit exactly one user-visible assistant message containing, in order, the exact unabridged resolution-scope.md content, Full report: <action-items.md path>, and this question with its choices:
Which findings should I remediate?
- all
- severity group: critical, high, medium, low, or comma-separated groups such as critical,high
- indexes: comma-separated indexes or ranges such as 1,3,5-7
A terminal/tool rendering alone never satisfies this interaction: collapsed output, Read resolution-scope.md summaries, status messages, artifact links without the ledger, and announcements that the ledger is rendering do not expose selectable options. Do not open a second scope-selection control after the combined user-visible message; that would duplicate the question and split its choices from their context.
If remediation_scope supplied, it is user selection: apply without re-asking; still write and print complete <run-directory>/resolution-scope.md before edits, but omit question and choices from user-visible message. If omitted and selectable items exist, stop before edits and ask exactly once with combined message above. Never infer all, silently select only code-editable items, or use default selection. If runtime cannot ask at all, fail scope-selection-required before edit. If none selectable, write and print none-selectable, skip implementation, continue gates/artifact.
Record in durable ledger and CODE_REMEDIATE_METADATA.resolution_scope; do not hand-edit generated resolution-scope.md:
- selection source:
explicit-input, user-prompt, or none-selectable
- prompt presented
- user selection confirmed before editing
- selected indexes/severity groups
- omitted resolved-online count
- deferred/unselected indexes
- unselected critical/high findings
Validate before edit:
all selects every selectable item
- severity group selects every selectable matching severity
- indexes select only selectable rows
- invalid index or attempt to select omitted/resolved item => fail before editing
- sel
…(truncated)
1---2name: code-remediate3description: Apply selected review fixes; bare PR targets use current online items, while PR +review adds the latest matching artifact.4---56# Code Remediate78See the [fixed recurrence and root-cause policy](../../shared/native-skill-contract.md#recurrence-and-root-cause-policy) and [reasoning-progress escalation policy](../../shared/native-skill-contract.md#reasoning-progress-escalation) for repeated-obstacle handling; record and validate `reasoning-progress.json` before another cycle after escalation trigger.910Run linear code remediation to close findings.1112## Input Schema1314```json15{16 "findings_source": "optional path, explicit list, review for the current-session assessed review, or +review/+report/report/latest to auto-select the newest matching PR review report; omit with a bare PR target to use current online review items",17 "mode": "optional report|pr|auto; infer pr for bare number, #number, or PR URL",18 "target": "optional shorthand target number, issue/PR URL, path, or current branch",19 "pr_target": "optional PR number, PR URL, or current branch PR when mode=pr",20 "remediation_scope": "optional all|critical|high|medium|low|comma-separated severities|comma-separated selection indexes; ask before editing when omitted",21 "target_scope": "required path/module",22 "done_when": "selected findings are fixed/resolved and unselected critical/high findings are explicitly deferred"23}24```2526## Workflow (Exact Commands)2728### 01: Create Run Directory2930Run `create_run.py --skill code-remediate` per `../../shared/helper-cli-contract.md`.3132### 02: Normalize input and optional report findings3334Shorthand rules:3536- Canonical in-session report: `$code-remediate review` => `mode=report`, `REQUESTED_REPORT=true`, `FINDINGS_SOURCE=latest-assessed-current-session-review`. It resolves to the latest assessed `code-review` result created in the current session. Reuse the exact prior artifact path recorded in this session; do not scan reports or infer a PR target. Do not collect PR evidence or fetch online review comments. If no assessed current-session review result is available, fail with `current-session-review-report-required` and instruct the user to run `$code-review <target>` first or supply a report path.37- Canonical online-only PR: `$code-remediate #123` => `mode=pr`, `PR_TARGET=123`, `REQUESTED_REPORT=false`, `FINDINGS_SOURCE=none`. Accepted bare PR forms are: bare number, `#number`, PR URL, and natural-language bare PR targets; they collect current online items and verified local checkout without a prior review report.38- Natural-language online-only aliases: `remediate 123`, `remediate #123`, `remediate PR 123`, and `remediate <github-pr-url>` use same bare-PR route.39- Canonical report-backed PR: `$code-remediate #123 +review` => `mode=pr`, `PR_TARGET=123`, `REQUESTED_REPORT=true`, `FINDINGS_SOURCE=latest-matching-review-report`.40- `matching-review-incomplete:<run-directory>` means identified review retained notes but never produced promoted result or candidate. First explain in plain English that preliminary evidence exists but review did not complete; then state `Review handoff blocked`, link that retained run, and name exact failed checkpoint with evidence-backed next action. Return to producer completion checkpoint and perform permitted diagnosis yourself; do not claim no review was performed, consume notes as validated result, select older verdict, or switch to online-only intake. This applies across sessions as well as within one session. A newer malformed result similarly blocks stale assessed fallback.41- Compatibility alias: `$code-remediate #123 +report` => `mode=pr`, `PR_TARGET=123`, `REQUESTED_REPORT=true`, `FINDINGS_SOURCE=latest-matching-review-report`; `$code-remediate #123 +report compatibility alias` has same report lookup.42- Natural-language aliases: `remediate 123 report`, `remediate #123 report`, and `remediate PR 123 report` => `mode=pr`, `PR_TARGET=123`, `REQUESTED_REPORT=true`, `FINDINGS_SOURCE=latest-matching-review-report`.43- `remediate <github-pr-url> report` => `mode=pr`, `PR_TARGET=<github-pr-url>`, `REQUESTED_REPORT=true`, `FINDINGS_SOURCE=latest-matching-review-report`.44- An explicit review result path combined with PR target sets `REQUESTED_REPORT=true`; bare PR target has no implicit report path.45- Bare PR and report-backed PR routing are distinct: explicit `+review`, `+report`, report aliases, and report paths retain report-plus-online behavior; absence of report source selects online-only intake and never falls back to report lookup.46- If `+review`, `+report`, `report`, `latest`, `latest-report`, or `review-report` replaces path, find newest matching result across canonical `.reports/codex/code-review/pr-<number>/run-<NNN>/result.json` and legacy flat `.reports/codex/code-review/<timestamp>/result.json` artifacts whose sibling `pr.json` has same PR number/URL as `PR_TARGET`.47- When `REQUESTED_REPORT=true`, no matching code-review report means the requested assessed findings are missing. Explain that first, then ask for an existing report path or permission to run `$code-review <target>` if not already authorized. A `matching-review-unavailable-rerun-code-review` result means PR collection failed before any assessed review; do not use it as findings input. Inspect that run's classified error and retained checkout diagnostics, perform permitted recovery, and rerun collection only when the diagnosed cause or external state supports it; ask only for the specific missing access or decision. A `matching-review-closed-not-remediable` result is a terminal close disposition with no source findings; do not remediate it or fall back to an older assessed report. A `matching-review-candidate-unpromoted:<path>` result requires the bounded same-session recovery below; do not fall back to an older assessed report.48- When canonical matching PR runs exist, select greatest parsed numeric `run-<NNN>` index. Otherwise select greatest parsed legacy flat timestamp. Never rely on lexical glob order, modification time, or directory traversal order; record selected path in `<run-directory>/findings-input.txt`.4950When `FINDINGS_SOURCE=latest-matching-review-report`, inspect `python PLUGIN_ROOT/shared/find-review-report.py --help`, resolve `PR_TARGET` against `.reports/codex/code-review`, and assign printed path to `FINDINGS_SOURCE`. The helper searches explicit canonical nested PR runs plus legacy flat timestamped runs; no migration is required. It filters explicit `review_status=unavailable` diagnostics, so older assessed review remains eligible when newer collection failure exists. A newer `review_status=closed` result instead blocks older findings because close disposition is current and non-remediable. Before accepting explicit review result path as findings input, invoke same helper with `--result <path>`; it rejects unavailable results with rerun instruction, closed results with `matching-review-closed-not-remediable`, and candidate paths with `matching-review-candidate-unpromoted:<path>`. A bare PR target must not run this helper, scan prior review reports, or require a `code-review` artifact.5152For `matching-review-candidate-unpromoted:<path>`, recover only when the candidate's `specialist-manifest.json` names the same parent thread as the current remediation session. Run the review-specific validator, then the shared validator, against that exact candidate and its review run directory; promote it to `result.json` only after both validators pass, then rerun the finder and use the promoted result. Never consume `result.candidate.json` directly. If either validator fails, persist its exact stderr code in `<run-directory>/review-candidate-validation.txt`, including `manifest-invalid-attempt-count:<role>` when applicable, and return to the code-review manifest preflight checkpoint for one evidence-preserving repair from retained specialist and rollout records. Never invent missing attempt provenance or retry a specialist for artifact bookkeeping. After a repaired manifest passes `--manifest-only`, rerender/rewrite the candidate as required and retry both validators once. If exact evidence cannot repair the run or either validator still fails, do not promote the candidate, rerun the full review, or fall back to an older assessed report; stop with the exact error and candidate path. This recovery has no waiting loop and makes no remote mutation.5354When `FINDINGS_SOURCE` exists, copy its exact bytes to `<run-directory>/findings-input.txt` with filesystem tool. Do not depend on shell variable retaining that source path. For bare PR online-only intake, do not create `<run-directory>/findings-input.txt`; set `CODE_REMEDIATE_METADATA.review_report_intake.requested_report=false` and every report-item counter to `0`.5556For `mode=pr`, inspect `python PLUGIN_ROOT/shared/collect_pr.py --help`; collect `PR_TARGET` into `<run-directory>/pr` with checkout enabled for current online evidence, target/head refresh, local checkout.5758In runtimes with network sandboxing, execute the complete collector command with approved external network access from its first attempt under `../../shared/native-skill-contract.md`. Before requesting it, state:5960- `Action and purpose`: collect current PR evidence before remediation.61- `External capability`: read-only GitHub access plus documented local checkout.62- `Credential behavior`: `gh` is opaque local credential broker.63- `Filesystem and worktree effects`: write collection artifacts and may update local checkout.64- `Retry policy and safe denial outcome`: one classified recovery only, otherwise remediation uses its core collection-failure path.65- For Codex exec, set `sandbox_permissions="require_escalated"` on the collector with a narrow read-only GitHub justification; never request a broad `python` approval prefix. Apply the other shared runtime and denial boundaries. A direct approval for `gh pr view` does not cover `gh` spawned by the collector: the outer collector command owns its nested GitHub CLI, HTTPS fallback, checkout, and Git fetch traffic. The PR request authorizes asking, never bypassing runtime approval.66- If an agent-caused unapproved attempt returns `github-network` before any user approval request or denial, rerun that same complete collector command once through the runtime's external-network approval mechanism before treating collection as terminal. This recovery exists only for that pre-denial sandbox mistake; after the user denies approval, the current turn stops and the retry is forbidden. Only after that approved collector attempt fails, external-network approval is unavailable, or the user denies it may remediation apply its core collection-failure path; never repeat more than one approved recovery attempt.6768`github_read.py` is plugin-wide GitHub data boundary: do not invoke `gh` outside it.6970- It uses `gh` as opaque local credential broker, never invokes `gh auth`, reads token/keychain state, or persists GitHub CLI failure output.71- It permits only audited built-in view groups (`gist`, `issue`, `pr`, `project`, `release`, `repo`, `ruleset`, `run`, `workflow`), REST GET, and GraphQL queries; no remote mutation is permitted.72- Its public HTTPS fallback cannot establish private PR evidence.7374Core and supplemental evidence:7576- `collect_pr.py` treats PR identity/body plus exact local source as core evidence: it uses numbered fork-aware `gh pr checkout <number>` when needed, verifies PR head SHA, and derives `diff.patch` locally. Its `worktree-preflight.json` permits unrelated tracked edits and blocks only paths checkout would overwrite.77- GraphQL review-thread resolution status is supplemental; if unavailable, collector writes empty normalized thread arrays plus `review-threads-error.txt` and continues.78- Record that online-triage coverage gap in `action-items.md`, result confidence gaps, and unresolved/deferred closure rationale; never treat it as code finding or silently claim complete thread triage.79- On core collection failure, use `<run-directory>/pr/pr-error.txt`, `<run-directory>/pr/worktree-preflight.json`, and `<run-directory>/pr/command-failure.json` when present to distinguish classified process failure from source-review findings; for dirty-worktree overlap, name exact `overlapping_paths` first; do not treat it as merge recommendation.8081When `gh pr view` metadata fails, public unauthenticated HTTPS fallback is eligible only when all of these hold:8283- The failure is `github-network`, `github-auth`, `github-rate-limit`, or `command-timeout`.84- The checkout target is trusted: canonical PR URL must match configured GitHub remote; numeric target requires exactly one distinct configured GitHub repository identity.8586Ambiguous or unsafe targets, permission failures, not-found failures, and unclassified failures remain fail-closed.8788Fallback behavior:8990- The fallback normalizes limited PR metadata, then uses verified `refs/pull/<number>/head` ref for detached checkout and derives local diff; it never establishes private PR evidence.91- `online-review-summary.json` must list unavailable fallback evidence as sorted IDs.92- Raw GitHub CLI stderr is never persisted; terminal diagnostics may include safe `failure_reason` enum alongside non-secret classification metadata.9394Findings intake:9596- For `mode=report`, normalize only the review report after confirming it is assessed. Reject `review_status=unavailable` and `review_status=closed`; the latter is a close disposition without source findings. Do not read, collect, or infer any `<run-directory>/pr/` evidence.97- For `mode=pr`, always normalize `<run-directory>/pr/comments.json`, `<run-directory>/pr/reviews.json`, `<run-directory>/pr/review-threads.json`, and `<run-directory>/pr/unresolved-review-threads.json`.98 - When `REQUESTED_REPORT=false`, those current online records are complete findings source. Do not read or infer review report, and do not require prior assessed artifact. If no online item is actionable after triage, continue through documented `none-selectable` path instead of requesting `code-review`.99 - When `REQUESTED_REPORT=true`, additionally normalize `<run-directory>/findings-input.txt`. Treat review report as closure contract, not only code findings: before editing normalize report findings, failed `checks_failed`, `follow_up`, `review_decision.required_next_work`, confidence gaps, confidence-recovery remaining limits, and no-finding residual risks into report-origin action items.100 - Use local checkout in `<run-directory>/pr/local-checkout.json` as authoritative source for code triage/edits and require its `verified-local-checkout` diff provenance.101 - Refresh both target and PR head yourself before conflict/review-item resolution; `<run-directory>/pr/target-branch.json` and `<run-directory>/pr/pr-head-fetch.json` must record fetched tips, including fork PRs. The primary checkout remains `gh pr checkout <number>`; preliminary fork pull-ref fetch makes its commit available for safe checkout comparison. Routine freshness is agent-owned work, not request for user to pull branches. Use fetched target ref directly; separate local target checkout is unnecessary.102 - Checkout artifacts include `force_policy`; if checkout fails or does not match PR head, record `forced-checkout-not-attempted`. Inspect classified failure, retained command/checkout diagnostics, and current branch/head yourself; continue permitted safe recovery, stopping only before forced retry, loss of user changes, unavailable access, or unresolved identity. If fresh fetched evidence proves PR moved, recollect metadata once and verify rebuilt bundle under existing authorization. Report actual expected/observed IDs and next action, never generic "repair checkout" instructions.103 - If core metadata, target refresh, checkout, or local diff fails, record failure; continue with supplied report only when user accepts stale online-review coverage and no code edits are required, else fail.104 - If only supplemental review-thread resolution status is unavailable, continue with explicit partial-coverage evidence and do not infer that any thread is resolved.105 - Never inspect/edit PR code from `curl`, `raw.githubusercontent.com`, or copied `head-files/` snapshots; raw-file snapshot rejection: snapshots are rejected.106107### 03: Understand PR Intent, Then Resolve Merge Conflicts108109For `mode=pr`, required before `action-items.md`, `resolution-scope.md`, or report/PR-review code changes. Establish clean PR and latest target implementation before conflict markers make worktree noisy.110111Read `remote_ref` from `<run-directory>/pr/target-branch.json` with JSON parser and retain exact printed value as `<base-remote-ref>`. Run `git merge-base HEAD <base-remote-ref>` as argv, retain its single printed value as `<merge-base>`, and write that value to `<run-directory>/pr/merge-base.txt`. Run these argv commands separately and write stdout to named artifacts:112113- `git diff --stat <merge-base>..HEAD` → `<run-directory>/pr/pr-intent.diffstat`114- `git diff --name-only <merge-base>..HEAD` → `<run-directory>/pr/pr-intent-files.txt`115- `git diff --stat <merge-base>..<base-remote-ref>` → `<run-directory>/pr/target-since-merge-base.diffstat`116- `git merge-tree <merge-base> HEAD <base-remote-ref>` → `<run-directory>/pr/merge-tree.txt`117118Record each command's exit status; unavailable evidence is gap, never implied clean result.119120Write `<run-directory>/merge-prestage.md` sections before attempting merge:121122- `## PR And Target Refresh`: PR number/head, target branch, fetched target hash, local checkout hash, evidence paths.123- `## Clean PR Implementation Context`: intended change, changed files, key invariants, clean-PR-implied tests/docs.124- `## Target Branch Context`: relevant fetched-target details, especially likely collision files.125- `## Conflict Risk`: mergeability, `merge-tree` signal, both-side changed files, conflicts present/likely/absent.126- `## Resolution Strategy`: reconcile PR intent and target implementation for each conflict/likely collision before review/report findings.127- `## Merge Execution`: conflict decision, authorization state, merge command/status, resolved paths, verification, and evidence path.128129Write `<run-directory>/pr/merge-resolution.json` with `schema_version`, `conflicts_detected`, `status`, `authorization`, `base_remote_ref`, `target_oid`, `pre_merge_head`, `post_merge_head`, `merge_commit`, `resolved_paths`, `unmerged_paths`, and `evidence`. Use `status=not-needed` and `authorization=not-required` when fresh evidence proves no conflict. Do not merge target merely to refresh conflict-free PR.130131If conflicts are present or likely, resolve them as PR integration before normalizing or addressing any report/online-review item:1321331. Use already-recorded clean PR purpose, invariants, target changes, and per-file resolution strategy as primary context. Inspect `git show <base-remote-ref>:<path>` and nearby tests where needed; conflict markers are secondary evidence only.1342. A generic remediation request does not authorize local merge commit. Show target ref/OID, intended merge, collision files, resolution strategy, and overwrite/commit effect. Ask for explicit authorization to create local target-merge commit: `Authorize this local merge and commit? (yes / no)`. Ask only when that exact action is not already authorized. A `no` leaves the merge unapproved. Record `authorization=explicit-input|user-confirmed`; if authorization is absent or runtime cannot ask, stop with `target-merge-authorization-required` before review-item work.1353. After authorization, run `git merge --no-commit --no-ff <base-remote-ref>` with retained literal ref. Never rebase, force checkout, or rewrite history as substitute.1364. Resolve only merge collisions, preserving recorded PR intent atop fetched target implementation. Do not combine review-comment fixes unless same lines cannot otherwise form coherent merge; record unavoidable coupling in `<run-directory>/closure-log.md`.1375. Verify `git diff --name-only --diff-filter=U` is empty, run smallest collision-relevant tests, then create authorized merge commit using `../../shared/commit-response-template.md` and required `Co-authored-by: Codex <codex@openai.com>` trailer. Record pre/post HEAD, merge commit, resolved paths, tests, and empty unmerged-path list in `merge-resolution.json` and `## Merge Execution`.138139Do not create `action-items.md`, `resolution-scope.md`, or edit for report/online-review finding until `merge-resolution.json` is `not-needed` or `completed`, worktree has no unmerged paths, and no merge is in progress. If merge resolution or its verification fails, stop; do not hide conflict behind finding remediation.140141If checkout starts dirty, conflicted, or partially merged, fail or ask cleanup before editing. Never use existing conflicted worktree as primary truth.142143### 04: Normalize Findings Before Editing144145**Structural context (optional)**: when `target_scope` names Python module, also probe codemap-py once for changed-symbol/caller impact: `python PLUGIN_ROOT/shared/codemap_adapter.py context --category review [--target <qname>] --out <run-directory>/codemap-context.json`. Per `../../shared/codemap-contract.md`, absence/incompatibility is non-fatal — continue normalizing available report and/or online findings evidence. Persist result once here; specialist owners assigned in step 06 receive `<run-directory>/codemap-context.json` in their context pack, never fresh query.146147Write `<run-directory>/action-items.md` starting with `## Review Item Resolution Table`, before prose. Normalize by canonical obligation, not by each report mention. For structured reviews, consume each `review_findings` record once using `report [<report-json>#<finding-id>]`; copy its title, summary, required change, evidence and closure evidence. Historical ID/severity-only or Markdown reviews remain readable: identify one primary finding/action record and attach other views of that same finding as `related_mentions`, never independent source records. Consolidate only matching canonical finding IDs within one report or independently evidenced same obligation; shared closure text, test command or source location alone never justifies merging distinct findings. A genuinely independent gate or confidence obligation remains separate item. Do not weaken report validation or certify historical failed results.148149Every source has one owning item. Preserve genuinely independent report and fresh-online evidence with exact references, bodies and evidence paths. An online comment already attached to finding must not also be ingested as second duplicate row; record its duplicate/corroborating relationship in owning item's expanded record. Multiple different sources for same obligation may share item; never drop provenance. Each report source carries `finding_id` when known; optional `related_mentions` retains repeated summary/action/confidence locations without increasing source counts. Render primary sources as `report [<report-file>:<line>]`, `report [<report-json>#<finding-id>]`, or `online [<comment|thread|review-id>]`. Keep full source records in metadata and expanded item records: category, stable source ID, location or `general`, complete body, evidence path or `report-only`. No counts, representative sources, ellipses or artifact links may replace required evidence. Before asking for selection, run executable inventory gate in step 05; handwritten counts are not acceptance evidence.150151When `online-review-summary.json` reports `pr_metadata_transport=public-https-fallback`, list sorted `unavailable_evidence` IDs `github_provided_file_list`, `mergeability`, `review_decision`, `reviews`, and `top_level_comments` in `action-items.md` and online action evidence, and add exact confidence gap `Public HTTPS PR metadata fallback omitted evidence: <sorted IDs>.` Substitute that sorted list into `<sorted IDs>`. The final remediation confidence is capped at `0.89`; carry gap and its closure state through `action-items.md`, result metadata, and unresolved/deferred evidence.152153For `mode=pr`, check every report/PR-review item against PR intent and changed diff before triage:154155- `direct-diff`: references PR-changed file/hunk/behavior.156- `pr-intent`: connects to PR purpose, acceptance criteria, review decision, requested change, even outside touched hunk.157- `adjacent`: touches nearby code/tests/docs/config/verification needed for safe merge.158- `unknown`: current evidence cannot determine relation.159- `unrelated`: no connection to PR intent, changed files, adjacent verification, or merge readiness after local PR-context inspection.160161Write relation in action table and every expanded item. `direct-diff`, `pr-intent`, `adjacent`, `unknown` are never `out-of-scope`; keep `valid`/`needs-clarification` and selectable unless `resolved`, `already-fixed`, or `already-applied` evidence closes them. If current PR cannot close one, record `unresolved`, `deferred`, or required follow-up; never downgrade to `out-of-scope`. User can select, defer, or explicitly rule it into PR.162163When `REQUESTED_REPORT=true`, include non-code report-origin review obligations:164165- failed `checks_failed`, including missing independence, full gates, lint, type, test, confidence gates166- `follow_up`, especially `needs-independent-review`167- `review_decision.required_next_work` and merge/readiness blockers168- confidence gaps, confidence-recovery remaining limits, no-finding residual risks blocking acceptance169170Report-origin obligations default in scope for `+review`, `+report`, `report`, or review-report path. Never mark `out-of-scope` merely because closure needs independent reviewer, installed tool, CI/full-gate run, or unavailable local environment. Mark `valid`/`needs-clarification`, keep selectable, leave `unresolved`/user-deferred until closure evidence. `out-of-scope` only for item proven unrelated to requested report/PR/target after citing evidence; never use it to silence failed gates/follow-up.171172After resolution table, add `## Review Report Intake`: whether report was requested, total report-origin items, report-origin review-gate/follow-up items, selectable review-gate/follow-up items, and report-origin `out-of-scope` count. When `REQUESTED_REPORT=false`, record `requested report: false` and `0` for every report count. The `out-of-scope` count must be `0` unless item is proven unrelated to requested report/PR/target.173174Required table columns:175176- selection index: numeric selectable; `-` non-selectable177- input item: stable input row id, report id, PR comment id, review id, thread id, source location178- item name: short human-readable finding/review obligation/gate/comment/thread name179- item type: `code|test|docs|review-gate|confidence-gap|pr-comment|pr-review|pr-thread|unresolved-pr-thread|ci|typing|lint|security|performance|process|other`180- sources: ordered compact unique pointers rendered as `report [<report-file>:<line>]`, `report [<report-json>#<finding-id>]`, or `online [<comment|thread|review-id>]`; join multiple records with one plain ASCII space and never append locations, bodies, evidence paths, resolutions, summaries, or online URLs181- item id or source location182- source category: `report|online`; `online` covers PR comments, reviews, threads, and unresolved threads while item type preserves detailed online subtype183- fetched evidence path, or `report-only`184- PR/diff relation: `direct-diff|pr-intent|adjacent|unknown|unrelated`185- severity186- summary187- triage status: `valid|resolved|duplicate|stale|out-of-scope|already-fixed|already-applied|needs-clarification`188- resolution: `implemented|resolved|rejected|stale|not-applicable|duplicate|already-fixed|already-applied|needs-clarification|unresolved`189- owner/status: `todo|fixed|resolved|deferred|unresolved|not-selected|not-actionable`190- resolved how: `[O<row-position>]`; immediately below table define `[O<row-position>] <how/why resolved/unresolved/deferred/not applicable>`191- evidence: closure evidence or unresolved rationale as `[E<row-position>]`; immediately below table define `[E<row-position>] <complete evidence, unresolved rationale, owner action, or next action>`192193After table add `## Final Resolution Summary`:194195- what was requested196- ingested entries total197- resolved or already-closed entries total198- implemented entries total199- unresolved entries total200- deferred/not-selected entries total201- not-applicable/stale/duplicate/rejected entries total202- one sentence: all selected local actionable items closed or not203204Then add `## Final Resolution Table Completeness`:205206- ingested entries total207- final table rows total208- omitted entries total: must be `0`209- selectable/non-selectable row totals210- triage status counts211- resolution status counts212- source records total213- represented source records total214- omitted source records total: must be `0`215- grouped items total216217`CODE_REMEDIATE_METADATA.final_resolution_table` has same item and source counts plus `items`, ordered machine-readable source for durable and final-chat tables. Each item contains non-empty `input_item_id`, `item_name`, `item_type`, `severity`, `triage_status`, `resolution_status`, `owner_status`, `resolved_how`, and `evidence`, plus boolean `selectable` and non-empty ordered `sources` list. Each source contains `kind=report|online`, `source_id`, `location`, `body`, and `evidence`; `(kind, source_id)` is unique across items. A report `source_id` is `<report-file>:<line>` or `<report-json>#<finding-id>`; online `source_id` is its stable comment, thread, or review ID, never URL. Preserve source order, full bodies, and unique IDs. Render the `Review Item Resolution Table` and `Final Outcome Table` from this list. Their `Sources` cells contain only ordered compact pointers; full source records remain in metadata and expanded item records. The durable table uses `[O<n>]` and `[E<n>]` cells and defines their complete `resolved_how` and `evidence` text immediately below table. The final handoff maps cells mechanically as `input_item_id`, `severity`, `item_name`, every compact source reference joined in source order, `resolution_status — [O<n>]`, and `[E<n>] — owner/status: owner_status`; its table `details` list contains ordered `O<n>`/`E<n>` definitions. No later prose rewrite may change those values. Fail before output if durable table and items disagree, compact pointer or detail symbol is missing or changed, expanded source detail is missing, `omitted_source_records_total` is nonzero, source counts disagree, final table omits or changes item, counts fail to account for every row, or any row lacks disposition. `CODE_REMEDIATE_METADATA.final_resolution_table.required_columns` lists `input item`, `item name`, `item type`, `sources`, `triage status`, `resolution`, `owner/status`, `resolved how`, `evidence`.218219Closure evidence for report-origin obligation must match type:220221- independent review: independent specialist/maintainer output path plus updated metadata proving independence, or unavailable rationale222- full gates: clean full-gate/CI result path, or workspace/environment-prevented rationale223- type/lint/test environment: installed-environment command log, or missing executable/dependency rationale224- confidence gap: closing evidence, or explicit unresolved/deferred record225226After table, keep expanded item record for every remediation item:227228- finding id or source location229- severity230- source and fetched evidence path231- every contributing `report|online` source ID, location, complete body, and evidence path232- PR/diff relation and evidence233- summary234- exact affected files235- expected closure evidence236- triage status: `valid|resolved|duplicate|stale|out-of-scope|already-fixed|already-applied|needs-clarification`237- resolution: `implemented|resolved|rejected|stale|not-applicable|duplicate|already-fixed|already-applied|needs-clarification|unresolved`238- owner/status: `todo|fixed|resolved|deferred|unresolved`239- unresolved rationale, when applicable240241For ambiguous finding/thread/comment, inspect referenced local/checked-out code; sharpen to action item or `needs-clarification` before edits. If fetched PR evidence marks comment/thread resolved, table it as triage/resolution `resolved`, cite fetched evidence, state current PR marks it resolved; do not create implementation follow-up. If requested change already exists locally, mark triage/resolution `already-applied`, cite code evidence, no follow-up. Never fix duplicate, stale, out-of-scope, already-fixed, already-applied, or resolved comments; record triage evidence.242243### 05: Ask For Resolution Scope Before Editing244245Before code changes, build `<run-directory>/resolution-scope.md` with `## Resolution Scope Selection`. Selectable list includes every non-closed work-requiring finding; omits fetched online PR comments/threads currently resolved. Omit resolved online PR items from selection; keep them in `action-items.md` only as non-selectable audit rows, selection index `-`; omit-resolved-online rule.246247Write `<run-directory>/selection.json` before prompting or accepting explicit scope: `schema_version=1`, `selected_indexes=null` while awaiting input, and `items` in stable ledger order. Each item copies `input_item_id`, `item_name`, `item_type`, `severity`, `selectable`, and complete ordered `sources` from normalized ledger, plus nonempty `summary` and `closure_evidence`. Classify report-origin non-code gate/follow-up obligations as `review-gate` or `confidence-gap`; intake counts derive from these types, not words in titles. Include nonselectable items for identity/count reconciliation; only selectable items appear as choices. A confirmed selection is list of numeric selection indexes, not finding IDs. No-selectable uses `[]` without pretending user selected anything.248249Report identity defaults to its source file path, so different reports may reuse finding IDs. When different files are verified views of same report, give their sources same explicit `report_id`; do not use shared directory as identity. Selection input/output must be distinct files; output symlinks and aliases are rejected before writing.250251Set `selection.json.presentation_version=3` and add a short, concrete `resolution_proposal` to each selectable item. Inspect `python PLUGIN_ROOT/shared/final_handoff.py selection --help`, then run its `selection` action with `--input <run-directory>/selection.json --out-scope <run-directory>/resolution-scope.md`. Failure blocks the prompt and edits. The helper validates unique item/source/canonical-finding ownership and any declared totals before writing. It renders `# | Severity | Finding | Resolution proposal | Sources`. Sources are derived tags such as `report ×1; online ×2`, counting genuine source records only; never fill the overview with paths, IDs, bodies or repeated mentions. Each ID-only detail group adds `Context`, `Done when`, and every genuine evidence reference once. Use Finding for the named problem, not a synonymous Issue label; context explains the failure without repeating title/proposal. Related mentions are labeled separately. Historical presentations retain their original rendering.252253Before selection, say `Awaiting selection`; never imply pending findings were deliberately deferred. After explicit choice, update `selected_indexes`, rerun helper, and record `CODE_REMEDIATE_METADATA.resolution_scope.presentation_version=3`, matching selection.json. Final validation checks exact rendered bytes, confirmed/deferred indexes and unchanged item/source inventory. Preserve version-2 and legacy scope validation for historical runs.254255Selectable items:256257- include triage `valid`258- include `needs-clarification` only when next step is clarification/code inspection, not implementation259- include report-origin failed checks, follow-ups, required next work, confidence gaps, residual risks unless cited evidence closes them260- include PR/review items related to PR intent, changed diff, adjacent verification, unknown relation unless cited evidence closes them261- exclude triage/resolution `resolved`, `duplicate`, `stale`, `out-of-scope`, `already-fixed`, `already-applied`262- exclude fetched online PR comments/threads marked resolved in current PR evidence263264### Terminal Scope Context Contract265266Before accepting explicit scope or prompting for one, complete pre-edit `<run-directory>/resolution-scope.md` document. It must contain, in this order:2672681. `## Resolution Scope Selection`.2692. Helper-derived pending/confirmed state and actual item/source counts. Keep selection source, exact prompt or explicit-input note, confirmation, severity groups and resolved-online omission counts in `CODE_REMEDIATE_METADATA.resolution_scope` and durable ledger, not hand-edited generated Markdown.2703. The complete short selection table, followed by visually separated ID-only detail group for every selectable item. Do not abbreviate supporting context, closure evidence or genuine source references; do not repeat table's finding name or proposal.271272For omitted `remediation_scope`, record pending state before prompting: `selection source: user-prompt`, exact prompt below, `user selection confirmed before editing: false`, and no selected indexes or severity groups. Retain resolved online items as nonselectable inventory entries and documented omitted count; do not add them to choice table.273274Read the complete `<run-directory>/resolution-scope.md` through the filesystem tool and render it unabridged before any scope prompt or edits. Immediately append `Full report: <run-directory>/action-items.md`; do not use shell output or a persisted path variable to assemble this context.275276The `Full report` path must appear immediately after unabridged scope context and target `<run-directory>/action-items.md`, complete normalized resolution report. The link supplements scope context; do not replace context with a `Selectable items:` summary, shortened numbered list, artifact link, or ellipsis. The rendered table must let user choose from full item id/source, severity, summary, and closure evidence without opening another file.277278Immediately after the terminal command returns, emit exactly one user-visible assistant message containing, in order, the exact unabridged `resolution-scope.md` content, `Full report: <action-items.md path>`, and this question with its choices:279280```text281Which findings should I remediate?282- all283- severity group: critical, high, medium, low, or comma-separated groups such as critical,high284- indexes: comma-separated indexes or ranges such as 1,3,5-7285```286287A terminal/tool rendering alone never satisfies this interaction: collapsed output, `Read resolution-scope.md` summaries, status messages, artifact links without the ledger, and announcements that the ledger is rendering do not expose selectable options. Do not open a second scope-selection control after the combined user-visible message; that would duplicate the question and split its choices from their context.288289If `remediation_scope` supplied, it is user selection: apply without re-asking; still write and print complete `<run-directory>/resolution-scope.md` before edits, but omit question and choices from user-visible message. If omitted and selectable items exist, stop before edits and ask exactly once with combined message above. Never infer `all`, silently select only code-editable items, or use default selection. If runtime cannot ask at all, fail `scope-selection-required` before edit. If none selectable, write and print `none-selectable`, skip implementation, continue gates/artifact.290291Record in durable ledger and `CODE_REMEDIATE_METADATA.resolution_scope`; do not hand-edit generated `resolution-scope.md`:292293- selection source: `explicit-input`, `user-prompt`, or `none-selectable`294- prompt presented295- user selection confirmed before editing296- selected indexes/severity groups297- omitted resolved-online count298- deferred/unselected indexes299- unselected critical/high findings300301Validate before edit:302303- `all` selects every selectable item304- severity group selects every selectable matching severity305- indexes select only selectable rows306- invalid index or attempt to select omitted/resolved item => fail before editing307- sel308309…(truncated)