Skip to content

feat: Gate CLI/Unity compatibility on an IPC protocol version instead of release numbers - #1329

Merged
hatayama merged 10 commits into
v3-betafrom
feat/cli-protocol-version-gate
Jun 14, 2026
Merged

hatayama merged 10 commits into
v3-betafrom
feat/cli-protocol-version-gate

Conversation

@hatayama

@hatayama hatayama commented Jun 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • The Unity package now decides whether an installed CLI is compatible by comparing an integer IPC protocol version, not by comparing release numbers.
  • This removes the failure mode behind the recent release breakage, where CLI changes accumulated across releases forced authors to predict the next release number and a release shipped a CLI version below what the package required.

User Impact

  • No change in normal use. CLIs built from the same source as the package keep working.
  • An outdated CLI that predates the protocol handshake (or speaks an older protocol generation) is still cleanly told to run uloop update before any tool runs — the error now reports protocol generations instead of a guessed release tag.

Why

Compatibility is really about the C#↔Go IPC contract, but it was expressed as a semver floor (MINIMUM_REQUIRED_CLI_VERSION). That coupled a compatibility decision to release-please's numbering: every CLI change nudged the floor, and the prediction broke when several CLI PRs landed between releases. Protocol versions decouple the two: the integer moves only on a breaking IPC change, never per release.

Changes

  • Contract: cli/contract.json gains protocolVersion; the CLI sends it in the uloop request metadata (cli/contract.go, cli/internal/unityipc/client.go).
  • Gate: JsonRpcProcessor reads uloop.protocolVersion and rejects clients below CliConstants.REQUIRED_CLI_PROTOCOL_VERSION. A missing or non-integer value fails the gate, so pre-handshake CLIs are treated as outdated. The cli_update_required error now carries current/required protocol versions.
  • CI: removed the whole minimum-version-warning apparatus (comment binary, scripts, pull_request_target workflow, fail-on-warning build step) and replaced it with one deterministic Go test, TestProtocolVersionMatchesUnityPackage, that fails the build if the Go and C# protocol declarations diverge. No git diff, PR number, or GitHub API involved.
  • Roles clarified: MINIMUM_REQUIRED_CLI_VERSION stays only as the installer pin for setup/update; release-please still owns the cliVersion/default-tools.json stamps.
  • Docs: AGENTS.md (CLAUDE.md symlink) now documents when to bump the protocol version and what not to touch in feature PRs.

Verification

  • scripts/check-go-cli.sh: green (fmt, vet, lint, full Go suite incl. the new invariant test).
  • Negative check: temporarily setting contract.json protocolVersion to 2 makes TestProtocolVersionMatchesUnityPackage fail as expected; reverted.
  • C# EditMode via this checkout's dev binary: JsonRpcProcessorCliVersionGateTests + UnityCliLoopFirstPartyServerLifecycleBindingTests pass (16/16); broader gate/setup/comparer classes pass (30/30). 3 unrelated pre-existing failures (prefab/architecture/recovery-flake) reproduce identically on the base branch.
  • End-to-end: rebuilt dev binary (sends protocolVersion=1) passes the live C# gate and compiles the project successfully.

Review in cubic

hatayama added 4 commits June 13, 2026 10:26
The semver-based compatibility floor forced PR authors to predict the
next release number, which diverged from release-please numbering and
broke a release. Compatibility is really about the C# IPC contract, so
the contract now carries an integer protocolVersion that only moves
when the Unity package and the CLI stop interoperating. The CLI sends
it in the uloop request metadata so the Unity side can gate on it.
The Unity package rejected old CLIs by comparing release numbers
against MINIMUM_REQUIRED_CLI_VERSION, which forced PR authors to
predict the next release number and broke when CLI changes accumulated
across releases. The gate now reads uloop.protocolVersion from the
request metadata and rejects clients below REQUIRED_CLI_PROTOCOL_VERSION,
an integer that moves only on a breaking IPC contract change.

A missing or non-integer protocolVersion fails the gate, so CLIs
released before the handshake are treated as outdated. The
cli_update_required error now reports current/required protocol
versions instead of a target release tag. MINIMUM_REQUIRED_CLI_VERSION
stays as the installer pin for setup/update flows.
The minimum-version warning fired whenever Go CLI files changed without
bumping MINIMUM_REQUIRED_CLI_VERSION. That constant is now only the
installer pin, so the warning enforced the wrong thing, depended on a
git diff, and tangled with release-please numbering.

Replace the whole apparatus (comment binary, scripts, pull_request_target
workflow, and the fail-on-warning build step) with one deterministic Go
test: cli/contract.json protocolVersion must equal the Unity package's
REQUIRED_CLI_PROTOCOL_VERSION. It runs in the existing test suite, needs
no diff, PR number, or GitHub API, and has no false positives. Whether a
given change is breaking enough to bump the protocol is a code-review and
docs concern, not a path heuristic.
Replace the commit-time MINIMUM_REQUIRED_CLI_VERSION rule, which no
longer reflects how the gate works, with guidance for the protocol
version: keep cli/contract.json protocolVersion and
CliConstants.REQUIRED_CLI_PROTOCOL_VERSION equal and bump both only on
a breaking IPC change. Clarify that release-please owns the version
stamps and that MINIMUM_REQUIRED_CLI_VERSION is the installer pin,
neither of which belongs in a feature PR.
@coderabbitai

coderabbitai Bot commented Jun 13, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@hatayama, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 13 minutes and 52 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0287a635-f36c-4d34-8cc3-6b765cd0c297

📥 Commits

Reviewing files that changed from the base of the PR and between ede0d8d and 6f860ec.

📒 Files selected for processing (6)
  • Assets/Tests/Editor/CliInstallationDetectorTests.cs
  • Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs
  • Packages/src/Editor/Domain/CliConstants.cs
  • Packages/src/Editor/Infrastructure/Api/JsonRpcProcessor.cs
  • Packages/src/Editor/Infrastructure/CLI/CliInstallationDetector.cs
  • cli/contract.json
📝 Walkthrough

Walkthrough

This PR transitions the CLI/Unity package IPC compatibility model from minimum version string comparison to exact-match integer protocol generation, introducing a protocolVersion field in the CLI contract that must match CliConstants.REQUIRED_CLI_PROTOCOL_VERSION in the C# package. The change includes CLI detection updates, JSON-RPC protocol gating, UI updates for protocol-based state (including new downgrade handling), JSON version output support, removal of legacy minimum-version warning automation, and a new IPC protocol reminder check for coordinated protocol bumps.

Changes

CLI IPC Protocol Version Negotiation

Layer / File(s) Summary
Protocol version contract definition
cli/contract.go, cli/contract.json, cli/contract_test.go, cli/protocol_version_consistency_test.go, Packages/src/Editor/Domain/CliConstants.cs, AGENTS.md, .coderabbit.yaml
Contract struct now includes ProtocolVersion field; contract JSON set to version 1; validation test ensures protocol ≥ 1; cross-build test enforces C#/Go protocol version equality via regex parsing; REQUIRED_CLI_PROTOCOL_VERSION constant defined; policy documentation describes coordination rules and constraints on version field edits.
CLI protocol version detection and caching
Packages/src/Editor/Infrastructure/CLI/CliInstallationDetector.cs, Assets/Tests/Editor/CliInstallationDetectorTests.cs
CliInstallationDetection data structure now carries optional ProtocolVersion; detector caches protocol via GetCachedCliProtocolVersion(); shell commands emit contract markers and parse contract JSON to extract protocol version; executable-path detection tries contract/JSON invocation first, falls back to version-only; test cases validate protocol parsing for contract/version-only/failure scenarios.
JSON-RPC protocol version gating
Packages/src/Editor/Infrastructure/Api/JsonRpcProcessor.cs, Packages/src/Editor/Infrastructure/Api/JsonRpcRequest.cs, Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs
JsonRpcRequest adds ClientProtocolVersion property; processor parses uloop.protocolVersion from incoming requests and enforces exact match to REQUIRED_CLI_PROTOCOL_VERSION; protocol mismatch returns error with current/required protocol fields and update command; legacy CLI-version gating removed; tests validate protocol-exact-match acceptance, protocol-newer/older rejection, missing/malformed protocol handling.

Application Services and CLI Inspection

Layer / File(s) Summary
Protocol version and comparison helpers
Packages/src/Editor/Application/CliSetupApplicationService.cs, Packages/src/Editor/Domain/CliVersionComparer.cs, Assets/Tests/Editor/CliPathSetupFlowTests.cs, Assets/Tests/Editor/CliSetupApplicationServiceTests.cs, Assets/Tests/Editor/CliVersionComparerTests.cs
ICliInstallationDetector interface adds GetCachedCliProtocolVersion(); services expose cached protocol and new IsVersionGreaterThan/IsVersionEqual comparison methods; CliVersionComparer adds strict comparison wrappers; fake test detectors implement new interface methods.

UI and Settings Window Updates

Layer / File(s) Summary
Setup wizard protocol-based CLI state
Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs, Assets/Tests/Editor/SetupWizardWindowTests.cs
SetupWizardWindow reads cached protocol version and computes CLI compatibility/update/downgrade via protocol equality instead of semver satisfaction; UpdateCliStep accepts cliProtocolVersion and needsDowngrade; button text includes "Downgrade CLI" branch; PATH repair requires both update and downgrade to be false; helper methods refactored to use protocol-based logic.
Settings window protocol-based actions
Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs, Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs
CreateCliSetupData computes needsUpdate and introduces needsDowngrade from cached protocol version; primary-button decision helpers reparameterized to accept int? cliProtocolVersion; repair path condition updated to exclude downgrades; new IsCliDowngradeNeeded helper flags protocol versions above required constant.

CLI Version Output and Metadata

Layer / File(s) Summary
CLI package-level protocol version and IPC client metadata
cli/internal/cli/tools.go, cli/internal/unityipc/client.go, cli/internal/unityipc/client_test.go
CLI defines package-level protocolVersion from contract; Unity IPC client adds ProtocolVersion field to request metadata and populates it from contract; test validates protocol field in request metadata.
JSON version output with protocol
cli/internal/cli/run.go, cli/internal/cli/run_help.go, cli/internal/cli/help_test.go
CLI detects --version --json requests; RunProjectLocal marshals and outputs {cliVersion, protocolVersion} JSON to stdout; test validates both fields match contract.
Server readiness request uses protocol
Packages/src/Editor/CompositionRoot/UnityCliLoopFirstPartyServerLifecycleBinding.cs, Assets/Tests/Editor/UnityCliLoopFirstPartyServerLifecycleBindingTests.cs
Readiness request now sends uloop.protocolVersion instead of uloop.cliVersion; test updated to validate protocol field against required constant.

CLI Error Handling and Messaging

Layer / File(s) Summary
Protocol mismatch next actions
cli/internal/cli/error_envelope.go, cli/internal/cli/error_envelope_test.go, Assets/Tests/Editor/ProjectIpcWarmupClientTests.cs
cliUpdateRequiredNextActions refactored to handle updateCommand and distinguish protocol-newer from protocol-older cases via helper functions; error test updated to use protocol fields instead of CLI version fields; warmup client test expects "does not match" messaging for protocol mismatch.

IPC Protocol Reminder and Coordination

Layer / File(s) Summary
IPC protocol reminder automation
cli/cmd/check-ipc-protocol-reminder/main.go, cli/internal/automation/ipc_protocol_reminder.go, cli/internal/automation/ipc_protocol_reminder_test.go, .github/workflows/build-and-test.yml
New check-ipc-protocol-reminder command detects changes to IPC-facing files and flags when protocol declarations should be reviewed; integrated as PR-only build step with base/head ref comparison; includes Git-based change detection, path matching, GitHub step summary output, and comprehensive test coverage for classification and summary writing.

Removal of Legacy Minimum-Version Automation

Layer / File(s) Summary
Remove minimum-version warning infrastructure
.github/workflows/build-and-test.yml, scripts/check-cli-minimum-version-warning.sh, scripts/comment-cli-minimum-version-warning.sh, scripts/test-cli-minimum-version-warning-workflow.sh, scripts/test-comment-cli-minimum-version-warning.sh, cli/cmd/comment-cli-minimum-version-warning/main.go, cli/internal/automation/minimum_version_warning.go, cli/internal/automation/minimum_version_warning_test.go, cli/internal/architecture/comment_cli_minimum_version_warning_test.go
Removed workflow step for minimum version bump check, helper scripts, and Go automation/tests for minimum version PR comments; consolidated minimum-version bump validation into general shell helper testing.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • hatayama/unity-cli-loop#1325: Modifies the minimum-version warning automation that this PR completely removes, targeting the same release-please branch scenario handling.
  • hatayama/unity-cli-loop#1131: Modifies CliInstallationDetector shell-based detection logic, overlapping with the protocol marker parsing additions in this PR.
  • hatayama/unity-cli-loop#1258: Modifies Setup Wizard/Settings primary-button decision logic around update vs PATH repair, which this PR further extends with protocol-based and downgrade handling.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.87% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: shifting CLI/Unity compatibility gating from semver release numbers to an integer IPC protocol version.
Description check ✅ Passed The description is well-structured, comprehensive, and directly related to the changeset. It explains the problem, the solution, changes made, and verification steps, all aligned with the code modifications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/cli-protocol-version-gate

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 23 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Packages/src/Editor/Infrastructure/Api/JsonRpcProcessor.cs Outdated
hatayama added 3 commits June 13, 2026 12:49
Use the IPC protocol generation, rather than release semver, for runtime compatibility and setup UI decisions.

- Require exact protocol matches at IPC handshake time with distinct guidance for older and newer CLI protocols.
- Expose `uloop --version --json` so the Unity package can detect CLI protocol metadata.
- Make setup update and replacement actions protocol-aware while keeping release tags limited to installation.
Ask CodeRabbit to flag IPC-facing changes for protocol-version review without treating ordinary CLI or release changes as automatic bump triggers.
Tighten the AGENTS wording for protocol-version bump guidance so the contract-generation rule reads cleanly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
Assets/Tests/Editor/SetupWizardWindowTests.cs (1)

488-509: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add the required behavior comment to this test.

This changed test method is missing the short comment that explains what behavior it verifies.

✏️ Suggested comment
 public void GetCliButtonTextForSetupWizard_ReturnsExpectedLabel(
     bool cliInstalled,
     bool isInstallingCli,
     bool isChecking,
     bool needsUpdate,
     bool needsDowngrade,
     bool needsCliPathSetup,
     string cliVersion,
     string requiredCliVersion,
     string expectedLabel)
 {
+    // Verifies that the setup wizard button text reflects install, update, downgrade, PATH-repair, and checking states.
     string label = SetupWizardWindow.GetCliButtonTextForSetupWizard(
         cliInstalled,
         isInstallingCli,
         isChecking,

As per coding guidelines, **/*[Tt]est?(s).cs: Every test method must have a short comment that states what behavior the test verifies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Assets/Tests/Editor/SetupWizardWindowTests.cs` around lines 488 - 509, Add a
short one-line comment above the test method
GetCliButtonTextForSetupWizard_ReturnsExpectedLabel describing the behavior it
verifies (e.g., "Verifies GetCliButtonTextForSetupWizard returns the correct
label for given CLI/install states"), ensuring the comment succinctly states the
expected behavior of SetupWizardWindow.GetCliButtonTextForSetupWizard for the
supplied parameter combinations.

Source: Coding guidelines

Packages/src/Editor/Infrastructure/CLI/CliInstallationDetector.cs (1)

482-551: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Wrap process in using statement to prevent resource leak.

The process is manually disposed at lines 529, 538, and 544, but if an exception occurs between process creation (line 497) and the try block (line 522), the process will leak. Wrap the process lifecycle in a using statement for guaranteed cleanup.

🔒 Recommended fix to add using statement
         Process process = ProcessStartHelper.TryStart(startInfo);
         if (process == null)
         {
             return null;
         }

-        StringBuilder outputBuilder = new();
-
-        process.OutputDataReceived += (sender, e) =>
-        {
-            if (e.Data != null)
-            {
-                outputBuilder.Append(e.Data);
-            }
-        };
-        process.ErrorDataReceived += (sender, e) => { };
-
-        process.BeginOutputReadLine();
-        process.BeginErrorReadLine();
-
-        using CancellationTokenRegistration registration = ct.Register(() =>
-        {
-            KillProcessIfRunning(process);
-        });
-
-        try
+        using (process)
         {
-            bool exited = process.WaitForExit(PROCESS_TIMEOUT_MS);
-
-            if (!exited)
+            StringBuilder outputBuilder = new();
+
+            process.OutputDataReceived += (sender, e) =>
             {
-                KillProcessIfRunning(process);
-                process.Dispose();
-                return null;
-            }
-
-            // Parameterless WaitForExit flushes async output buffers
-            process.WaitForExit();
-
-            string output = outputBuilder.ToString().Trim();
-            bool failed = process.ExitCode != 0 || string.IsNullOrEmpty(output);
-            process.Dispose();
-
-            return failed ? null : output;
-        }
-        catch (Exception ex)
-        {
-            process.Dispose();
-            if (!ct.IsCancellationRequested)
+                if (e.Data != null)
+                {
+                    outputBuilder.Append(e.Data);
+                }
+            };
+            process.ErrorDataReceived += (sender, e) => { };
+
+            process.BeginOutputReadLine();
+            process.BeginErrorReadLine();
+
+            using CancellationTokenRegistration registration = ct.Register(() =>
             {
-                UnityEngine.Debug.LogWarning($"[UnityCliLoop] Failed to detect CLI version: {ex.Message}");
+                KillProcessIfRunning(process);
+            });
+
+            try
+            {
+                bool exited = process.WaitForExit(PROCESS_TIMEOUT_MS);
+
+                if (!exited)
+                {
+                    KillProcessIfRunning(process);
+                    return null;
+                }
+
+                // Parameterless WaitForExit flushes async output buffers
+                process.WaitForExit();
+
+                string output = outputBuilder.ToString().Trim();
+                bool failed = process.ExitCode != 0 || string.IsNullOrEmpty(output);
+
+                return failed ? null : output;
+            }
+            catch (Exception ex)
+            {
+                if (!ct.IsCancellationRequested)
+                {
+                    UnityEngine.Debug.LogWarning($"[UnityCliLoop] Failed to detect CLI version: {ex.Message}");
+                }
+                return null;
             }
-            return null;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Packages/src/Editor/Infrastructure/CLI/CliInstallationDetector.cs` around
lines 482 - 551, The Process returned by ProcessStartHelper.TryStart in
ExecuteCliVersionCommand can leak if an exception occurs before the manual
Dispose calls; wrap the Process in a using statement (e.g., using var process =
ProcessStartHelper.TryStart(startInfo);) immediately after creation and return
early if it's null, then remove the explicit process.Dispose() calls inside the
method (including the ones after KillProcessIfRunning and in the catch), keeping
the existing CancellationTokenRegistration and calls to KillProcessIfRunning and
process.WaitForExit(PROCESS_TIMEOUT_MS) as-is so the using ensures deterministic
cleanup.
Assets/Tests/Editor/UnityCliLoopFirstPartyServerLifecycleBindingTests.cs (1)

11-14: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the test comment to reflect protocol version verification.

The comment states the test verifies "the internal readiness probe does not depend on user-toggleable tools," but the updated assertion now checks protocolVersion in the request metadata. Update the comment to clarify that the test also verifies the protocol version is included in the readiness request.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Assets/Tests/Editor/UnityCliLoopFirstPartyServerLifecycleBindingTests.cs`
around lines 11 - 14, Update the failing test comment for
CreateGetVersionReadinessRequestJson_UsesInternalHealthCheckWithCliMetadata to
reflect the new assertion: replace or extend the current description ("Tests
that the internal readiness probe does not depend on user-toggleable tools.")
with a brief note that the test also verifies the protocol version is included
in the readiness request metadata (i.e., that protocolVersion is present and
correct in the generated request JSON).

Source: Coding guidelines

🧹 Nitpick comments (1)
cli/internal/cli/error_envelope_test.go (1)

215-231: ⚡ Quick win

Also lock the retry contract in the newer-protocol test.

This branch currently only verifies the first guidance string. Adding the same ErrorCode / Retryable / SafeToRetry assertions as the older-protocol test will keep the newer-protocol classification from regressing silently.

🧪 Suggested assertion block
 	cliErr := classifyError(err, errorContext{projectRoot: "/tmp/MyProject", command: "compile"})
 	if cliErr.ErrorCode != errorCodeCLIUpdateRequired {
 		t.Fatalf("error code mismatch: %#v", cliErr)
 	}
+	if !cliErr.Retryable || !cliErr.SafeToRetry {
+		t.Fatalf("retry flags mismatch: %#v", cliErr)
+	}
 	if len(cliErr.NextActions) == 0 || cliErr.NextActions[0] != "Update the Unity package to a version that supports this CLI protocol, or install the CLI from the same release as the package." {
 		t.Fatalf("next actions mismatch: %#v", cliErr.NextActions)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/internal/cli/error_envelope_test.go` around lines 215 - 231, The
newer-protocol test TestClassifyCliUpdateRequiredRPCErrorForNewerProtocol only
asserts the NextActions string; add the same assertions used in the
older-protocol test to lock the retry contract: after calling classifyError(err,
...) assert cliErr.ErrorCode == errorCodeCLIUpdateRequired, cliErr.Retryable ==
true (or the expected boolean as in the older test), and cliErr.SafeToRetry ==
false (or the expected boolean from the older test) so ErrorCode, Retryable and
SafeToRetry cannot regress; reference the classifyError result variable cliErr
and the constant errorCodeCLIUpdateRequired when adding these checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@Assets/Tests/Editor/SetupWizardWindowTests.cs`:
- Around line 488-509: Add a short one-line comment above the test method
GetCliButtonTextForSetupWizard_ReturnsExpectedLabel describing the behavior it
verifies (e.g., "Verifies GetCliButtonTextForSetupWizard returns the correct
label for given CLI/install states"), ensuring the comment succinctly states the
expected behavior of SetupWizardWindow.GetCliButtonTextForSetupWizard for the
supplied parameter combinations.

In `@Assets/Tests/Editor/UnityCliLoopFirstPartyServerLifecycleBindingTests.cs`:
- Around line 11-14: Update the failing test comment for
CreateGetVersionReadinessRequestJson_UsesInternalHealthCheckWithCliMetadata to
reflect the new assertion: replace or extend the current description ("Tests
that the internal readiness probe does not depend on user-toggleable tools.")
with a brief note that the test also verifies the protocol version is included
in the readiness request metadata (i.e., that protocolVersion is present and
correct in the generated request JSON).

In `@Packages/src/Editor/Infrastructure/CLI/CliInstallationDetector.cs`:
- Around line 482-551: The Process returned by ProcessStartHelper.TryStart in
ExecuteCliVersionCommand can leak if an exception occurs before the manual
Dispose calls; wrap the Process in a using statement (e.g., using var process =
ProcessStartHelper.TryStart(startInfo);) immediately after creation and return
early if it's null, then remove the explicit process.Dispose() calls inside the
method (including the ones after KillProcessIfRunning and in the catch), keeping
the existing CancellationTokenRegistration and calls to KillProcessIfRunning and
process.WaitForExit(PROCESS_TIMEOUT_MS) as-is so the using ensures deterministic
cleanup.

---

Nitpick comments:
In `@cli/internal/cli/error_envelope_test.go`:
- Around line 215-231: The newer-protocol test
TestClassifyCliUpdateRequiredRPCErrorForNewerProtocol only asserts the
NextActions string; add the same assertions used in the older-protocol test to
lock the retry contract: after calling classifyError(err, ...) assert
cliErr.ErrorCode == errorCodeCLIUpdateRequired, cliErr.Retryable == true (or the
expected boolean as in the older test), and cliErr.SafeToRetry == false (or the
expected boolean from the older test) so ErrorCode, Retryable and SafeToRetry
cannot regress; reference the classifyError result variable cliErr and the
constant errorCodeCLIUpdateRequired when adding these checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 03dbf5b0-8ad4-4bd2-9637-64f9b965e95d

📥 Commits

Reviewing files that changed from the base of the PR and between 1b1b89b and a434187.

📒 Files selected for processing (42)
  • .coderabbit.yaml
  • .github/workflows/build-and-test.yml
  • .github/workflows/cli-minimum-version-warning.yml
  • AGENTS.md
  • Assets/Tests/Editor/CliInstallationDetectorTests.cs
  • Assets/Tests/Editor/CliPathSetupFlowTests.cs
  • Assets/Tests/Editor/CliSetupApplicationServiceTests.cs
  • Assets/Tests/Editor/CliVersionComparerTests.cs
  • Assets/Tests/Editor/JsonRpcProcessorCliVersionGateTests.cs
  • Assets/Tests/Editor/ProjectIpcWarmupClientTests.cs
  • Assets/Tests/Editor/SetupWizardWindowTests.cs
  • Assets/Tests/Editor/UnityCliLoopFirstPartyServerLifecycleBindingTests.cs
  • Assets/Tests/Editor/UnityCliLoopSettingsWindowCliActionTests.cs
  • Packages/src/Editor/Application/CliSetupApplicationService.cs
  • Packages/src/Editor/CompositionRoot/UnityCliLoopFirstPartyServerLifecycleBinding.cs
  • Packages/src/Editor/Domain/CliConstants.cs
  • Packages/src/Editor/Domain/CliVersionComparer.cs
  • Packages/src/Editor/Infrastructure/Api/JsonRpcProcessor.cs
  • Packages/src/Editor/Infrastructure/Api/JsonRpcRequest.cs
  • Packages/src/Editor/Infrastructure/CLI/CliInstallationDetector.cs
  • Packages/src/Editor/Presentation/Setup/SetupWizardWindow.cs
  • Packages/src/Editor/Presentation/UnityCliLoopSettingsWindow.cs
  • cli/cmd/comment-cli-minimum-version-warning/main.go
  • cli/contract.go
  • cli/contract.json
  • cli/contract_test.go
  • cli/internal/architecture/comment_cli_minimum_version_warning_test.go
  • cli/internal/automation/minimum_version_warning.go
  • cli/internal/automation/minimum_version_warning_test.go
  • cli/internal/cli/error_envelope.go
  • cli/internal/cli/error_envelope_test.go
  • cli/internal/cli/help_test.go
  • cli/internal/cli/run.go
  • cli/internal/cli/run_help.go
  • cli/internal/cli/tools.go
  • cli/internal/unityipc/client.go
  • cli/internal/unityipc/client_test.go
  • cli/protocol_version_consistency_test.go
  • scripts/check-cli-minimum-version-warning.sh
  • scripts/comment-cli-minimum-version-warning.sh
  • scripts/test-cli-minimum-version-warning-workflow.sh
  • scripts/test-comment-cli-minimum-version-warning.sh
💤 Files with no reviewable changes (10)
  • scripts/test-comment-cli-minimum-version-warning.sh
  • scripts/test-cli-minimum-version-warning-workflow.sh
  • cli/cmd/comment-cli-minimum-version-warning/main.go
  • .github/workflows/cli-minimum-version-warning.yml
  • .github/workflows/build-and-test.yml
  • scripts/comment-cli-minimum-version-warning.sh
  • scripts/check-cli-minimum-version-warning.sh
  • cli/internal/automation/minimum_version_warning.go
  • cli/internal/automation/minimum_version_warning_test.go
  • cli/internal/architecture/comment_cli_minimum_version_warning_test.go

hatayama added 3 commits June 14, 2026 15:06
Add contract-shape tests for protocol and heartbeat metadata, plus a non-blocking PR reminder that highlights IPC-facing diffs when protocol declarations were not changed.
Resolve protocol gate conflicts by keeping protocolVersion 1 while adopting the latest published CLI release version from origin/v3-beta.
Treat protocolVersion integers outside the Int32 range as missing metadata so compatibility checks return deterministic update guidance instead of parser overflow errors.
@hatayama
hatayama merged commit 85c21d3 into v3-beta Jun 14, 2026
9 checks passed
@hatayama
hatayama deleted the feat/cli-protocol-version-gate branch June 14, 2026 06:41
@github-actions github-actions Bot mentioned this pull request Jun 14, 2026
RyanXie123 pushed a commit to RyanXie123/unity-cli-loop that referenced this pull request Sep 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant