Instruction file imported from kurone-kito/kurone-kito (
.github/instructions/idd-review-triage.instructions.md). Copyright stays with the author.
IDD — Review Triage Phase (E4–E8)
Read this file after idd-review-snapshot.instructions.md (E3) finds
ReviewItems_snapshot non-empty. Covers classifying, scoring, recording
dispositions, and counting accepted items.
Before posting any E-phase operational comment or GitHub reply, apply
the shared claim revalidation gate. The active claim must still use your
current {claim-id}.
Skip condition E8: if the Accepted PATH A count after verification
is zero, proceed to the E-phase branch-sync check below (its
no-sync-required clean/behind-no-conflict exit applies the
Zero-Accepted-PATH-A advisory re-review gate).
E4 — Classify and score ReviewItems_snapshot
Once per triage pass (not per item), read the claimed issue's own body
and note any explicit out-of-scope statement in it, trusted for the
scope fence below only if it predates the B2 plan
(idd-work.instructions.md) — an author keeps edit rights throughout
the claim and could otherwise time an edit to force-reject a legitimate
finding. Fetch userContentEdits (GraphQL; updatedAt also moves on
unrelated activity, so it will not do) and find the entry with the
latest editedAt at or before the plan's post time; that entry's
diff (or the original creation content, if none predates the plan)
is the trusted snapshot. A statement absent from it — added later, or
present now but not there — needs independent corroboration (a
maintainer comment, not another edit). Treat an unavailable or failed
userContentEdits read the same way: fail closed, never assume no
post-plan edit occurred.
For each item in ReviewItems_snapshot, first classify it:
- PATH A — actionable feedback: human reviewer threads and regular
comments,
CHANGES_REQUESTEDreview bodies, and critique-pass findings that require a code change or maintainer decision. - PATH B — advisory feedback: Copilot and CI advisory bot comments included by E1 for traceability, even when they do not require a code change.
- If classification is ambiguous, default to PATH A.
- Record each PATH A actor's permission standing (CODEOWNER, required reviewer, Triage/Write/Maintain/Admin, or none) — E5's cap reads it.
Advisory non-review notice. Before scoring a PATH B item, decide whether it is a completed advisory review of the current HEAD or an advisory non-review notice — an advisory bot comment reporting that it did not review the current HEAD: rate-limit / quota / credit-exhaustion warnings, queued / in-progress status, a bare request acknowledgement (e.g. CodeRabbit "Actions performed"), or an error / "temporarily unavailable" notice. A non-review notice carries no advisory result to score; handle it with the E6 non-review-notice rule instead of the normal PATH B disposition.
Then apply path-specific scoring:
- PATH A: assess severity/relevance to PR intent. High (safety, correctness, requirement violations, CI stability) → Accept forced, gated by "Verify before accept" and the actor-permission cap (E5); Low (minor, unrelated to PR intent) → Reject recommended; Medium → judge by context.
- PATH B: no High/Medium/Low. Score only a completed review of
current HEAD as
Accepted(confirmed/useful) orRejected(noted, no action) — route a non-review notice to E6 instead. - Scope fence (PATH A and PATH B). A finding that asks to
introduce, or further broaden, a change class the claimed issue's own
body explicitly places out of scope scores
Low(PATH A) orRejected(PATH B) and disposes Reject forced, regardless of technical correctness or tractability, from the point that class is introduced onward. A refinement or bug fix inside an already-introduced instance of that class is still in-scope work and scores normally. This fence overrides PATH A's High-tierAccept forcedrule: even a correctness finding that would introduce or broaden a fenced class does not reachAccept forcedmerely for being High-severity. Record a rejected instance as a known limitation in the PR body's follow-up-issues content (idd-pr-submit.instructions.md— mapped onto the template's "Follow-up issues" section when one exists), not a defect. Edit it under E12's "PR body sync" safeguards (idd-review-fix.instructions.md: claim revalidation first, fetch the full body, edit only this claim, post the full result back, re-checkclosingIssuesReferences) even when E8's zero-Accepted- PATH-A skip bypasses E9-E15, and E12 with it. This rule parallels E10's "Round-count heuristic for genuinely-new findings" (same file): that heuristic covers a shared root cause once PATH A work is underway; this fence applies earlier, at PATH A/B scoring.
E5 — Record Accept / Reject decisions
Record a path-specific disposition for every item:
- PATH A: High-severity items reach Accepted only via "Verify before accept" below, or — when the actor-permission cap applies — an explicit maintainer confirmation reply; Medium/Low require an explicit Accept or Reject decision, except a scope-fenced finding (E4), which is Reject forced regardless of severity.
- PATH B (a completed review of the current HEAD):
Acceptedmeans the advisory confirms the implementation or captures useful context;Rejectedmeans noted, no action required. An advisory non-review notice (E4) is not scored here — record it, but always asRejectedper the E6 non-review-notice rule.
Actor-permission cap (PATH A). Before an Accept, check whether the
actor is a CODEOWNER, required reviewer, or holds Triage/Write/Maintain/
Admin access (GET /repos/{owner}/{repo}/collaborators/{username}/permission). Absent all
three, assertion alone never reaches Accept forced — only "Verify before
accept" confirming the claim, or an explicit maintainer confirmation
reply, gets it there. Otherwise cap it at Rejected with the reasoned
reply E6 already requires. CODEOWNER/required-reviewer AMD handling is
unchanged.
Accepted PATH B items do not enter review-fix. They are fully handled in E6-E7.
Verify before accept (PATH A and PATH B). A PATH A or PATH B item
often asserts a fact — about safety, correctness, the runtime, CI, or an
artifact. Before Accepting it, confirm the claim against live evidence
(a code read, reproduction, or an equivalent check), not the comment
text alone — the actor-permission cap above is the only exception, via
maintainer confirmation for an unprivileged PATH A actor: confirmed →
Accept and act; false on the live evidence → disposition it
Rejected and cite the contradicting evidence (the code as read, the
real run conclusion, file contents, or artifact) — a verified-false
claim is a reasoned rejection, not an action item (scoped to this
verification only — not E4/E5's Low-severity/no-action Rejected
routes); inconclusive (neither confirmed nor contradicted — the
needed check has no route here, not merely low confidence) → for an
actor-permission-capped, reviewer-feedback PATH A item, route it
through the CODEOWNER/required-reviewer AMD hold (E6) instead of
Rejected, using E6's marker (a critique-pass finding stays under
the unchanged cap above).
Resolved-thread duplicate pre-check (PATH B, before verification).
Before verification above, check whether a new PATH B item — a review
thread or a regular comment (E6 supports both PATH B sources) — matches
an entry in this PR's resolved-thread index
(idd-review-snapshot.instructions.md E1 Step 3). Matching is scoped to
this PR's resolved threads only: a regular comment has no resolved
state of its own, but can still match a prior resolved thread's claim.
- Match the new item against the index by file area and substantive claim, requiring the identical claim rather than merely a related topic in the same file (same file but a different claim is not a match).
- On a match, open the linked prior thread — the index disposition alone
is not proof. Re-confirm the new item raises that same underlying
claim, not just a related one, then confirm the prior thread
actually recorded a reasoned rejection with citable evidence (not
a bare
**Rejected**, and not the E6 non-review-notice rejection, which asserts no result was reviewed rather than rejecting a claim), then quickly recheck that the cited evidence still holds at the current HEAD — the diff moves between rounds, so a prior file/line citation can be stale. - Shortcut. If the prior disposition was a reasoned rejection with evidence and that evidence still holds: reply to the new item with a fresh, individually-authored disposition citing the prior thread's URL and its evidence, then apply the existing E6 PATH B reply rules for that item's source — resolve immediately after replying for a review thread; reply only for a regular comment. Every recurrence still gets its own reply, so the 1:1 disposition-count / no-combined-replies rule (E6) is unchanged — only the reply's content is shortcut.
- Fall through unchanged to "Verify before accept" above when there is no match, re-confirmation shows the new item is not actually the same underlying claim, the matched disposition is not a reasoned rejection with evidence, the cited evidence no longer holds at current HEAD, or the new occurrence carries genuinely new information the prior thread did not address.
Round-count cutoff (critiqueLoop.deferAfterRounds, default 15).
Once the claim's review-watermark post count (paginated,
including minimized ones and this pass's own E1 post) reaches the
threshold, disposition an undispositioned Low-severity (E4) PATH A
item Reject (defer) instead of the normal judgment — never an
already-Accepted item mid-fix (e10NoProgressHoldAfter unaffected) nor
a CODEOWNER/required-reviewer item (E6's AMD exception applies). Reply
**Rejected** — deferred to follow-up issue #<n> (round <round>/<threshold>): {reason}, resolve normally, and bundle every
item from this cutoff into one follow-up issue per E6's
follow-up-issue rule, each with an AC bullet and the
<!-- kurone-kito-authoring-defer-source: review-fix-loop-cutoff -->
marker. See
rationale.
E6 — Post disposition replies
Apply the reply rules below after E5 records a disposition.
PATH A — Accepted items:
- Do not reply in triage solely to acknowledge the acceptance. Accepted
reviewer feedback is replied to after the fix work in
idd-review-fix.instructions.md.
PATH A — Rejected/inconclusive reviewer feedback:
For each Rejected or inconclusive (E5) PATH A item whose source is reviewer feedback:
-
Reply using the format:
**Rejected** — {reason}— unless the Exception below applies. -
Exception: if the source is a CODEOWNER or required reviewer, or the item is E5's inconclusive outcome, do not reject unilaterally. Reply using the format:
**Awaiting maintainer decision** — {your reasoning}(name the unavailable check when inconclusive) and wait for the maintainer's response. -
After posting your reply, immediately resolve the thread — except for
**Awaiting maintainer decision**. When helper runtime is enabled, the profile-selected resolve-review-thread command (--pr <number> --comment-id <id> --apply, with--body/--claim-issue/--claim-idor--claimless; seedocs/idd-helper-scripts.md) posts the reply and resolves in one call, replying before resolving so a failed reply never leaves a silently-resolved thread; the manual REST + GraphQLresolveReviewThreadsequence is the fallback. Resolving means "agent acted", not "reviewer agreed" — a disagreeing reviewer can reopen the thread, which re-surfaces it in a future E1 pass. -
Exception to immediate resolution: for a review-thread AMD, leave it unresolved (do NOT resolve) so F2's "Unresolved threads = 0" gate blocks merge until the maintainer responds, and post a separate hold comment explaining what you're waiting for. A regular-comment AMD (CODEOWNER/required-reviewer feedback with no thread) cannot use that gate structurally — instead post the hold comment stating you will not merge until the decision appears, and stop. Either way, wait for the response in a future E1 pass (see the transitions below).
-
When an
Awaiting maintainer decisionthread re-appears in ReviewItems_snapshot: scan the activity universe for a qualifying response — a reply on this thread, or a separate comment/review that clearly references this item — from a qualifying person (any CODEOWNER, required reviewer, or a collaborator with Write/Maintain/Admin access perGET /repos/{owner}/{repo}/collaborators/{username}/permission), excluding the acting agent and the PR author, posted after your AMD comment. A general comment/review from a qualifying person that does not reference this item does not count.If a qualifying response exists, apply the transitions below. Otherwise, ensure a hold comment exists (post one if not), then stop — do not re-reply or resolve; resume when the response appears in a future E1 pass.
-
When the maintainer eventually responds (their response surfaces in a future E1 pass as an unresolved thread or new reply):
- If the maintainer agrees no action is needed: reply summarizing
the agreed decision (e.g.,
**Rejection confirmed by maintainer** — {summary}) and resolve the thread. - If the maintainer disagrees: move the item to Accepted and proceed through the fix flow. Resolve the thread after fixing.
- If the maintainer's response arrived in a separate PR comment or review rather than in the original thread: mirror the decision onto the original thread and resolve the thread. Also reply to the maintainer's separate comment (e.g., "Decision mirrored to the review thread — {link}") so that F2's unreplied-comments gate does not block merge on that comment.
- If the maintainer agrees no action is needed: reply summarizing
the agreed decision (e.g.,
-
For a
CHANGES_REQUESTEDreview body you are rejecting: post a PR comment explaining your reasoning and ask the reviewer to reconsider.- If the reviewer does not respond and the state does not change: post
a hold comment (keep the claim) and stop. Check elapsed time on the
next heartbeat or resume:
- After
reviewEscalation.changesRequestedFirstEscalation(defaultPT24H) with no response: escalate to a maintainer via issue or PR comment. - After
reviewEscalation.changesRequestedSecondEscalation(defaultPT48H) with no escalation response: apply the Needs-decision claim release rule inidd-overview-appendix.instructions.md(Hold / suspend).
- After
- Clearing F2's
CHANGES_REQUESTEDgate always requires the review state itself to change — a reviewer state change (re-submit asCOMMENTED/APPROVED) or an admin dismissal viaPUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals. A comment merely agreeing with your rejection is never sufficient on its own, whether posted by the original reviewer or by a different maintainer/admin — ask them to change state or dismiss explicitly. - If the reviewer responds and disagrees: move the item to Accepted and proceed through the fix flow.
- If the reviewer responds (either way): restart from E1.
- If the reviewer does not respond and the state does not change: post
a hold comment (keep the claim) and stop. Check elapsed time on the
next heartbeat or resume:
-
If you decide "Reject now but should do eventually": open a new issue following
idd-pr-submit.instructions.mdD3's follow-up-issue rule — never callgh issue create(or the REST issues API) directly; use theissue-authoringskill. The new issue's body must include aRefs #NNNline on its own line (not narrative prose) back to the originating issue — useRefsspecifically and reference the issue, never the PR: a referenced PR is recorded as an unresolved reference bydiscover-roadmap-graph, and only theRefsrelationship is cycle-exempt for a closed leaf, so a different keyword (e.g.Closes) or a PR target leaves the reference unresolved until the issue body is corrected. Mention the originating PR in prose if useful. Mirrors the A1.5 rule inidd-roadmap-audit.instructions.md.
Use these prefixes so that disposition is always unambiguous:
- PATH B acceptance marker (only for a completed review of the current
HEAD):
**Accepted** — {what the advisory comment confirmed} - Ordinary rejection:
**Rejected** — {reason} - CODEOWNER / required reviewer, or inconclusive (E5), exception:
**Awaiting maintainer decision** — {reasoning}
Two requirements make the F2/F3 disposition-evidence gate recognize an
**Accepted** / **Rejected** disposition — isDispositionComment reads
"the body starts with that marker" and pairs dispositions to advisory
comments 1:1 by count (**Awaiting maintainer decision** is a
separate PATH A signal, not part of this pairing):
- The marker must be the first bytes of the comment body — no heading, block quote, code fence, or preamble before it (a code-fenced marker fails this on its own — the fence delimiters, not the marker, are the first bytes), or the gate counts zero dispositions for that comment.
- After the visible prefix, include the prefix-aware reply-identity
stamp
<!-- {markerPrefix}-review-reply -->(use the repositorymarkerPrefix, defaultidd-skill; helpers inject it; a manualgh apiJSON body must append it). The stamp is utterance identity, not an E1review-watermark, and it must not replace the required**Accepted**/**Rejected**first bytes. F2 treats an unmarked human reply on a human-authored thread as presence-only; it does not treat that as a completed IDD disposition. Copilot / configured-advisory-bot threads still require a stamped or legacy trusted IDD disposition (or resolution). E7 still fails a recorded PATH A agent reply that lacks this marker contract — presence-only is an evaluation rule for other people's replies, not a license to post bare prose on the session's own items. - Post one disposition reply per advisory item — never combine
several markers into one comment; the 1:1 pairing clears only one item
per comment, leaving the rest flagged
missing-disposition-evidence.
PATH B — Advisory items (completed review of the current HEAD):
- Reply immediately with a decision marker, even when no code change is
needed. Use
**Accepted**/ "no findings / no action required" framing only when the advisory is a completed review of the current HEAD:**Accepted** — {what the advisory comment confirmed}**Rejected** — {why no action is required}
- Review threads: resolve immediately after posting the marker.
- Regular comments: reply only.
- Do not send PATH B items to review-fix. Their work is complete once the marker is posted and any thread resolution is done.
review-ack: marker — Clause 1 vs Clause 2. Posting **Accepted**
/ **Rejected** above satisfies advisory-convergence's Clause 2
(thread / comment disposition) only. When the latest Copilot review on
current HEAD also reports suppressedCount > 0 (a finding folded into
a <details><summary>Suppressed comments (N)</summary> block instead
of a comment, so it has no thread or comment ID of its own to reply
to — see docs/idd-helper-scripts.md), Clause 1's suppressedCount
term needs its own coverage
(suppressedCount === 0 || hasValidReviewAck) regardless of any
Clause 2 disposition elsewhere in the same review. After reading the
review body and confirming the suppressed finding(s) are handled
(fixed, or judged as needing no action), post review-ack: for the
current HEAD SHA. post-idd-marker.mjs itself performs no author
gating — anyone with gh credentials can post the comment — but
idd-advisory-convergence only honors a marker whose GitHub author is
a trustedMarkerActors login; an untrusted poster's marker is ignored,
not rejected at post time (helper-first: post-idd-marker --type review-ack --from-pr <pr-number> --agent-id <id> --timestamp <ISO8601> --apply):
review-ack: {agent-id} {PR_HEAD_SHA} {ISO8601-acknowledged-at}
Worked example: see rationale.
PATH B — Advisory non-review notice (rate-limit / quota / queued / bare ack / error, as defined in E4):
- A non-review notice is never evidence of a completed review — never disposition it as confirmation, "no findings", or "reviewed, no action needed". It also doesn't prove no review exists: disposition any separate completed review of current HEAD under the completed-review rules above.
- Helper-first (optional). When helper runtime is enabled, the
disposition-non-review-noticeshelper (seedocs/idd-helper-scripts.md) detects these notices and emits (dry-run) or posts (--apply) the canonical disposition below — marker-first, one per notice, idempotently and fail-closed. The written rule here stays authoritative; the manualgh apipath is the fallback. - Disposition it deterministically in the current pass — no
re-request, no wait. The notice itself is always
**Rejected**(never**Accepted**— it carries no advisory result):**Rejected** — {bot} did not review HEAD {sha} ({reason}); this is not a completed review (source: #issuecomment-{id}). Use the bot's GitHub login for{bot}(e.g.coderabbitai[bot]) so the carry-forward rule below can attribute per-bot. A separate completed review of current HEAD, if present, is its own snapshot item — disposition that one as**Accepted**under the completed-review rules, not this notice. Re-validate first: a completed review can race in after the E1 snapshot but before this rejection posts. If it has, disposition that review instead and take a fresh E1 snapshot, so the rejection's later timestamp doesn't filter the completed review out of the next pass. - Paraphrase, never reproduce, a bot's trigger or command string in
{reason}. Advisory bots scan comment bodies for their own command-trigger strings even inside Markdown code spans, so quoting a bot's literal review-request mention verbatim — fenced or not — can fire it as though a fresh review had been manually requested. Describe the situation in your own words instead. Canonical paraphrase for the low-star / manual-trigger skip-review case: "requires a manually triggered review for low-star repositories". - Carry the rejection forward across pushes. Once a notice carries a
**Rejected** — {bot} did not review HEAD …reply, that disposition persists across later HEAD changes and pushes while the same notice persists and the bot still hasn't reviewed any HEAD — a bumpedupdatedAtor a re-posted identical summary needs no fresh rejection; the F2/F3 disposition-evidence gate carries the existing one forward. Scoped per bot (by GitHub login): one bot's carried rejection never clears another's undispositioned notice. Re-disposition only when the bot replaces the notice with an actual completed review — disposition that under the completed-review rules instead. - Never auto-request a fresh review to "upgrade" a notice. Requesting
review state is owned solely by the advisory-wait protocol
(
idd-advisory-wait.instructions.md, AW3REQUEST_NEEDED→ E14); a maintainer may manually re-trigger a non-Copilot bot. A later completed review is dispositioned normally on the next E1 pass. Never post anadvisory-waitmarker for a non-Copilot bot — AW2/AW3 treat any trusted same-HEAD marker as Copilot evidence, wrongly satisfying the Copilot gate and consuming its cap. (The Zero-Accepted-PATH-A advisory re-review gate below is a sanctioned exception — it never triggers on a notice alone.) - Fail-closed honesty: never cite a non-review notice as evidence
that the advisory reviewer reviewed the current HEAD — not in the
disposition reply, the
Authoritative byline, or the PR live status digest. - Non-blocking boundary: this rule does not make PATH B a merge
blocker. The blocking advisory gate remains the Copilot advisory-wait
protocol in
idd-advisory-wait.instructions.md, which is unchanged.
E7 — Verify recorded dispositions
When helper runtime is enabled, prefer the read-only verifier command:
idd-review-disposition-verify --items '<json>'
In the source repository, node scripts/review-disposition-verify.mjs
is equivalent. E7 consumes helper fields passed, items[].passed,
items[].checks, and items[].issues. This helper never posts replies
or resolves threads: all E6 mutations remain manual and authoritative.
Discard helper output and apply the written checks below directly if
execution fails, output is invalid, or it conflicts with observed
review state.
Before leaving triage, verify every ReviewItems_snapshot item has the evidence required by its path:
- Every PATH A item has a recorded classification and an Accept, Reject, or AMD decision (including E5 inconclusive). Every Accepted item cites its "Verify before accept" evidence, or the maintainer confirmation reply when actor-permission capped.
- Every Rejected or inconclusive PATH A item whose source is reviewer
feedback has the required rejection or
**Awaiting maintainer decision**reply posted, and any non-AMD thread resolution is complete. - Every PATH B item has a posted
**Accepted**or**Rejected**marker. Review threads are resolved immediately after the marker. - Only Accepted PATH A items remain candidates for
idd-review-fix.instructions.md. PATH B items are fully closed out in triage.
If any check fails, do not continue. Return to E4-E6 as needed until the missing evidence is recorded.
After E7 succeeds, update the PR live status digest only when it will
not invalidate a merge-bound E1 snapshot — when triage posts a hold and
stops, when Accepted PATH A items remain and the next route is E9, or
when a fresh E1 snapshot follows before F2. Set Phase to E triage,
summarize remaining Accepted PATH A work or none in Open blockers,
Next action to E9 or F2 as appropriate, and cite the disposition
replies plus the trusted review-watermark in Authoritative by. If
ReviewItems_snapshot is empty and the next step is F2, defer the digest
update unless you intentionally return to E1 afterward.
E8 — Accepted PATH A count check
Zero Accepted PATH A → E-phase branch-sync check below (per the
Skip condition note above); otherwise →
idd-review-fix.instructions.md.
E-phase branch-sync check
After the review loop confirms no PATH A items remain (from E3 or E8),
check the current branch state before routing to F-phase. This gate uses
merge-from-{development-branch} (never rebase) when synchronization is
required, preserving review history on the already-published PR branch.
{development-branch} is the value resolved in
idd-work.instructions.md's B1
Resolve the development branch
step.
When helper runtime is enabled, call:
idd-branch-conflict-state --pr {pr-number}
Otherwise read branch state directly:
gh pr view {pr-number} --json mergeable,mergeStateStatus
Route based on branchState from the helper (or mergeable /
mergeStateStatus from gh pr view):
cleanorbehind-no-conflictwhen branch protection does not require an up-to-date head: first apply the Zero-Accepted-PATH-A advisory re-review gate below if it applies (no-op otherwise). Then, if E6 posted any disposition reply this pass, refresh thereview-watermarkfor the same{head-SHA}(recompute{max-activity-updatedAt}/{total-item-count}/{latest-ci-completed-at}, following the E1 Step 2 rules) — otherwise F2's review-currency check treats your own dispositions as new activity and bounces back to E1 needlessly. Skip the refresh on the sync path (E1 re-snapshots after merging{development-branch}) or on a hold.cleanhere means conflict-freeness only — see thebaseAdvancedSinceMergeBasenote under F1 inidd-pre-merge.instructions.md. Then proceed toidd-pre-merge.instructions.md(F1).behind-no-conflictwhen branch protection or recorded repository policy requires an up-to-date head, or undetermined (fail closed, per F1): → sync path below.content-conflict(mergeableisCONFLICTING): → sync path below.computing(syncRecommendationisrecheck):mergeableisUNKNOWN/ null because GitHub computes mergeability asynchronously and has not settled — a transient state. Do not hold. Re-poll after a short wait, up to a small fixed attempt budget (distributed default: 3 attempts, a few seconds apart), then route by the first settled result. Only a state that is stillcomputing/unknownafter the budget falls through to the hold below.dirty(mergeStateStatusisDIRTY) orunknown: hold; post a PR comment documenting the state and stop. Do not proceed to F-phase without confirmed branch-state evidence.
Sync path (merge-from-{development-branch}):
- Active review gate: unresolved review threads, unreplied
comments, or a reviewer's
CHANGES_REQUESTEDstate require explicit operator confirmation before this merge, since the merge commit will appear in PR history. - Merge
{development-branch}into the feature branch:git fetch origin {development-branch} && git merge origin/{development-branch}. Use the signed-commit merge wrapper when primary signing is non-interactive-hostile. That wrapper's merge invocation includes a conventional-msubject (for examplechore: merge origin/{development-branch} into the claimed branch) so a commitlintcommit-msghook does not reject the merge commit. - If conflicts arise, resolve them and complete the merge with that same procedure — mirrors the D1 rebase note.
- Run post-fix-validate.
- Push the feature branch normally (no force push required for merge commits).
- Return to
idd-review-snapshot.instructions.md(E1).
Merge-development-branch livelock under fast-moving {development-branch}
Under heavy concurrent-session load, {development-branch} can advance
faster than one sync cycle finishes, livelocking naive retries before
ever reaching F3 (background:
design rationale).
Rule: post the watermark as the last action before F3's
idd-merge-execute.mjs --apply, every pass — anything after (a CI
rerun settling, a new disposition reply, another {development-branch}
advance) stales it, failing --apply closed on review-currency regardless
of CI color; re-post before retrying. A stale idd-advisory-convergence
rollup: see rerun mechanics.
Zero-Accepted-PATH-A advisory re-review gate
Applies only from the branch-sync check's no-sync-required clean /
behind-no-conflict exit, and fires under either of two conditions:
(a) the last non-empty ReviewItems_snapshot pass this episode had
zero Accepted PATH A items and at least one PATH B item got a
completed-review disposition (never a notice-only rejection — see
the E6 non-review-notice rule); or (b) the current HEAD is eligible
for AW3-S's settled-window (non-pending) entry (running
advisory-wait-state reports staleRequestRecovery.action as
"attempt" for that entry) — D4 and F2 each already consult AW3-S
independently for this same settled-window entry (#2726), but a
true-virgin empty snapshot otherwise never runs E14 through this gate
specifically; condition (b) is a defense-in-depth backstop that
guarantees this path also reaches the stale-request recovery cycle
(and its route to COPILOT_UNAVAILABLE), rather than depending
solely on D4/F2 revisits eventually accumulating enough AW3-S cycles
on their own. Otherwise a no-op: a true-virgin empty snapshot with no
entry eligible for AW3-S's settled-window (no PATH B ever
dispositioned this episode, and no stale same-head request either)
never fires it; a
later-pass empty snapshot after a sync loop-back still fires via (a),
since the lookback still finds the prior non-empty pass. (Rationale
for the gap condition (a) closes:
design rationale.)
Run this gate after any branch-sync merge settles — requesting
first would let a later merge invalidate the review just obtained.
Run E14's Primary advisory bot procedure
(idd-review-fix.instructions.md E14) at this now-stable HEAD — steps
1-4 plus the active polling loop when it applies; skip Human reviewers
and the secondary-bot step. Substitute "resume the branch-sync check's
no-sync-required clean exit (watermark-refresh, then F1)" for each of
E14's four "proceed to E15" exits (step 2's SATISFIED, step 4's AW3
SATISFIED and CAP_EXHAUSTED default, and the polling loop's
SATISFIED exit). Every other exit — every "return to E1" and every
hold-and-stop exit — halts exactly as in a normal E9-E15 pass; never
redirect a hold to branch-sync or F1.
E14's own fresh AW1 check already makes this gate inert once the bot has reviewed current HEAD, so it never duplicates a request, and never fires when the bot's latest review already covers HEAD but still carries items — AW6 (#1511) handles that residual from F2 instead.
Advisory courtesy-ack convergence
A trusted advisory bot's post-disposition courtesy reply (e.g. "thanks
for confirming") advances the PR's updatedAt, which a naive
review-currency check would treat as new activity and loop the
review/snapshot cycle forever.
Rule: once every ReviewItems_snapshot item has an
**Accepted**/**Rejected** disposition at the current HEAD SHA, a
later ack-only comment from a trusted advisory bot does not reopen
the loop — bind the merge to current HEAD and proceed. An ack-only
comment opens no new thread, carries no CHANGES_REQUESTED, and raises
no new finding; anything else re-opens the loop normally.
Example: CodeRabbit replies "Thanks for confirming" after your
**Rejected** disposition — no new thread or finding, so continue to
F-phase on the current HEAD despite the updatedAt advance.
Helper evidence: when the advisory-bot identity is configured, the
activity-snapshot / pre-merge-readiness evidence emits the structural
half of this classification (reviewCurrency.live.ackOnly.items,
reviewCurrency.comparisonReason: ack-only-post-disposition); the
agent still confirms the semantic residual (no new finding), and this
never weakens the disposition-evidence or unreplied-comment backstops.
Disposition-evidence parity (advisory-only): the same ack can also
re-trip the dispositionEvidence backstop on an already-resolved
thread (route: return-to-e1). pre-merge-readiness flags each such
thread ackOnlyPostDisposition: true; when
dispositionEvidence.soleCauseAckOnlyPostDisposition is true (every
blocking item is one such thread), autopilot may deterministically
override return-to-e1 and proceed (see idd-pre-merge.instructions.md
F2). Any non-ack blocking cause keeps it false, so the backstop holds
otherwise. (inPlaceEditOnly/soleCauseInPlaceEditOnly, #1313, is a
stricter subset — not an override path of its own.)