-
Notifications
You must be signed in to change notification settings - Fork 6
docs(loop): plan concurrent PR review reconciliation #187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
fd153b0
docs(loop): plan concurrent PR reconciliation
Abiorh001 53b5596
docs(loop): record WS-ENG-007 plan review
Abiorh001 d80aa1a
Merge remote-tracking branch 'origin/main' into codex/ws-eng-007-plan
Abiorh001 32f5a87
docs(loop): close WS-ENG-007 review ambiguities
Abiorh001 1a0638d
docs(loop): record PR 187 review repairs
Abiorh001 806b14d
docs(loop): disambiguate finding schema version
Abiorh001 b09527f
docs(loop): bind exact-head CI repair review
Abiorh001 da29dea
Merge branch 'main' into codex/ws-eng-007-plan
abiorh-claw 34ddac1
docs(loop): rebind WS-ENG-007 to latest main
Abiorh001 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
...nt-loop/initiatives/WS-ENG-007-concurrent-pr-review-reconciliation/CHUNK_MAP.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Chunk Map: WS-ENG-007 - Concurrent PR Review Reconciliation | ||
|
|
||
| | Order | Chunk | Purpose | Risk | State | | ||
| |---:|---|---|---:|---| | ||
| | 1 | `WS-ENG-007-01` | Add deterministic reviewed-patch identity and conservative base-delta review preservation | L1 | Proposed | | ||
| | 2 | `WS-ENG-007-02` | Add structured reviewer-track and upstream-finding reconciliation | L1 | Blocked on 01 merge and explicit start | | ||
| | 3 | `WS-ENG-007-03` | Add merge-group CI parity and queue-readiness proof | L1 | Blocked on 02 merge and explicit start | | ||
|
|
||
| Each chunk is one PR and stops after merge. Every successor requires a separate | ||
| explicit signed start. |
47 changes: 47 additions & 0 deletions
47
...nt-loop/initiatives/WS-ENG-007-concurrent-pr-review-reconciliation/DECISIONS.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # Decisions: WS-ENG-007 - Concurrent PR Review Reconciliation | ||
|
|
||
| ## D1 - CI always reruns on the combined tree | ||
|
|
||
| Review preservation never preserves CI results across a base advance. | ||
|
|
||
| ## D2 - Preserve internal tracks, not human approval | ||
|
|
||
| GitHub approval and explicit human merge ownership remain governed by branch | ||
| protection and repository policy. | ||
|
|
||
| ## D3 - Effective patch identity is mandatory | ||
|
|
||
| File-path disjointness is insufficient. Preservation requires the same | ||
| canonical PR-authored delta and declared boundary non-impact. | ||
|
|
||
| ## D4 - Unknown means stale | ||
|
|
||
| Missing objects, ambiguous dependencies, conflicts, or unsupported merge shapes | ||
| invalidate conservatively. | ||
|
|
||
| ## D5 - Upstream resolution requires a predicate | ||
|
|
||
| A finding is resolved upstream only when its closed resolution predicate is | ||
| deterministically `true` on the exact candidate tree. `false` remains | ||
| `still_valid`; `unknown` makes every reviewer track stale because the affected | ||
| set is not proven. | ||
|
|
||
| ## D6 - Merge queue comes last | ||
|
|
||
| Do not enable merge queue until both required workflows and evidence gates prove | ||
| `merge_group` parity. | ||
|
|
||
| ## D7 - One shared Git evidence implementation | ||
|
|
||
| Extract strict tree/delta primitives for reuse; do not create a second parser | ||
| or rely on fuzzy patch application. | ||
|
|
||
| ## D8 - Closed repository-owned boundaries | ||
|
|
||
| PRs cannot declare their review surface. A versioned policy graph derives path | ||
| classes, transitive impacts, and reviewer escalation. | ||
|
|
||
| ## D9 - Detection and lifecycle states differ | ||
|
|
||
| `unknown` is a reconciliation result; `track_stale` for every track is its | ||
| mandatory reviewer lifecycle consequence. Neither is a claimant override. |
61 changes: 61 additions & 0 deletions
61
...nt-loop/initiatives/WS-ENG-007-concurrent-pr-review-reconciliation/DISCOVERY.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| # Discovery: WS-ENG-007 - Concurrent PR Review Reconciliation | ||
|
|
||
| Discovery was performed read-only against trusted `main` at merge | ||
| `9033a97a4be6d762cae4b210018ef81a079395c2`. | ||
|
|
||
| ## Repository behavior found | ||
|
|
||
| - Branch protection requires `agent-gates` and `test`, uses strict up-to-date | ||
| checks, enforces protection for administrators, requires one approval, and | ||
| dismisses stale reviews. | ||
| - `.github/workflows/backend.yml` and `agent-gates.yml` run for pull requests; | ||
| neither declares `merge_group`. | ||
| - `scripts/check_internal_review_evidence.py` records one reviewed SHA and | ||
| rejects every non-evidence path changed between that SHA and the PR head. | ||
| - The evidence gate does not distinguish PR-authored changes from a later base | ||
| merge, does not bind a patch manifest, and cannot preserve reviewer tracks. | ||
| - Loop-memory merge records already preserve base/head/tree identities and | ||
| deterministic deltas, providing conventions that can be reused without | ||
| making generated memory a pre-merge authority. | ||
|
|
||
| ## Relevant files | ||
|
|
||
| | Path | Relevance | | ||
| |---|---| | ||
| | `scripts/check_internal_review_evidence.py` | Current coarse reviewed-SHA invalidation. | | ||
| | `scripts/workstream_agent_gate.py` | Computes changed files for PR gate routing. | | ||
| | `scripts/test_agent_gates.py` | Deterministic policy tests and synthetic repositories. | | ||
| | `.github/workflows/agent-gates.yml` | Required policy check; lacks merge-group trigger. | | ||
| | `.github/workflows/backend.yml` | Required backend/fan-in check; lacks merge-group trigger. | | ||
| | `.agent-loop/templates/INTERNAL_REVIEW_EVIDENCE.md` | Human-readable review provenance template. | | ||
| | `.agent-loop/templates/PR_TRUST_BUNDLE.md` | Human merge summary and CI integrity surface. | | ||
| | `.agent-loop/policies/repository-engineering-policy.md` | Canonical review and merge boundaries. | | ||
| | `AGENTS.md` | Mandatory agent behavior. | | ||
|
|
||
| ## Important distinction | ||
|
|
||
| GitHub approval dismissal and internal reviewer validity are separate. GitHub | ||
| may require a renewed human approval after a branch update. This initiative | ||
| does not bypass that rule; it prevents unnecessary internal agent fanout when | ||
| the reviewed patch is provably unchanged. | ||
|
|
||
| ## Closed initial boundary vocabulary | ||
|
|
||
| The repository-owned v1 graph classifies every tracked path into one or more of | ||
| `workflow_ci`, `auth_security`, `payment_compensation`, `database_schema`, | ||
| `shared_interface_contract`, `generated_policy_process`, `product_runtime`, | ||
| `tests_coverage`, or `docs_only`. Unmatched, malformed, or ambiguously mapped | ||
| paths are `unknown`. | ||
|
|
||
| Transitive edges are repository-owned: workflow/CI reaches tests/coverage and | ||
| generated process; database/schema reaches consuming runtime, interfaces, and | ||
| tests; shared interfaces reach consuming runtime/tests; auth and payment reach | ||
| their runtime, interfaces, migrations, audit, and tests; generated process | ||
| reaches workflows, schemas, templates, and gates. `unknown` invalidates all | ||
| tracks. A PR never authors or narrows this graph. | ||
|
|
||
| ## Unknowns reserved for later human administration | ||
|
|
||
| - Exact GitHub merge-queue repository-setting API behavior. | ||
| - Hosted context behavior after queue enablement. These block administrative | ||
| enablement, not repository-side parity planning. |
81 changes: 81 additions & 0 deletions
81
.agent-loop/initiatives/WS-ENG-007-concurrent-pr-review-reconciliation/INTENT.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| # Intent: WS-ENG-007 - Concurrent PR Review Reconciliation | ||
|
|
||
| ## Problem being solved | ||
|
|
||
| When one concurrent PR merges, another open PR must be validated against the | ||
| new `main`. Today the repository correctly reruns strict CI, but its internal | ||
| review evidence is invalidated coarsely by commit ancestry. Unrelated upstream | ||
| changes can therefore trigger full reviewer fanout, while a finding already | ||
| fixed upstream can remain misleadingly open. | ||
|
|
||
| ## Why this work matters | ||
|
|
||
| Workstream permits distinct initiatives to run concurrently. That concurrency | ||
| must remain safe without making every merge restart every other initiative's | ||
| human-agent review loop. | ||
|
|
||
| ## Current behavior | ||
|
|
||
| - Required GitHub checks are strict and require an up-to-date branch. | ||
| - GitHub dismisses stale approvals after new commits. | ||
| - Internal evidence binds one reviewed code SHA and rejects any later | ||
| non-evidence path. | ||
| - The repository has no `merge_group` workflow support, reviewed-patch identity, | ||
| base-delta classifier, or structured upstream-finding disposition. | ||
|
|
||
| ## Target behavior | ||
|
|
||
| - CI always validates the exact combined tree proposed for merge. | ||
| - A base advance that provably leaves the reviewed patch and risk boundaries | ||
| unchanged preserves unaffected internal reviewer tracks. | ||
| - Findings fixed by trusted `main` are recorded as resolved upstream, not | ||
| repeated against the PR. | ||
| - Deterministically known overlap, dependency impact, or effective-diff change | ||
| reruns the derived affected tracks. Ambiguity, conflict, or any unknown | ||
| impact fails closed and stales every track. | ||
| - Human approval remains the final merge checkpoint. | ||
|
|
||
| ## Design chosen | ||
|
|
||
| Bind reviews to an immutable base tree, head tree, effective patch manifest, | ||
| declared boundary manifest, and reviewer-track impact manifest. Reconcile each | ||
| new trusted-main base deterministically. Add merge-group CI only after the | ||
| classifier and evidence model are proven. | ||
|
|
||
| ## Alternatives considered | ||
|
|
||
| - Always rerun every reviewer: safe but defeats useful concurrency. | ||
| - Preserve reviews whenever changed file paths are disjoint: insufficient for | ||
| dependencies, generated contracts, migrations, and shared interfaces. | ||
| - Trust GitHub comments or chat to close findings: mutable and not canonical. | ||
| - Allow an AI-only semantic judgment to preserve approval: not deterministic | ||
| enough for a merge gate. | ||
|
|
||
| ## Boundaries preserved | ||
|
|
||
| Signed starts, one active chunk per initiative, required CI, coverage floors, | ||
| internal reviewer independence, CodeRabbit's supplementary role, explicit | ||
| human merge approval, and automated post-merge memory remain unchanged. | ||
|
|
||
| ## Expected risks | ||
|
|
||
| False preservation is more dangerous than redundant review. Any unclassified | ||
| dependency or changed effective patch must invalidate conservatively. | ||
|
|
||
| ## What must not change | ||
|
|
||
| No product behavior, auth/payment/data policy, coverage threshold, contributor | ||
| permission, automatic merge authority, or bypass for conflicts and failed CI. | ||
|
|
||
| ## How this will be proven | ||
|
|
||
| Deterministic synthetic Git histories will cover disjoint base changes, | ||
| overlapping files, dependency-boundary changes, upstream-resolved findings, | ||
| conflicts, rebases, merge commits, squash-equivalent patches, missing objects, | ||
| forged manifests, and merge-group combined trees. | ||
|
|
||
| ## Human decisions required | ||
|
|
||
| Approve each implementation chunk and the later repository-setting change that | ||
| enables GitHub merge queue. No queue or automatic merge setting changes in the | ||
| planning intake. |
183 changes: 183 additions & 0 deletions
183
.agent-loop/initiatives/WS-ENG-007-concurrent-pr-review-reconciliation/PLAN.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| # Plan: WS-ENG-007 - Concurrent PR Review Reconciliation | ||
|
|
||
| ## Approach | ||
|
|
||
| Implement the trust model in three ordered chunks. | ||
|
|
||
| First, introduce deterministic reviewed-patch and base-advance evidence. A | ||
| review is preserved only when the original PR patch can be reconstructed, the | ||
| same patch applies to new `main`, its resulting effective delta is identical, | ||
| and neither the new-base delta nor declared dependency boundaries affect the | ||
| reviewer's track. Ambiguity invalidates. | ||
|
|
||
| Second, add structured reviewer-track and finding reconciliation. Findings have | ||
| stable IDs, target evidence, owner track, and a machine disposition. Trusted | ||
| upstream changes may resolve a finding only when a deterministic predicate | ||
| proves the finding is absent in the combined tree. A `false` result keeps the | ||
| finding valid and reruns its owning track; `unknown` stales every track. Human | ||
| approval is never synthesized. | ||
|
|
||
| Third, add `merge_group` workflow support and combined-tree evidence. Only | ||
| after repository tests prove parity will a human administrator enable GitHub's | ||
| merge queue and align required checks. | ||
|
|
||
| ## Canonical Git evidence | ||
|
|
||
| One shared `scripts/git_tree_evidence.py` module is the only Git tree/delta | ||
| authority. Loop-memory and review reconciliation consume it; neither may build a | ||
| second parser or use fuzzy `git apply` behavior. | ||
|
|
||
| Patch identity is canonical JSON (UTF-8, sorted keys, compact separators) with | ||
| repository identity, unique reviewed trusted-main base commit/tree, reviewed | ||
| head commit/tree, and raw-path-sorted records containing `path`, `operation`, | ||
| `old_mode`, `old_oid`, `new_mode`, and `new_oid`. Renames are always delete plus | ||
| add, never similarity guesses. SHA-256 covers the serialization. Object type and | ||
| mode are independently recomputed. Symlinks, executables, binary/empty blobs, | ||
| deletes, and directory/file transitions retain exact modes and OIDs. Submodules, | ||
| unsupported types, duplicate/invalid paths, multiple merge bases, | ||
| missing/pruned objects, and non-unique bases fail closed. | ||
|
|
||
| The candidate is built by an exact three-tree operation over reviewed base, | ||
| reviewed head, and latest trusted-main trees. Latest-main-to-candidate records | ||
| must equal the original canonical patch records exactly. Conflict, partial or | ||
| full upstream absorption, empty effective patch, changed mode/blob/result, or a | ||
| different manifest invalidates. | ||
|
|
||
| ## Boundary and track authority | ||
|
|
||
| `.agent-loop/policies/review-boundaries.json` is the sole closed, versioned | ||
| boundary graph. Reconciliation derives boundaries; PR evidence only records the | ||
| derived version, digest, and result. Version drift, unknown path, unknown class, | ||
| unknown edge, cycle, ambiguous traversal, or unclassified multi-boundary impact | ||
| makes the affected set unprovable and therefore invalidates all tracks. | ||
| Targeted invalidation is permitted only when every path, class, edge, and | ||
| transitive impact is known. | ||
|
|
||
| Chunk 01 owns immutable Git evidence, boundary derivation, and the impacted | ||
| track set. Chunk 02 alone owns structured findings, upstream predicates, rerun | ||
| results, and final track evidence lifecycle. | ||
|
|
||
| The v1 minimum track map uses only exact evidence-gate names: `workflow_ci` | ||
| routes `CI integrity`, `architecture`, `senior engineering`, `security/auth`, | ||
| `QA/test`, and `test delta`; `auth_security` routes `security/auth`, | ||
| `architecture`, `senior engineering`, `QA/test`, `product/ops`, and | ||
| `test delta`; `payment_compensation` routes `security/auth`, `product/ops`, | ||
| `architecture`, `senior engineering`, `QA/test`, and `test delta`; | ||
| `database_schema` routes `architecture`, `security/auth`, `senior engineering`, | ||
| `QA/test`, `CI integrity`, `product/ops`, and `test delta`; | ||
| `shared_interface_contract` routes `architecture`, `senior engineering`, | ||
| `QA/test`, `product/ops`, `reuse/dedup`, `docs`, and `test delta`; | ||
| `generated_policy_process` routes all tracks; `product_runtime` routes | ||
| `senior engineering`, | ||
| `QA/test`, `security/auth`, `product/ops`, `architecture`, `reuse/dedup`, and | ||
| `test delta`; `tests_coverage` routes `QA/test`, `CI integrity`, | ||
| `senior engineering`, and `test delta`; `docs_only` routes `docs` and | ||
| `senior engineering`. Aliases, case changes, and unknown names fail closed. | ||
| Multi-class paths take the union; `unknown` routes all. | ||
|
|
||
| ## Finding predicate grammar | ||
|
|
||
| Finding IDs are `SHA-256` over compact, sorted-key UTF-8 JSON with the literal | ||
| version `workstream-review-finding-id-v1` and exactly these immutable identity | ||
| fields: repository, initiative, chunk, canonical reviewer track, repository- | ||
| owned rule ID, and target. Target contains the raw repository path, target kind, | ||
| immutable original object identity or diagnostic key, predicate kind, and the | ||
| predicate's immutable expected value. Mutable severity, message wording, | ||
| disposition, candidate/upstream evidence, timestamps, reviewer session, and | ||
| rerun results are excluded. A duplicate digest with non-byte-identical | ||
| canonical identity payload rejects the complete evidence set as a collision; | ||
| it is never silently deduplicated. An exact duplicate canonical payload/ID is | ||
| also rejected as duplicate evidence, yielding `unknown` and all tracks stale. | ||
|
|
||
| Every predicate is a resolution predicate: `true` means the exact candidate | ||
| proves the finding resolved; `false` means `still_valid`. `blob_equals` is true only | ||
| for the expected blob, `blob_absent` and `path_absent` only when the bound path | ||
| is absent, `mode_equals` only for the expected mode, and `diagnostic_absent` | ||
| only when a repository-owned typed checker reports the diagnostic absent. A | ||
| `diagnostic_absent` identity additionally binds the checker repository path, | ||
| checker blob OID, declared checker version, diagnostic code, input-schema | ||
| SHA-256, and output-schema SHA-256. Evaluation records the same fields from the | ||
| checker actually loaded from the candidate tree; any identity, version, or | ||
| schema mismatch is `unknown` and invalidates all tracks. | ||
| Before evaluation, a renamed or recreated bound target is `unknown`; missing is | ||
| false for equals predicates and true only for absence predicates when identity | ||
| continuity is not ambiguous. Evaluator error, contradiction, unsupported target, | ||
| or identity ambiguity is `unknown`; every `unknown` mandates all tracks become | ||
| `track_stale`. A finding | ||
| fixed on main but reintroduced by the PR evaluates false and remains | ||
| `still_valid`. Arbitrary commands, code, expressions, regexes, URLs, comments, | ||
| and claimant-authored dispositions are forbidden. | ||
|
|
||
| Findings are linked only when their immutable identity payloads have the same | ||
| repository, initiative, chunk, raw target path, target kind, and original | ||
| object identity or diagnostic code key. Unlinked findings never block | ||
| one another. Linked findings are contradictory when their predicate kinds or | ||
| immutable expected values assert mutually exclusive candidate facts: distinct | ||
| `blob_equals` OIDs, distinct `mode_equals` modes, an absence predicate paired | ||
| with an equality predicate, or distinct diagnostic checker/schema identities | ||
| for the same diagnostic code. Linked-set evaluation is atomic: only an all-true, | ||
| contradiction-free set resolves every member; any `false` with no unknown or | ||
| contradiction makes every linked member `still_valid`; and any `unknown`, | ||
| contradiction, or cross-track disagreement makes every linked member `unknown` | ||
| and stales all tracks. | ||
|
|
||
| ## Merge-queue activation checkpoint | ||
|
|
||
| Chunk 03 proves repository-side readiness with static and synthetic merge-group | ||
| fixtures only. GitHub cannot emit a real merge-group event before queue | ||
| enablement. After 03 merges, a separately authenticated human administrator may | ||
| enable the queue, submit two approved concurrent PRs in both orderings, verify | ||
| the exact intermediate group SHAs/trees and required contexts, and immediately | ||
| disable/roll back on any mismatch. Final trees may be identical for disjoint | ||
| changes; every intermediate base, ordered input set, group SHA/tree, and | ||
| evidence record must remain distinct. The workflow cannot enable or merge. | ||
|
|
||
| ## Human and CI invariants | ||
|
|
||
| Every preserved internal track still requires fresh CI on the exact candidate | ||
| or merge-group SHA. GitHub may dismiss stale human approval after any update. | ||
| This system neither preserves nor synthesizes it, and the specific PR still | ||
| requires explicit human merge approval. | ||
|
|
||
| ## Preservation algorithm | ||
|
|
||
| ```text | ||
| reviewed base + reviewed PR patch -> reviewed combined tree | ||
| latest trusted main + same patch -> candidate combined tree | ||
|
|
||
| if patch cannot apply, effective patch changes, boundaries overlap, | ||
| required evidence is missing, or classification is uncertain: | ||
| invalidate affected tracks (or all tracks when impact is unknown) | ||
| else: | ||
| preserve unaffected internal tracks | ||
|
|
||
| always: | ||
| run required CI on the candidate combined tree | ||
| retain explicit human merge approval | ||
| ``` | ||
|
|
||
| ## Alternatives rejected | ||
|
|
||
| - Path-disjointness alone. | ||
| - Timestamp/comment-based staleness. | ||
| - Automatic AI declarations that a semantic change is harmless. | ||
| - Enabling merge queue before workflows support `merge_group`. | ||
| - Folding this work into CI-02B, whose approved scope is semantic test lanes. | ||
|
|
||
| ## Verification strategy | ||
|
|
||
| - Synthetic repositories with exact tree/blob identities. | ||
| - Adversarial base advances across overlapping and indirect boundaries. | ||
| - Rebase, merge, squash-equivalent, conflict, deleted-object, and forged-record | ||
| cases. | ||
| - Workflow assertions proving identical required checks for PR and merge group. | ||
| - Repository-side static and synthetic assertions proving two concurrent PR | ||
| orderings preserve required-check parity. Real hosted two-ordering evidence | ||
| is collected only at the separate post-merge human-admin activation | ||
| checkpoint: temporarily enable the queue, verify the emitted group commits, | ||
| trees, and contexts, and retain or immediately disable it based on results. | ||
|
|
||
| ## Stop conditions | ||
|
|
||
| Stop if preservation depends on mutable PR prose, inaccessible commits, an | ||
| unbounded semantic judgment, weakened CI, or automatic human approval. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.