IRON LAW: No review-automation trigger caused by this workflow's planned publication events may be accepted or released until the final SHA is the authoritative remote head and every workflow-planned context write in the frozen publication plan except the atomic operation that emits the final trigger is authoritative. A context write may occur before the final SHA is remote when it is authoritatively proven non-triggering. A triggering or unknown context write may occur earlier only when documented suppression, batching, or coalescing guarantees that it cannot emit, accept, or schedule a trigger before those conditions hold and that the eventual trigger is bound to the final SHA and frozen context. Delaying run start after trigger acceptance is not safe. Verify the final trigger-producing write authoritatively before a thread transition.
Resolve Review Comments
Workflow
Global Rules
- Self-contained execution: Select one available platform interface at preflight. Prefer a purpose-built GitHub or GitLab interface that exposes pagination, threads, comments, metadata, and runs. Otherwise use
gh/GitHub GraphQL or GitLab REST against the exact PR/MR host. Keep triage, code changes, review, replies, and description drafting in this workflow; do not depend on another skill.
- Bounded autonomous authorization: Determine authorization intent from the meaning of the complete user request, never from a hard-coded keyword, exact phrase, command token, language, or regex. Select
authorization mode: autonomous only when the request clearly identifies one PR/MR, delegates the end-to-end review-resolution workflow, authorizes the repository and review-system mutations needed for closure, and asks not to receive repeated confirmation or authorization prompts. Examples in documentation are illustrative, not a whitelist. When any dimension is missing, ambiguous, scoped more narrowly, or contradicted elsewhere in the request, select authorization mode: guarded. In autonomous mode, record a standing authorization envelope at preflight that permits triage, attributable edits, tests, replies, PR/MR metadata updates, Resolve/Reopen transitions, and review-automation interaction only for the current PR/MR. Include commit or push only when the trusted-base repository rules expressly permit advance authorization for that operation; a repository-mandated post-diff commit confirmation or separate push confirmation remains a mandatory checkpoint in every mode and cannot be waived by a request to avoid repeated prompts. Bind any permitted push authority to the authoritative source repository, full head ref, and a final SHA produced solely from attributable task changes. Validate every concrete mutation against the envelope before executing it. No operation outside the recorded envelope inherits authorization. Any scope expansion requires stopping and reporting the exact expansion. Do not repeat confirmation or authorization prompts for an operation inside the envelope, except at a mandatory repository checkpoint. If a material Clarify remains, a required check fails or cannot be verified, task attribution is unsafe, guarded drift recovery fails, safe trigger ordering cannot be proven, a remote result remains ambiguous, publication ownership is lost, or an unapproved destructive action is required, stop and report the exact blocker without asking a follow-up question. Do not treat generic advance acceptance of unknown test gaps, destructive targets, remote destinations, or ambiguous outcomes as authorization.
- Complete collection: Exhaust every page, cursor, continuation token, and nested comment connection before filtering. A partial response never proves that no work remains.
- Item-level ledger: Track stable comment/note IDs separately from thread/discussion IDs. A previously seen thread does not prove that its current replies were seen.
- Minimal scope: Implement only accepted feedback and required caller/test updates. Preserve unrelated and pre-existing work.
- No review metadata in repository outputs: Commit messages and PR/MR title/body must be understandable from the repository diff and history alone. Do not include reviewer names, comment IDs, or phrases such as “address review.”
- Replay safety: Before each reply or metadata write, refresh its exact target. After an ambiguous result, reconcile the complete exact target through the recorded visibility bound. Reuse one unique exact effect and apply the approval-gated duplicate rule to multiple matches. When no effect appears and the precondition remains unchanged, permit at most one identical retry only if the event is proven non-triggering or the provider applies the same idempotency key; otherwise stop. Reconcile again after that retry and never make a second retry.
- Concurrent publication safety: Prefer an exclusive publication lease keyed by provider, repository stable ID, and PR/MR number, and hold it through final verification. Lease acquire, renew, and release must each be authoritatively proven non-triggering; a mechanism with a triggering, unknown, or merely suppressed lifecycle event is not eligible as this lease. Before the final pre-push freshness read, require its remaining lifetime to exceed a recorded combined upper bound for that read, the push attempt and allowed push reconciliation, and the post-push critical section. After the freshness read, re-check that the remaining lifetime still covers the push and critical-section bound; renew only before repeating the freshness read, never inside the critical section. Without such a lease, freeze the exact remote head, metadata, item fingerprints, reply targets, thread states, and trigger evidence as an optimistic guard, then revalidate the applicable values immediately before each write. This path does not claim atomic exclusion from another publisher. Send an unsuppressed
triggering or unknown non-idempotent write only at the next trigger-safe position frozen in the publication plan, after every applicable context and final-SHA precondition holds. A covered write may occur earlier only when a documented mechanism prevents it from emitting, accepting, or scheduling a review trigger until a named release operation after those preconditions hold, and binds the eventual trigger to the final SHA and frozen publication context. A debounce or delayed run start after trigger acceptance is insufficient. Send a triggering, unknown, or covered write once, reconcile an ambiguous result through the relevant visibility bound, and never retry it without provider idempotency or documented coalescing. The ordering rules still permit at most one independently triggering context write unless batching, suppression, or coalescing prevents early trigger acceptance and partial context. For a proven non-triggering write, use this bounded convergence procedure: refresh the exact target, write once, reconcile through the recorded visibility bound, and make at most one identical retry only when the event remains proven non-triggering or the provider applies the same idempotency key; keep all preconditions unchanged.
- Known-trigger ordering: Build the trigger inventory from accessible repository workflows, PR/MR checks and runs, integration metadata, and trigger behavior already observed on the PR/MR. Classify every planned push, reply create/edit/delete, PR/MR metadata write, thread transition, or manual event as
triggering, non-triggering, or unknown, with evidence. Classify an event as triggering when it can accept, enqueue, or schedule review work, even if execution starts later. Do not claim that automation is absent without authoritative evidence. Inaccessible administrator-only integration metadata does not globally block events whose trigger behavior is established. Treat an unknown event as triggering for ordering; send it only when every other workflow-planned context write from the frozen snapshot is authoritative and its placement cannot expose partial planned context or an unpushed fix. Otherwise require batching, suppression, coalescing, or additional trigger evidence before sending it.
- Review-context linearization: Immediately before each trigger-safe publication position, complete the required review-context collection and freeze its canonical item IDs and fingerprints as the optimistic linearization snapshot. A publication lease coordinates only the writers it authoritatively covers; neither that lease nor refresh-write-verify proves that an external reviewer cannot add or edit feedback after the snapshot. Without a provider conditional revision or an exclusive mechanism covering every review-context writer, guarantee only that the final SHA and every workflow-planned context write from the frozen snapshot were authoritative at the linearization point. Never claim atomic exclusion of later external feedback. Reconcile later drift as a new triage/publication cycle. If the requested contract requires one trigger to include feedback written concurrently after the snapshot, stop unless an atomic provider guard or a lease covering all such writers is available.
- Post-push critical section: From push success (or no-push remote-head confirmation) until every planned resolve/reopen has a recorded result, perform only remote-head confirmation, the complete review-context freshness read, a triggering context write that Step 7 explicitly deferred until the final SHA was remote, the planned thread transitions and any frozen inverse compensation required by an aborted sequence, and narrow reconciliation reads. Do not test, wait for CI, draft text, rediscover trigger configuration, or perform unrelated API work in this interval.
- Untrusted-head execution: Classify the head repository and author against an explicit trusted-base repository policy. If no policy exists or its evidence is incomplete, classify the head as untrusted; never infer trust from a familiar owner, branch name, or hosting provider. Read workflow rules and verification commands from the trusted base, not from an untrusted head. Run untrusted-head code only in a credential-free, host-isolated environment with network access disabled by default. If that isolation is unavailable, perform static review; in guarded mode, ask for a trusted runner or explicit acceptance of the exact unverified scope, while in autonomous mode stop-and-report without asking. Never execute untrusted-head code on a credential-bearing host.
1. Preflight and Trigger Inventory
- Parse the PR/MR URL without sending reusable credentials. Before any operation that could require user interaction, derive a prospective authorization mode from the complete request and parsed URL using Bounded autonomous authorization. Preserve the exact scheme and host; do not assume that every non-
github.com host is GitLab. Before any authenticated request, require an exact normalized-host credential binding, such as a host-specific gh login or an explicit GITLABHOST plus GITLABTOKEN pair. In guarded mode, obtain or verify that binding. In prospective autonomous mode, verify that an existing binding already applies to the exact host and parsed target; if it is missing or ambiguous, stop-and-report without asking. Never select a token or send it to a host solely because that host appeared in the supplied URL. Confirm the provider through an unauthenticated authoritative response when possible.
- Record the base and head/source repository stable IDs, owners/projects, canonical clone URLs, PR/MR number, title, body, base and head full refs, local HEAD, and authoritative remote head SHA. Bind one authenticated canonical head-repository URL and the full head ref as the explicit push destination. A configured Git remote that resolves to the same repository may be recorded as an alias but is not required; never derive the destination from a local branch or remote name. Stop if the authoritative repository/ref is missing or ambiguous.
- Confirm the prospective authorization mode against the authoritative PR/MR identity and freeze it. Freeze guarded mode when autonomous intent was not prospectively established. For prospective autonomous mode, require every autonomous-intent dimension to match the authoritative identity or stop-and-report without asking. In autonomous mode, freeze the standing authorization envelope (
standing envelope) containing: the original request; current PR/MR identity; allowed operations (triage, edit, test, reply, update-metadata, resolve, reopen, trigger-and-wait-for-review, acquire-publication-lease, renew-publication-lease, release-publication-lease, plus commit or push only when the trusted-base repository rules permit standing authorization); authoritative source repository; full head ref; final SHA: pending; interaction policy: do-not-request-reconfirmation-except-mandatory-repository-checkpoints; and blocker policy: stop-and-report. Limit all three lease operations to the exact key formed by the current provider, authoritative source-repository stable ID, and PR/MR number; no other lease target is authorized.
- Verify that the checkout is based on the authoritative remote head. A detached checkout or differently named local branch is valid when the destination URL and full ref are explicitly bound. If local HEAD differs from the remote head, move to an isolated checkout at the remote head unless every ahead commit and hunk is explicitly attributed to this task and authorized for publication by guarded approval or the standing envelope; never proceed from a behind or diverged base.
- Record pre-existing staged, unstaged, and untracked paths and hunks separately. If any pre-existing staged, unstaged, or untracked change exists, continue only in an isolated checkout at the authoritative remote head with its own worktree and index, or stop before editing. Hunk non-overlap or permission to preserve the baseline does not make a dirty worktree a valid verification environment. Never unstage, overwrite, or commit baseline entries merely to prepare this task.
- Classify the head as trusted or untrusted using the trusted-base repository policy. If no such policy exists or the evidence is incomplete, record
untrusted by default. Record the evidence, the trusted source of workflow instructions and verification commands, and the credential/network/process isolation available for executing head-controlled code.
- Select and record one platform interface and the authenticated identity. Confirm that it can:
- enumerate all required review collections with pagination; - fetch a thread/discussion directly by full ID; - create replies and update PR/MR metadata; - resolve and reopen threads when supported; - inspect known review-automation runs or outputs.
- Build a known trigger inventory. Inspect accessible workflow/configuration files, current checks and runs, installed integration metadata, and prior bot activity on this PR/MR. For each planned remote event and each known comment-producing automation, record:
- event classification: triggering, non-triggering, or unknown, with evidence; - event kind: publication-lease acquire/renew/release, push, reply create/edit/compensating-create/duplicate-delete, PR/MR metadata edit, planned or compensating resolve/reopen, or manual action; - actor or command filters; - how a resulting run or bot output will be identified; - whether multiple events are suppressed, ignored, or coalesced.
- Record an observation-start time, one finite total Step 9 verification budget, and finite event-delivery, run-queue, and comment-visibility bounds. Use provider or repository guidance when available; otherwise record conservative finite assumptions that fit within the budget. The budget and bounds must survive every workflow re-entry.
- Record a baseline of current related run IDs/statuses and current bot-authored item IDs. Exhaust pagination. Immediately assign every observed run a provisional classification in this priority order: (a)
must-pass when authoritative trigger or reviewed-SHA evidence associates it with this publication or the eventual final SHA; (b) otherwise must-reconcile while it is active; (c) otherwise historical when it is terminal. Use these provisional classifications during the first Step 2 collection and triage. Immediately before the first permitted trigger, or at no-push remote-head confirmation when no trigger is selected, refresh every observed run and record the boundary classification using the same priority; preserve any existing must-pass. Creation or lifecycle updates after the observation start do not establish a final-SHA association by themselves. A must-pass run requires an acceptable conclusion; a must-reconcile run must become terminal and have its complete output reconciled but its conclusion does not gate publication; a historical run remains subject to output reconciliation, but its old conclusion alone does not gate publication. On every later run/output enumeration, re-evaluate every observed run with all currently available trigger and reviewed-SHA evidence, and immediately upgrade an existing historical or must-reconcile run to must-pass when later evidence associates it with this publication or the final SHA. Never downgrade a must-pass run. A historical or must-reconcile output that still applies to the current head remains actionable. If no automation is found, record the evidence as not observed; record none only when authoritative configuration proves absence.
Before publication, choose an order in which the final SHA is remote and all replies and required PR/MR context in the frozen publication plan are authoritative before the first review-automation trigger caused by a planned publication event can be accepted or released:
- If push accepts or releases a review trigger, first publish every reply and metadata write that is non-triggering or covered by the no-early-trigger guarantee, then push.
- If one unsuppressed reply or metadata write accepts or releases a review trigger, perform every other permitted context write first and that operation last among context writes. Dispatch any manual action only after the thread-transition critical section.
- If multiple workflow-planned context writes can each accept independent review triggers, continue only when documented actor filters, suppression, batching, or coalescing prevent every earlier write from accepting or scheduling a trigger and bind one eventual trigger to the final SHA and frozen publication context. Otherwise stop before the first such write and report that no safe ordering is available.
- Multiple thread transitions may each accept independent review triggers after the final SHA is remote and every required reply and PR/MR metadata write is authoritative. Process them serially in the post-push critical section, record every trigger occurrence, and reconcile every resulting run; do not require suppression, batching, or coalescing merely to hide intermediate thread states.
- Treat a planned
unknown event like a triggering event for ordering. If sending it could expose a partial set of replies or metadata, stop before the first remote write. In guarded mode, request trigger evidence or a suppression/coalescing mechanism. In autonomous mode, stop-and-report that safe ordering cannot be proven without asking.
- A thread transition may trigger a run after push, but every reply and required PR/MR metadata update must already be authoritative.
- In either publication mode, never allow a triggering or unknown reply/metadata event to accept or release a review trigger before an immediate authoritative check confirms that the final SHA is the remote head. The context write itself may occur earlier only when documented suppression, batching, or coalescing prevents that write from accepting or scheduling a trigger, defers trigger acceptance to a named release operation after every workflow-planned context write from the frozen snapshot is authoritative, and binds the resulting run to the final SHA and frozen publication context. Otherwise, in push mode continue only when push is proven non-triggering and Step 7 can defer the single selected context trigger to Step 8; in no-push mode, defer that single selected context trigger to Step 8. If push and a workflow-planned context write independently accept review triggers, and neither suppression nor batching prevents the earlier trigger, stop before the first remote write.
2. Fetch Complete Review Context ⛔ BLOCKING
For every list query, record the interface or endpoint, page/batch count, and terminal evidence that no continuation remains.
GitHub
Fetch all of the following:
- GraphQL
pullRequest.reviewThreads, without filtering on isResolved;
- every thread’s complete nested
comments connection;
- all PR issue comments;
- all submitted reviews with non-empty top-level bodies, including reviews whose state is
DISMISSED; exclude only unpublished/pending reviews.
REST pull-request review comments do not expose thread resolved state, so they cannot replace the GraphQL thread collection. Mark top-level review bodies and issue comments reply_only; they receive a general PR comment and have no thread transition.
Do not drop a top-level review body because the review was dismissed. Dismissal changes the review state, not the existence of its body. Record the review state and reviewed SHA, then triage the body against the current head; use Superseded only with current-code evidence.
GitLab
Fetch every page of merge-request discussions and any separate notes collection used by the selected interface. If notes is empty, record the excluded placeholder and continue before reading notes[0]. Otherwise determine the containing discussion type from its root note (notes[0]), not from a nonexistent discussion-level resolved field. Enumerate every note; exclude system notes individually, and assign every other note the kind of its containing discussion:
| Root note state |
Treatment of non-system notes in the discussion |
system: true |
Exclude each system note; treat any non-system note as general-comment, reply_only |
system: false, resolvable: false |
general-comment, reply_only |
system: false, resolvable: true |
review-thread-comment; use the root note’s resolved value for thread state |
Enumerate every note in each non-empty discussion. Store the full discussion ID separately for transitions.
Review-Automation Outputs
Enumerate related review-automation runs again, assign a provisional classification to every newly observed run using Step 1, and fetch the complete output of every observed terminal run, including check annotations, summaries, job reports, and equivalent findings that were not also published as comments or notes. Do not defer a terminal output merely because the first-trigger boundary has not occurred. Do not mark a run reconciled until each independent actionable finding in that output is represented in the item ledger. When the same finding is also published as a comment or note with an authoritative cross-reference, keep the automation output as Context linked to that canonical comment/note instead of creating a second actionable record.
If a historical output is authoritatively unavailable because the provider reports that it expired, was deleted, or was erased, do not invent its content and do not block forever waiting for it to reappear. Record an automation-output tombstone with the stable run/output ID, reviewed SHA, terminal status, exact unavailability evidence, and body_sha256: N/A. Identify the equivalent review scope and add one replacement action to the trigger inventory and mutation authorization ledger; do not dispatch it while fetching or triaging. Dispatch it only through the Step 8 manual-trigger gate after the final SHA is remote, classify it as a new must-pass run, and reconcile its complete output through the normal ledger path. Link the tombstone to that replacement run; only the authoritative tombstone plus a terminal, acceptable, fully reconciled final-SHA replacement closes the unavailable historical output. If equivalent review scope cannot be identified or executed, stop and report the unverified scope. Unavailable must-reconcile or must-pass output never qualifies for this historical replacement rule.
Canonical Item Identity
Use only these item kinds:
| Kind |
GitHub |
GitLab |
review-thread-comment |
Pull-request review-thread comment |
Non-system note in a resolvable discussion |
general-comment |
PR issue comment |
Non-system note in a non-resolvable discussion |
review-summary |
Submitted top-level review body, including DISMISSED |
Not applicable |
automation-output |
Terminal check/run output, including annotations and summaries |
Terminal pipeline/job output, including reports and findings |
Use the GitHub GraphQL node ID (or REST node_id) when available, with the numeric REST ID as an alias. Use the exact GitLab note ID. For automation-output, use the provider's stable run/output ID; when one run has independently pageable output channels, append the provider channel ID, never a page-local index. If the provider exposes no stable output-channel ID, use one row for the complete run and keep each independent finding as an action record. If an interface exposes only a fallback ID, retain it until an authoritative response proves its alias. Stop on conflicting aliases.
For each current comment, note, or review summary, record exact body text and body_sha256 = sha256:<digest>, where <digest> is the 64 lowercase hexadecimal digits of SHA-256 over the UTF-8 API body after JSON decoding, without whitespace, Unicode, or line-ending normalization.
For automation-output, assemble every textual output field and annotation from the fully paginated provider response as records (kind, channelid, memberid, payload). kind is field or annotation, and channelid is the stable provider output-channel ID or the empty string when none exists. For a textual field, use its field name as memberid and its exact returned UTF-8 text as payload.
For an annotation, include every decoded annotation-object field by default, including path/range, level or severity, title, message, and raw details. Exclude a field only when authoritative provider schema identifies its exact field path as transport-only or volatile; record the path and evidence, and stop if content/location fields cannot be distinguished safely. Encode the remaining object as UTF-8 RFC 8785 JSON Canonicalization Scheme (JCS) bytes and use those bytes as payload. Use a stable provider annotation ID as memberid when available. Otherwise group byte-identical canonical payloads, sort groups lexicographically by payload bytes, and assign each occurrence in a group a zero-based ordinal; use sha256:<payload-hash>:occurrence:<n> as memberid, where <payload-hash> is the 64 lowercase hexadecimal digits of SHA-256 over payload and <n> is the shortest unsigned base-10 ASCII representation with no leading zeros. This treats annotations as a multiset: provider response order cannot change the fingerprint, while any content or location change does.
Stop on duplicate (kind, channelid, memberid) tuples, then sort all records component-by-component: compare kind, then channelid, then memberid as unsigned UTF-8 byte strings, and let the first unequal component determine the order. Compute bodysha256 = sha256:<digest> over UTF8("resolve-review-comments:automation-output:v1") || U64BE(recordcount) || concat(U64BE(len(componentbytes)) || componentbytes for kind, channelid, memberid, payload in each record), with <digest> encoded as 64 lowercase hexadecimal digits. Encode the first three components as UTF-8; payload is the exact field UTF-8 or annotation JCS bytes defined above. Every length is an unsigned 64-bit big-endian byte count. Do not normalize content outside JCS. Record the platform revision/update time when exposed.
An initial item in an already resolved thread is a historical Context candidate only when durable processing evidence exists, an authoritative resolution boundary proves that the current item revision predates the last resolution, or the repository owner/reviewer explicitly identifies it as historical. Processing evidence and a resolution boundary prove prior handling, not current applicability. For actionable-looking feedback, inspect the current head and record Context only when the prior disposition still holds; if the finding applies again or current applicability cannot be established, return it to triage. Otherwise triage the unprocessed non-system item even though the thread is currently resolved; this prevents feedback added after an earlier resolution from being silently skipped. When a current marker is valid for the source revision and current head, reuse its disposition and published reply result in the ledger. A newly observed external reply or externally edited item after the initial baseline always returns to triage. A workflow-emitted item already recorded in the ledger is an expected effect; return it to triage only if its body or durable identity changed, its source item or workflow-event link is invalid, or any required reply marker or compensation chain became ambiguous.
Treat a structurally valid processing marker written by the authenticated writer as a candidate, not proof of prior processing. Resolve its platform, item kind, and full item ID to one non-self source item in this PR/MR; require the marker body_sha256 to equal that source item's exact current fingerprint, validate the disposition and marker-covered SHA under the current-head rules above, and require one unambiguous compensation chain. Only then record the marker-bearing item as Context with origin: workflow-emitted and link it to the source item key; it does not process itself and must not receive another reply. If the source exists but its current fingerprint differs, record the marker-bearing item as stale workflow Context, do not treat it as processing evidence, and return the source item to triage. If the source is missing, retain the marker-bearing item as orphaned workflow Context only when the current ledger already contains that exact reply ID and marker linked to the source and a complete comparison authoritatively moved the source row to removed history; preserve that link to the removed source row. Otherwise stop on a malformed marker, a missing/cross-PR/self source, or an ambiguous source/compensation chain.
For an actionable bot-authored reply_only item associated with a historical or must-reconcile run, record the authoritative run ID and reviewed head SHA. When a valid current processing marker covers the item revision, reuse its disposition and reply result. Otherwise classify it as Superseded only when inspection of the current head proves that the finding was fixed or made inapplicable after the reviewed SHA; cite that evidence in the reply. If the finding still applies, triage it as actionable; if the run/head association or current applicability cannot be established, use Clarify rather than silently treating it as Context or repeatedly choosing Skip. An edited item or one associated with the current head always returns to triage.
Apply the same current-head rules to each action in an automation-output item. Record the authoritative run/output ID, reviewed head SHA, and exact annotation location or summary section for each action. Publish any required disposition reply as one general PR/MR comment for the complete output item. A terminal output is reconciled only after its current fingerprint has a ledger row, every independent finding has a decision, and any required reply is authoritative.
3. Build the Item Ledger and Triage ⛔ BLOCKING
Maintain one ledger row per canonical item. A Markdown table, JSON object, or equivalent structured record is acceptable, but every row must contain:
| Field group |
Required values |
| Identity |
platform, item kind, full canonical item ID, aliases, thread/discussion ID or reply_only |
| Source |
author stable ID, origin, processed source item key or workflow event key when workflow-emitted, path/line or reply target, revision/update time, exact body_sha256 or N/A for an authoritative historical-output tombstone, current resolved/actionable state |
| Decision |
stable per-action records with Implement / Superseded / Skip / Clarify / Context, rationale, affected files, aggregate item decision, and accepted-Skip closure evidence or N/A |
| Publication |
At triage: planned reply/no-reply and pending for future values. Before the first remote write: workflow final SHA, marker-covered SHA, exact reply text, and deterministic marker. For an exact-syntax manual-trigger command item: exact command text, workflow event key, and marker: N/A. After the write: reply/item ID and result |
| Transition |
At triage: observed pre-transition state, desired state, and planned Resolve/Reopen/No-op or N/A. After Step 8: transition result |
pending is a valid lifecycle value, not a missing ledger field. The Step 3 gate requires complete Identity, Source, and Decision values plus publication/transition plans; it must not require a future SHA, remote ID, or operation result. Replace each pending value at the step that authoritatively produces it, and freeze all remaining publication inputs in Step 7.
Classify every independently actionable request within each item:
| Decision |
Meaning |
| Implement |
Correct and applicable; change code/tests |
| Superseded |
Correct when written but demonstrably fixed, removed, or made inapplicable on the current head; cite the current code/diff evidence and make no new change |
| Skip |
Incorrect, harmful, or conflicting; write a technical reason |
| Clarify |
Intent cannot be determined safely; resolve under the mode-specific triage gate below |
| Context |
Non-actionable acknowledgement, workflow reply, system/status information, or initial historical resolved item; record why |
Keep one canonical item row, but add a stable action key and decision for every independent request in that row. Use aggregate item decision Implement when at least one actionable record is Implement and every actionable record is Implement or Superseded, Superseded when all actionable records are Superseded, Skip when all are Skip, Mixed when Skip occurs with Implement or Superseded, Clarify while any action awaits clarification, and Context only when no actionable request exists. Mixed is an aggregate value, not a per-action decision. For an open inline finding tied to an older reviewed SHA, use Superseded rather than Skip only after the current head proves that the finding no longer applies.
Deduplicate items only by canonical item identity and action records only within the same current item revision. Similar text is not identity. Preserve old revisions as history and make decisions from the current revision only.
Keep a Skip as the original decision when a later item closes it. Mark that action accepted-Skip for thread-state computation only when the original reviewer or a repository owner explicitly withdraws the request or accepts the published technical rationale, or when authoritative actor and ordering evidence proves that such a person resolved the thread after the exact Skip reply became visible. Record the accepting item or transition identity and timestamp. A generic acknowledgement, an unattributed resolution, or an automation-produced state change is not acceptance. Treat closure evidence as current-state evidence: if the accepting item is edited or deleted, or its actor/order proof no longer validates, clear accepted-Skip and return the action to triage. Preserve the original Skip decision and reply as history; do not relabel it Superseded or post another reply solely for closure.
For each thread, compute one desired state from current action records:
- Resolved when it has at least one actionable record and every actionable record is Implement, Superseded, or a Skip with valid
accepted-Skip closure evidence.
- Open when any current action record is an unaccepted Skip or Clarify.
- Unchanged when it contains only neutral Context.
Compare that desired state with the observed pre-transition state. Plan Resolve only for open → resolved, Reopen only for resolved → open, and No-op when the thread is already in the desired state or the desired state is Unchanged. reply_only items use N/A.
Immediately before presenting the triage table, repeat the complete Step 2 run/output enumeration and review-context collection. Fetch and ledger every run now observed terminal, then freeze the run IDs, statuses, output fingerprints, canonical item IDs, and item fingerprints as the triage linearization snapshot. A run still active at this snapshot remains provisional must-reconcile; if it becomes terminal later, the next mandatory run/output enumeration returns its output to triage before publication. This snapshot does not claim atomic exclusion of later external changes.
Present the complete item-and-action triage table from that snapshot before editing. Do not begin code changes until every current item and action record is classified and every Clarify is resolved. In guarded mode, obtain user confirmation for Skip decisions unless the current request already explicitly authorized the presented triage, and ask the user to resolve any Clarify that authoritative context cannot resolve. In autonomous mode, record each Skip rationale and proceed without asking; a material Clarify that cannot be resolved from authoritative context invokes stop-and-report.
Every item with aggregate decision Implement, Superseded, Skip, or Mixed must have exactly one planned workflow reply covering all of its current action records. A valid existing marked reply may satisfy this requirement and must be reused. no-reply is allowed only for Context when no status response is required; Clarify cannot pass the gate.
4. Implement Fixes
Read trusted-base repository instructions and the target plus surrounding code before each change. Apply every Implement action record in dependency order, including Implement records inside a Mixed item. For every Superseded record, verify and cite the current code or intervening diff that already satisfies it; do not create a no-op change.
For each fix:
- Reproduce or verify the issue with the smallest relevant check when possible.
- Apply the minimal code and test change.
- Run focused compilation, linting, or tests only under the trust and isolation decision recorded at preflight. Require every executed check to pass before publication; a known failing check always blocks publication. If a required check cannot run because trusted isolation or a prerequisite is unavailable, record the exact unverified scope and impact. In guarded mode, obtain explicit user acceptance before publication. In autonomous mode, stop-and-report without asking.
- Update callers and dependents only when the changed contract requires it.
5. Review-Fix Loop
Run at most three iterations over the entire accumulated diff.
- Map affected callers, consumers, implementers, importers, tests, and documented contracts.
- Re-read the full diff and affected code with the default assumption that the changes are wrong. If an isolated reviewer is available, provide only project conventions, the full diff, and the affected-code list—not fix rationale or earlier findings. Otherwise perform the same fresh-context review inline.
- Try to construct realistic failures for:
- caller or compatibility breakage; - authorization, tenant isolation, or data-loss problems; - null/empty values, concurrency, partial failure, and resource bounds; - missing or non-discriminating tests; - inconsistent fixes across items.
- Report findings with file, line range, code evidence, and impact. On iterations one and two, fix all in-scope findings, rerun focused verification, then restart from the full diff.
Only observable failures and documented-contract violations are findings. Publication requires the Step 4 verification gate plus a clean full-diff verdict after the latest modification. If iteration three finds anything, do not modify or publish; stop and report the findings. Any further fix requires a newly authorized review cycle, so no final change can bypass a clean adversarial review.
6. Commit and Obtain Publication Approval
- Re-fetch the exact head repository URL, full head ref, and remote head before commit preparation. Stop if the repository/ref mapping or SHA changed.
- Compare both the worktree and index with the preflight baseline and identify attributable paths and hunks. Never stage a baseline hunk.
- If uncommitted attributable code changes exist, show the final diff. Follow the trusted-base repository's commit-approval rule in every authorization mode. When it requires confirmation after the final diff, wait for that explicit confirmation; preflight or standing authorization cannot replace it. Otherwise, in guarded mode obtain explicit commit approval unless the current request already authorized commit, and in autonomous mode require every staged candidate to be attributable and
commit to be present in the standing envelope before proceeding. If no uncommitted task change exists, record that no new commit approval or commit is required.
- Follow repository commit rules; otherwise use Conventional Commits. Do not include review metadata.
- If approved uncommitted task changes exist, stage only those attributable hunks. Immediately before commit, inspect the complete
git diff --cached and require every staged hunk to be attributable and approved; if any baseline staged entry is present, use an isolated checkout with its own index or stop. Never unstage or overwrite baseline index entries to make this check pass. Re-read the staged diff, create the approved commit or commits, then confirm that every remaining uncommitted hunk belongs to the preflight baseline or stop.
- Capture the final local SHA and show every commit plus the complete
remotehead..finalsha diff. Prove that every commit and hunk is attributable to this task. In autonomous mode, replace the envelope's pending final SHA with this exact SHA only after proving that every included commit and hunk is attributable to the current task. When the workflow re-enters for new feedback on the same PR/MR and requires new attributable code changes, first invalidate the prior publication/final-SHA binding and restore final SHA: pending, but only if the PR/MR identity, authoritative source repository, full head ref, and recorded envelope scope are unchanged; then repeat the complete commit/hunk attribution proof before binding the new exact final SHA. This same-scope rebinding does not require renewed authorization. Revalidate that the PR/MR identity, authoritative source repository, full head ref, and recorded envelope scope still equal the envelope before initial binding or rebinding. Any identity, repository, ref, or scope mismatch invalidates standing push authority and triggers stop-and-report; do not ask for replacement authorization in the same execution. If no code change is needed and local HEAD already equals remote head, use publication mode: no-push; otherwise use publication mode: push. Never create an empty commit or publish an unattributed ahead commit.
- In
publication mode: push, materialize the exact final SHA, authoritative head repository URL, and full head ref. Follow the trusted-base repository's push-approval rule in every authorization mode. When it requires a separate explicit push request or confirmation, obtain it for that exact tuple; neither commit approval nor the standing envelope replaces it. Otherwise, in guarded mode obtain explicit push approval for that tuple, and in autonomous mode require the tuple to match the standing envelope after its final-SHA binding before proceeding; a mismatch invokes stop-and-report. In publication mode: no-push, record that no push approval or refspec exists.
7. Synchronize Replies and PR/MR Context ⛔ BLOCKING
- Repeat the complete Step 2 fetch and directly re-fetch every processed thread/discussion. Compare canonical item IDs and fingerprints bidirectionally with the ledger before any remote write. Merge new or edited items, preserve deleted external items as removed history, and return to triage on any new, edited, deleted, or missing external item or action without a decision. Return to Step 7 planning without writing if an expected workflow-emitted effect is missing or changed.
- Re-fetch the exact head repository URL, full head ref, remote head, title, and body. Record the remote head as
expectedoldsha bound to that URL and ref. Stop on any unexpected change.
- Derive the desired PR/MR title and body from repository templates and the final repository diff/history. Follow the repository's PR/MR title convention when one exists; otherwise use Conventional Commits format. Update only when needed; never add review metadata or reference files outside the repository.
- Build a candidate publication plan with the final SHA, expected old SHA, exact reply operations, current metadata, expected critical-section entry metadata, expected final metadata after any deferred write, which metadata depends on the pending SHA, aggregate thread dispositions, the ordered transition operations and their inverse compensations, and the transition-plus-compensation time bound.
- Immediately before the first remote write, rebuild the complete known-trigger inventory from the same authoritative sources used at preflight, now including every exact candidate-plan operation. Compare it with the preflight evidence and re-run the ordering decision. Stop without writing if evidence changed for an event that can no longer be ordered safely. Otherwise freeze the refreshed inventory and safe order into the publication plan. Do not call this plan the frozen ledger: authoritative pre-push replies still need their own item rows and publication results.
Before any lease operation or other remote write, freeze a mode-neutral mutation authorization ledger with one row per planned mutation. Cover push; publication-lease acquire, renew, and release; reply create, edit, and compensating-create; metadata update and restore; Resolve/Reopen and every inverse; manual trigger; and duplicate delete. Each row records operation kind, exact target, payload or desired state, inverse compensation when applicable, authorization source, authorization scope, and eventual result. A lease row's exact target is the current PR/MR-scoped provider/repository-stable-ID/number key. In guarded mode, require every row to be covered by explicit preauthorization in the current request or explicit confirmation of that exact ledger. In autonomous mode, require every row except duplicate delete and a repository-checkpoint-approved push to match the standing envelope; record the exact post-diff or separate-push confirmation as the authorization source for any operation excluded from the envelope by repository rules. A duplicate delete instead requires the independent exact-ID grant below. The ledger records authorization and never creates or expands it. An unlisted mutation is prohibited. Before any operation substitution or compensation, refresh or add its exact row, re-run trigger ordering, re-match its authorization source and scope, and record that result; return to this gate before writing if the frozen ledger changes. All lease, optimistic-guard, reconciliation, compensation, verification, and completion requirements remain mandatory.
Before the first remote write, revalidate the acquire row and acquire the recorded exclusive publication lease only when its acquire, renew, and release operations are each authoritatively proven non-triggering. Record its owner token and expiry, renew it before expiry only through a revalidated renew row, and release it authoritatively after final verification or after recording every compensation on an early stop. If no eligible lease is available, use the lease-free path. If lease ownership is lost, stop all writes and reconcile remote state. Without a lease, freeze the optimistic guard defined in Concurrent publication safety and record the immediately revalidated preconditions for every write. For each triggering or unknown non-idempotent write, require the frozen order to designate it as the next trigger-safe operation and never retry it without provider idempotency or documented coalescing. Require every other write to be proven non-triggering, suppressed, coalesced, or safely convergent. Otherwise stop without mutating remote state.
After the lease or lease-free guard is established, publish context in the frozen trigger-safe order. In both publication modes, execute only context writes proven non-triggering or covered by a documented mechanism that prevents those writes from accepting or scheduling a review trigger, defers trigger acceptance until the final SHA is remote and every planned context write is authoritative, and binds the resulting run to that SHA and context. Keep a covered event classified as triggering or unknown and record the named later operation that releases the trigger. A delayed run start after an earlier trigger is not sufficient. When exactly one context write lacks that guarantee and push is proven non-triggering or the mode is no-push, freeze that operation and defer it to Step 8. Do not send any other unsuppressed triggering or unknown context write in this step.
Every workflow-authored reply, including a required status reply to a Context item, consists of the exact human-readable reply, one LF, and one final marker line:
resolve-review-comments:v1 {"platform":"github","item_kind":"review-thread-comment","item_id":"<full-id>","body_sha256":"sha256:<source-hash>","disposition":"Implement","final_sha":"<full-sha>","supersedes_reply_id":null}
Use github or gitlab, the canonical kind and full ID, the current source fingerprint, the marker-covered SHA, the aggregate item disposition (including Superseded, Mixed, or Context for a required status reply), and the prior full reply ID when compensating. Normally the marker-covered SHA is the workflow final SHA. When an eligible ancestor marker is reused, preserve its original SHA and record the current workflow final SHA separately in the ledger. The marker makes an exact successful reply reusable across retries.
Before each reply:
Treat reply create, edit, compensating create, and duplicate delete as distinct frozen trigger-inventory and mutation-authorization-ledger operations. Re-run both gates before substituting one operation for another.
- Re-fetch the exact item/thread and complete target reply collection.
- If the source changed or is missing, return to triage.
- If the exact intended reply text and marker already exist from the authenticated writer and the marker-covered SHA is the current remote head or the exact pending local SHA based on that remote head, reuse the reply ID and do not post again.
- If a marker from the same writer covers the same item revision, disposition, and still-accurate human-readable reply but its SHA is only an ancestor of the current head, inspect the intervening diff and current implementation. Reuse it unchanged only when the recorded disposition and reply remain true; preserve its marker-covered SHA in the ledger.
- If a marker from the same writer covers the same item revision but the intended text or disposition changed, or the ancestor check failed because the newer final SHA invalidated the reply, edit that reply when supported and permitted by the frozen trigger order. Otherwise publish one permitted compensating reply whose
supersedesreplyid is the prior full reply ID. Record one acyclic chain with one terminal reply; stop on forks, cycles, or multiple terminal replies.
- Otherwise post once and record the returned full reply ID.
- After every successful or ambiguous create, re-fetch the complete target replies and match exact body + marker + authenticated author. One match is authoritative. With multiple matches, stop and report every full canonical ID without creating, editing, deleting, or retrying another reply. Delete exact duplicates only under an independent exact-ID duplicate-delete grant naming the exact retain/delete IDs and recorded as that ledger row's authorization source. In guarded mode, obtain explicit confirmation for those exact IDs unless the current request already grants them. The default autonomous envelope does not authorize deletion; in autonomous mode, proceed only when the current request already contains that separate exact-ID grant, otherwise stop-and-report without asking. The grant does not expand the standing envelope. Immediately before each granted deletion, refresh the target, revalidate trigger order and the ledger row, delete only an authenticated-writer exact duplicate, and verify the granted retained reply is the unique match.
- On timeout or another ambiguous response, continue the complete reconciliation through the recorded comment-visibility bound. Reuse one unique match. With zero matches and an unchanged source/target, make one identical retry only when the reply event is proven non-triggering or uses the same provider idempotency key, then repeat step 7; otherwise stop. Never make a second retry.
Reply rules:
These rules govern reply content only. Keep the aggregate thread disposition frozen from Step 3 and execute every Resolve/Reopen mutation only in Step 8.
- Implement: state every Implement result and, when the item also has Superseded actions, their current-code or intervening-diff evidence. If sent before push, identify the final local SHA as the prepared fix and state that remote publication will be verified separately; use wording that remains true after a later push, and do not edit or post a second reply solely to announce publication. If deferred until after remote-head confirmation, say the change is published in the final SHA. Never claim an unpushed SHA is remote.
- Superseded: cite the current code or intervening diff that already removed the finding and state that no new change was required.
- Skip: state the technical reason.
- Mixed: state every applicable Implement result, Superseded current-code or intervening-diff evidence, and Skip reason in one reply.
- Clarify: cannot reach publication until resolved.
- Context: do not reply unless a status response is required; when required, use the same marker and replay-safety procedure with disposition
Context.
After every context write, record its authoritative result and any newly observed automation run or bot item. For every authoritative workflow-authored reply, update the source item's publication result and upsert exactly one reply row by canonical item ID as Context with origin: workflow-emitted and its source item key. If observed behavior contradicts the recorded event classification, stop every forward publication mutation, add the event to the trigger inventory, and perform a complete read-only re-fetch. Permit only the frozen safe compensation in the pre-publication abort procedure, then release the lease when permitted and report that the already delivered event may have exposed partial context. Do not restart this step or Step 7 in the same execution; replanning cannot repair an already accepted trigger.
Proceed only after every non-deferred known reply and required metadata update is authoritative and the single deferred trigger operation, if any, is frozen exactly in the publication plan. Re-fetch the complete current review context and metadata and reconcile every non-deferred planned effect with a bidirectional canonical-ID comparison. If any external item is new, edited, deleted, or missing, or any current external action lacks a decision, preserve removed rows as history and return to triage without freezing publication state. If an expected workflow-emitted effect is missing or changed, return to the start of Step 7 without rewriting history or silently recreating it. Otherwise freeze the critical-section ledger and metadata baselines. The critical-section ledger must include exactly one row for every current item and every pre-push workflow-emitted reply; keep the deferred operation separate until Step 8 executes and records its effect.
Define one pre-publication abort procedure for every stop or return after a Step 7 remote write and before push success or no-push confirmation. For each title/body value recorded in the publication plan as depending on the pending SHA, refresh the exact field and restore its recorded pre-write value only when the current value still equals this workflow's desired value, the compensation is permitted by the refreshed trigger order and a re-matched exact ledger row, and any acquired publication lease is still owned and valid. A lost lease or changed lease-free guard permits reconciliation reads but no compensation write. Verify every attempted restoration authoritatively. When a safe restoration is unavailable, make no compensating write and record the exact stale metadata value in the stop report. A truthful prepared-fix reply does not require deletion; reuse or supersede it on the next Step 7 entry. Invoke this procedure before leaving Step 7 or the pre-publication portion of Step 8 for any drift, lost guard or lease, changed trigger evidence, or failed push.
8. Push and Transition Threads
Before entering either publication mode:
- Prove that any held publication lease remains valid for a recorded combined upper bound covering the following freshness reads, the push attempt and allowed push reconciliation, any deferred write, all planned transitions, their reserved inverse-compensation budget, and narrow reconciliation. When renewal is needed, revalidate its exact-key ledger row before renewing; never renew inside the post-push critical section.
- Repeat the complete Step 2 collection and directly re-fetch every processed thread/discussion. Compare canonical item IDs and fingerprints bidirectionally with the critical-section ledger, treating its recorded workflow-emitted items as expected effects. Require every current external action to have a decision and every required non-deferred context result to remain authoritative. On any new, edited, deleted, or missing external item, preserve removed rows as history and return to triage without pushing. On a missing or changed expected workflow-emitted effect, return to Step 7 without pushing.
- Re-fetch the exact head repository URL, full head ref, remote head, title, and body. Require the repository/ref mapping to be unchanged, the remote head to equal
expectedoldsha, and title/body to equal the frozen expected critical-section entry metadata. Return to preflight on repository, ref, or head drift and Step 7 on metadata drift.
- Rebuild the complete known-trigger inventory from the same authoritative sources used at preflight and compare it with the frozen publication plan. Require every planned event classification, actor/command filter, matching rule, and suppression, batching, or coalescing guarantee to remain unchanged. Re-run the ordering decision with the current inventory. If evidence or classification changed for an event already sent in Step 7, stop before push and record that the event may already have breached the ordering guarantee; do not claim that replanning can repair it. If drift affects only unsent events, return to Step 7 when a safe order remains, or stop when none exists. This is the final broad trigger-configuration read.
- If a lease is held, immediately before push or no-push confirmation re-check that its remaining lifetime still covers the recorded push-and-critical-section bound, including the reserved inverse-compensation budget. If it does not, revalidate the exact-key renew row, renew the lease, and repeat steps 2–5; do not publish from the earlier snapshot.
- Repeat the complete Step 2 collection and directly re-fetch every processed thread/discussion. Require a bidirectional match with the critical-section ledger and freeze the canonical item IDs and fingerprints as the final pre-publication linearization snapshot. Re-fetch the exact repository/ref/head/title/body guard immediately afterward. On any drift, return to preflight, Step 7, or triage as applicable. After this snapshot, perform only the narrow reads needed to revalidate the exact trigger operation and then execute it. Record whether an atomic provider revision or a lease covering every review-context writer protects the snapshot; otherwise explicitly record the external-writer race described by Review-context linearization and do not claim atomic exclusion.
For publication mode: push:
- Revalidate the unchanged Section 6 exact tuple and its push row in the mutation authorization ledger. Require the previously recorded approval for that exact tuple when the trusted-base repository mandates a separate push checkpoint. Otherwise, in guarded mode require the recorded approval and in autonomous mode require the tuple to match the final-SHA-bound standing envelope. Any tuple or authorization change invokes stop-and-report without asking again.
- Immediately before sending, resolve and verify the exact
finalsha object, authoritative head repository URL, full head ref, and expectedoldsha. Push an exact-object refspec equivalent to <finalsha>:<fullheadref> to that URL with a conditional lease bound to expectedoldsha. Never infer the source object from the current branch or HEAD, never infer the destination from a same-named local branch, and never fall back to an unconditional force push.
- On an ambiguous push result, inspect the authoritative remote head before any other mutation. If the final SHA is present, record success. If the expected old SHA is unchanged and no retry has occurred, make one identical leased retry and inspect the remote head once more.
- After that inspection, any state other than the final SHA is a push failure; never retry again. Invoke the pre-publication abort procedure, then report both the push failure and every compensation result. Do not transition threads.
For publication mode: no-push, send no push and confirm that the remote head still equals the final SHA.
Enter the post-push critical section immediately after push success or no-push confirmation:
Maintain a stack of every transition that authoritatively reached its desired state, together with its observed pre-transition state and frozen inverse operation. On any transition-sequence abort:
- Record every not-yet-attempted transition as cancelled with the exact reason.
- Directly re-fetch the current or ambiguous transition and record its authoritative state when available.
- Before each inverse, re-fetch the remote head, metadata, and exact item/thread state and re-match the inverse's exact ledger row. Compensate only while those values match the frozen preconditions, the current state still equals this workflow's recorded desired post-transition state, the frozen inverse remains permitted by the trigger order and authorization ledger, and no observed response has contradicted that classification. With a valid publication lease, restore eligible state changes in reverse order to their observed pre-transition states. Without a lease, also revalidate every applicable optimistic-guard value available through the allowed narrow reads before using the same inverse path. Verify and record every compensation trigger and result.
- If lease ownership is lost, a lease-free precondition changed, or any state remains indeterminate, issue no further mutation for that state. Reconcile every processed thread directly, close the section, and report the partial or unknown remote state instead of claiming rollback or completion.
Do not renew a publication lease inside this section. If ownership is lost or its recorded expiry is reached despite the pre-push check, invoke the abort procedure with reason cancelled-by-lease-loss; lease loss permits reconciliation reads but no compensation writes. In lease-free mode, invoke the abort procedure with reason cancelled-by-context-change when a frozen precondition changes; unchanged preconditions permit only the guarded inverse operations above.
- Re-fetch the remote head, title, and body. Require the remote head to equal the final SHA and title/body to equal the frozen expected critical-section entry metadata.
- Perform one complete review-context freshness read and compare canonical item IDs and fingerprints bidirectionally with the critical-section ledger.
- On remote-head drift, metadata drift, an external item addition/edit/deletion, or a missing/changed expected workflow-emitted effect, record every not-yet-attempted transition as
cancelled-by-context-change and close the critical section. Return to preflight for head drift, Step 7 for metadata or workflow-effect drift, or triage for external item drift; do not execute a transition against the stale ledger.
- Apply the transition classification and serial order frozen by the final pre-push trigger-inventory check. Do not inspect workflows or integration metadata in the critical section. If an allowed response or reconciliation read itself contradicts a frozen classification, invoke the abort procedure with reason
cancelled-by-trigger-evidence-change. Record every triggering or unknown transition as a separate event for Step 9 reconciliation.
- If Step 7 deferred one selected context trigger, first repeat the complete Step 2 collection, directly re-fetch every processed thread/discussion, and require a bidirectional match with the active critical-section ledger. Freeze this as the deferred-operation linearization snapshot. Then refresh its exact operation target and revalidate its exact ledger row without writing: the source item/thread plus complete target replies for a reply, or title/body for metadata. Require the frozen source and pre-write values. Immediately afterward, re-fetch the remote head, title, and body; require the remote head to equal the final SHA and the metadata to equal the active frozen baseline. Then execute the operation by kind without an intervening read, and send no other deferred context write. Record whether an atomic provider revision or a lease covering every review-context writer protects the snapshot; otherwise preserve the external-writer race disclosure required by Review-context linearization:
- Reply: execute once, require an authoritative result or reconcile one unique exact write, then record the trigger occurrence and upsert exactly one workflow-emitted row by canonical item ID in both the item ledger and active critical-section ledger. - Metadata: execute once, and require an authoritative result or re-fetch the exact desired value after an ambiguous response. Record the trigger occurrence and metadata result outside the item ledger; a metadata write does not create a workflow-emitted comment item. After the deferred operation succeeds, make the frozen expected final metadata the active metadata baseline for every remaining guard. If it does not become authoritative, record every planned transition as cancelled-by-deferred-context-failure, close the critical section, and stop; do not attempt a thread transition.
- Process every planned state-changing Resolve/Reopen mutation serially in the frozen order; do not send a mutation for No-op, and do not execute any transition unless every preceding transition reached its desired state. Immediately before each transition, refresh the remote head, title/body, and exact thread and revalidate the transition's exact ledger row; verify that all still match the critical-section ledger and expected post-publication state. When a lease is held, also require current ownership and enough remaining lifetime for the current mutation plus the reserved inverse compensation. On any mismatch or insufficient lifetime while ownership remains valid, invoke the abort procedure; return to preflight for head drift, Step 7 for metadata drift, or triage for item/thread drift after the section closes.
- Use a provider conditional mutation when available. Otherwise use the portable guarded path: exact refresh → one mutation → authoritative response or direct full-ID re-fetch. This detects conflicts but does not claim atomic exclusion from an independent writer.
- After each successful or ambiguous mutation response, re-fetch the full thread/discussion. Desired state means success: append the transition to the success stack. Unchanged state after a definitive retryable failure permits one bounded retry and one more direct re-fetch only when the transition is proven non-triggering or the provider applies the same idempotency key or documented coalescing; otherwise invoke the abort procedure without retrying. If the desired state is still absent, invoke the abort procedure with reason
cancelled-by-transition-failure; an indeterminate state uses cancelled-by-ambiguous-transition.
- If head, metadata, or item drift appears after any mutation changed state in this critical section, invoke the abort procedure and return to preflight, Step 7, or triage after the section closes.
- Record every transition success, failure, ambiguity, cancellation, or compensation before leaving the section. Do not interleave unrelated work.
GitHub uses GraphQL resolveReviewThread / unresolveReviewThread with the full thread node ID. GitLab updates the full discussion ID with resolved=true / false. For both providers, verify the requested state from the mutation result or a direct full-ID re-fetch; HTTP success alone is not the final state check.
After the critical section closes, gate each planned manual review trigger against delayed automatic work:
- Derive or reuse the Step 9 absolute deadline. Enumerate and classify every related run/output by the Step 9 rules. Wait for every current
must-reconcile run and every active must-pass run to become terminal, reconcile their complete outputs, and repeat the complete Step 2 collection. Any such run still active at the deadline blocks manual dispatch.
- Exhaust the complete related run/output collection and complete Step 2 review context until all earlier triggering and sent-
unknown events are accounted for and the run/output set remains unchanged through the recorded event-delivery and run-queue bounds. Classify every newly observed related run immediately. Return to item 1 for every new must-pass or must-reconcile run: wait if it is active, or reconcile its complete output if it is already terminal.
- From the latest terminal run/output observation, wait the recorded comment-visibility bound without resetting the Step 9 absolute deadline, then repeat the complete run/output enumeration and Step 2 collection. If the bound cannot complete within the deadline, block manual dispatch. Return to item 1 for any new related run; return to triage for any new or changed external item or
automation-output. Preserve deleted external items as history. If a required workflow-emitted effect no longer matches the ledger, return to Step 7. Only a visibility-stable, authoritatively matched terminal run/output may satisfy the manual trigger and cause the dispatch to be skipped.
- Otherwise confirm the remote head and required context again, revalidate the manual trigger's exact ledger row, dispatch the trigger once, and record the authoritative acceptance/result. If the response includes a run/output ID, record it; otherwise leave the accepted event pending for Step 9 and do not retry merely because an ID was not returned. When the trigger creates a PR/MR comment or note, resolve its canonical item ID from the authoritative response or one unique exact author/body match in the recorded creation window, then upsert it in the item ledger as
Context with origin: workflow-emitted and the manual-trigger event key. If an accepted comment/note trigger is not visible yet, record its expected author, exact body, creation window, and event key so Step 9 can reconcile it as an expected effect rather than an unseen external item. Do not append a processing marker when command syntax must remain exact.
- On an ambiguous response, reconcile the complete run/output collection through the recorded event-delivery and run-queue bounds. Reuse one unique matching run/output; stop and report multiple matches. With zero matches, make at most one identical retry only when the provider honors the same idempotency key or documented coalescing guarantees one resulting run, then reconcile again. Otherwise stop. Never make a second manual-trigger attempt.
9. Verify Automation and Completeness
At the first post-publication automation observation, including the pre-manual-trigger gate in Step 8, derive one absolute deadline from the finite preflight budget. Reuse it on every re-entry; a new item, run, or trigger must not reset it.
- Repeatedly enumerate related runs and bot outputs from the preflight baseline forward, exhausting pagination. Include push, deferred-context, transition, and manual-trigger outcomes. Use the recorded boundary classifications, then re-evaluate every observed run on every enumeration and apply the evidence-driven provisional classification and upgrades required by Step 1.
- Account for every recorded triggering event and every sent
unknown event with a uniquely matched run/output or authoritative evidence that it was ignored, suppressed, or coalesced into a named observed run. If a run reveals that an event classified non-triggering or unknown actually triggered early, record the ordering breach and do not claim the synchronization guarantee held.
- Keep enumerating until all triggering and sent
unknown events are accounted for and the related run/output set remains unchanged through the recorded event-delivery and run-queue bounds. Re-evaluate every observed related run with all currently available authoritative trigger and reviewed-SHA evidence, including evidence first exposed by a later terminal output. Immediately upgrade an existing historical or must-reconcile run to must-pass when new evidence establishes a publication or final-SHA association; otherwise preserve its existing boundary classification. Classify a newly observed publication-associated run as must-pass; classify every other newly observed run as must-reconcile until authoritative evidence permits the upgrade. Never downgrade a must-pass run. A newly observed run or any classification upgrade restarts this stability observation without resetting the absolute deadline.
- Wait for every
must-pass and must-reconcile run to become terminal within the absolute deadline, then repeat Steps 1–3 to catch delayed or replacement runs. Require the provider/workflow’s documented acceptable conclusion only for must-pass; historical and must-reconcile runs require complete output reconciliation regardless of conclusion. Treat a failed/cancelled must-pass run as superseded only when authoritative concurrency or retry metadata names a specific replacement in the observation set and that replacement has an acceptable terminal conclusion; otherwise record it as incomplete.
- After the terminal run/output set is stable, re-fetch the exact head repository URL, full head ref, remote head, title, and body; require the repository/ref mapping to remain unchanged, the remote head to equal the final SHA, and title/body to equal the active metadata baseline. Then repeat the complete Step 2 collection and directly re-fetch every processed thread/discussion, including resolved ones.
- Resolve every pending workflow-emitted manual comment/note to one canonical item ID and upsert its
Context row before comparing canonical item IDs, revisions/fingerprints, replies, and thread states with the ledger. Account for this workflow’s own replies, comment/note manual triggers, and transitions as expected effects.
- After the latest related run/output and prior head/metadata/review snapshot are visible, wait the recorded comment-visibility bound and repeat the run/output enumeration, exact repository/ref/head/title/body fetch, complete review collection, and processed-thread fetch. Compare canonical item sets and fingerprints bidirectionally. A new run restarts this section at item 1. Head or repository/ref drift returns to preflight; metadata or expected workflow-effect drift returns to Step 7. If the two complete head/metadata/review snapshots differ, treat the later snapshot as current and repeat within the same absolute deadline.
- Return every new, edited, deleted, or missing external item to triage, preserving removed rows as history. If no code change is required, use
publication mode: no-push; do not create an empty commit. Reuse successful reply IDs and markers.
Completion requires:
- every list query has terminal pagination evidence;
- every current item has a ledger row and every independent action record has a decision;
- every planned workflow-emitted reply or manual-trigger comment/note has one authoritative item row;
- every executed required check passed and no known failing check remains; in guarded mode, an unavailable required check may instead have an exact unverified scope and impact with explicit user acceptance, while autonomous mode requires every required check to have actually passed;
- every executed mutation matched its exact mutation-authorization-ledger row; in autonomous mode, each general operation matched the standing envelope's PR/MR, operation, repository, ref, and final-SHA scope, each duplicate delete matched an independent exact-ID retain/delete grant without expanding that envelope, and each publication-lease lifecycle mutation matched the exact current PR/MR-scoped provider/repository-stable-ID/number key; every substitution and compensation was separately re-matched and recorded, and any pending lease release already has an authorized exact-key row;
- no review trigger caused by this workflow's planned publication events was accepted or released before the final SHA was remote and every workflow-planned context write from the frozen snapshot other than the atomic operation emitting the final trigger was authoritative; historical and
must-reconcile runs remain governed by their reconciliation requirements, while any earlier covered write has evidence that it could not accept or schedule a trigger, that the named later operation released the trigger against the final SHA and frozen publication context, and that any unsuppressed selected context trigger was frozen before publication, executed only after the final SHA was remote, and verified authoritative before transitions;
- an exclusive publication lease covered all triggering or unknown non-idempotent writes, or every lease-free write satisfied its frozen preconditions and every triggering/unknown non-idempotent write was sent only at its frozen trigger-safe position without an unsafe retry;
- no unrelated work occurred between push confirmation and recorded transition outcomes;
- the remote head, replies, metadata, and thread states match the ledger;
- every recorded triggering event and sent
unknown event has an authoritative run/output, ignored, suppressed, or coalesced outcome;
- every available
historical, must-reconcile, and must-pass output has a current automation-output ledger row or an authoritative link to its canonical comment/note; every unavailable historical output has an authoritative tombstone linked to a terminal, acceptable, fully reconciled equivalent final-SHA must-pass output; every must-reconcile run is terminal and reconciled; every must-pass run is terminal with an acceptable conclusion and reconciled; and no related run/output appeared during the final queue-stability window;
- the final two complete repository/ref/head/metadata/review snapshots are stable.
After all other completion conditions hold, execute the authorized release row for any publication lease, record and verify its result in the mutation authorization ledger, re-evaluate the mutation-authorization completion condition, and verify that this workflow no longer owns the lease before claiming success. If no lease was acquired, record release as N/A. If any condition or lease release fails, report the exact incomplete item, transition, run, query, or lease state instead of claiming success.