Skip to content

Conversation

dsarno
Copy link
Owner

@dsarno dsarno commented Aug 26, 2025

TL;DR
This PR hardens the transport with explicit framing + timeouts/retries, upgrades the editing surface for Claude (micro‑edits and resource read/search), and adds an end‑to‑end natural‑language (NL) test harness that drives a live Unity instance from CI and reports JUnit/Markdown artifacts suitable for Actions. (+6,962/−741 over 47 files.) ([GitHub]1)

Why this matters

  • Message integrity & throughput: Stable framed IO eliminates boundary bugs, enforces sane limits, and improves latency under load. ([GitHub]1)
  • Claude‑first editing: Tools expose precise text/structured edits and resource reading so models can read → plan → apply → verify with preconditions, reducing churn and syntax breakage. ([GitHub]2)
  • Confidence at PR time: The NL suite spins up a Unity bridge, verifies handshake/framing, runs editing exercises, and publishes normalized JUnit + readable Markdown for quick review. ([GitHub]3)

Highlights (compared to main)

1) Robust framing of messages (with testing)

  • Handshake & transport rules: Strict FRAMING=1 handshake; non‑blocking script writes; TCP NoDelay; timeouts and retries on reads/writes. Caps frames at 64 MiB and rejects zero‑length frames. ([GitHub]1)
  • Test coverage: Adds transport/handshake tests and a socket framing check to catch boundary regressions early. The repo includes test_unity_socket_framing.py. ([GitHub]1)

2) Claude‑friendly editing tools + resource reading

  • Edit APIs the model can use safely: apply_text_edits (with precondition hashes and atomic multi‑edit batches) and script_apply_edits for structured C# edits; validate_script to catch syntax issues before writes. ([GitHub]2)
  • Resource access: list_resources, read_resource, and find_in_file enable read‑first plans and targeted diffs. ([GitHub]3)
  • Default posture: Prefer micro‑edits + resources; legacy manage_script paths stay for compatibility while read/update/edit flavors are de‑emphasized. ([GitHub]1)

3) New end‑to‑end NL testing CI (client prompts → Unity → back)

  • Mini NL suite wiring: Workflow runs a constrained prompt that uses only the allowed Unity tools (…manage_editor, …list_resources, …read_resource, …apply_text_edits, …script_apply_edits, …validate_script, …find_in_file + minimal Bash). ([GitHub]3)
  • Live Unity hookup: Probes the running bridge port and asserts the FRAMING=1 preamble before tests proceed. ([GitHub]1)
  • Deterministic artifacts: Always emits one consumer‑friendly JUnit (reports/junit-for-actions.xml) and a Markdown summary; uses mikepenz/action-junit-report@v5. ([GitHub]3)

What changed (selected)

  • Transport & bridge

    • Stable framing handshake; safe ReadExact with timeouts/retries; 64 MiB frame cap; rejects zero‑length frames; non‑blocking script writes; NoDelay on sockets. ([GitHub]1)
  • Server & tools

    • Prefer micro‑edits + apply_text_edits/script_apply_edits; add list_resources/read_resource; improve method‑span parsing and validation flows to reduce false negatives. ([GitHub]1)
  • Tests

    • New transport/handshake tests and a socket framing test file to guard payload boundaries and stdout hygiene. ([GitHub]1)
  • CI

    • .github/workflows/claude-nl-suite.yml switched to a mini NL prompt; honors JUNIT_OUT/MD_OUT; normalizes to reports/junit-for-actions.xml; publishes via action‑junit‑report v5; adds summary to the job page. ([GitHub]3)

How to verify

A) In CI (recommended)

  1. Run “Claude NL Test Suite (mini)” on this branch. (Requires an ANTHROPIC_API_KEY in your GH secrets)

  2. Confirm the steps:

    • Handshake probe shows FRAMING=1 and the suite proceeds. ([GitHub]1)
    • reports/junit-for-actions.xml is published and annotated by the JUnit action. ([GitHub]3)
    • Job summary includes the Markdown report with trimmed evidence. ([GitHub]3)

B) Locally (quick check)

  1. Start the Unity bridge and run the server.
  2. Execute the transport tests; inspect test_unity_socket_framing.py assertions for boundary and preamble checks. ([GitHub]2)
  3. Exercise apply_text_edits or script_apply_edits on a small C# file, then call validate_script and read_resource to confirm read‑write‑re‑read flows. ([GitHub]2)

Backwards compatibility

  • Legacy manage_script remains available; the NL suite and docs steer tooling toward micro‑edits and resource‑first reads. No public API breaks are expected for existing automations. ([GitHub]1)

Risks

  • Low → Medium: Transport framing is stricter (size cap, zero‑length reject). If any external client relied on loose framing, it will need to adopt FRAMING=1 and proper lengths. The NL suite explicitly verifies this path. ([GitHub]1)

Follow‑ups

  • Expand framing tests to large batched edits and back‑pressure scenarios; broaden NL coverage beyond the mini prompt to a full suite when runners with Unity licenses are available. ([GitHub]1)

Change map (at a glance)

  • Commits: 188; Files changed: 47; net +6,962/−741. ([GitHub]1)

Summary by CodeRabbit

  • New Features

    • Unity-backed NL/T CI suites (mini & full) that run natural-language edits against a Unity test project and produce JUnit XML and human-readable Markdown reports; new in‑CI script-edit and validate endpoints and a long test script for large-edit scenarios.
  • Improvements

    • Robust framed transport with retries, safer atomic multi-edit writes with precondition hashes, debounce refresh behavior, macOS path fixes, better editor logging/diagnostics, and safe revert/reporting helpers.
  • Documentation

    • Expanded CI/dev guides and run/reporting instructions.
  • Tests

    • Added many tests for framing, transport, resources, script editing, tooling, and logging.
  • Chores

    • Workflow updates, report post-processing tool, .gitignore tweak, and package version bump.

dsarno added 30 commits August 17, 2025 16:38
…ck; add uv -q for quieter stdio; MCP server: compatibility guards for capabilities/resource decorators and indentation fix; ManageScript: shadow var fix; robust mac config path.
…text edits; anchor aliasing and text-op conversion; immediate compile on NL/structured; add resource_tools (tail_lines, find_in_file); update test cases
…xt ops; preview+confirm for regex; safe_script_edit wrapper; immediate compile & verification; header-safe anchors
…ck; add uv -q for quieter stdio; MCP server: compatibility guards for capabilities/resource decorators and indentation fix; ManageScript: shadow var fix; robust mac config path.
…add SHA precondition and immediate refresh; keep verification slice; minor test and uv.lock updates
…cription with canonical fields & examples; alias/wrapper normalization; machine-parsable validation hints; auto applyMode=sequential for mixed insert+replace; echo normalizedEdits
…edit'; add routing='text' for pure text; echo normalizedEdits; C#: include 'code' in error payloads
…enrich spec examples; add routing metadata; add standalone long test script
…onfig

fix: update Unity MCP server path in workflow
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/claude-nl-suite.yml (2)

47-47: Pin all third‑party Actions by immutable commit SHAs.

Prevents supply‑chain drift and stabilizes CI. Apply at each uses: line shown below.

-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<commit-sha>

-      - uses: astral-sh/setup-uv@v4
+      - uses: astral-sh/setup-uv@<commit-sha>

-        uses: game-ci/unity-test-runner@v4
+        uses: game-ci/unity-test-runner@<commit-sha>

-        uses: anthropics/claude-code-base-action@beta
+        uses: anthropics/claude-code-base-action@<commit-sha>

-        uses: mikepenz/action-junit-report@v5
+        uses: mikepenz/action-junit-report@<commit-sha>

-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@<commit-sha>

List all unpinned actions in the repo:

#!/bin/bash
rg -nP 'uses:\s+\S+@(?!(?:[a-f0-9]{40}))' .github/workflows/*.yml

Also applies to: 52-52, 76-76, 251-251, 454-454, 466-466


14-17: Pin Unity Docker image by digest to avoid tag drift.

Locks the editor image for reproducible runs.

 env:
   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pin to immutable digest (replace <DIGEST> with the resolved sha256)
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>
   UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
🧹 Nitpick comments (3)
.github/workflows/claude-nl-suite.yml (3)

24-26: Fix YAMLlint findings: extra spaces after colons and trailing spaces.

Minor but keeps linters and actionlint quiet.

-      MD_OUT:    reports/junit-nl-suite.md
+      MD_OUT: reports/junit-nl-suite.md
@@
-          UNITY_LICENSE:  ${{ secrets.UNITY_LICENSE }}
-          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
-          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
-          UNITY_SERIAL:   ${{ secrets.UNITY_SERIAL }}
+          UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
+          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
+          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
+          UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
@@
-          UNITY_LICENSE:  ${{ secrets.UNITY_LICENSE }}
-          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
-          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
-          UNITY_SERIAL:   ${{ secrets.UNITY_SERIAL }}
+          UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
+          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
+          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
+          UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
@@
-          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
+          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
@@
-          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
+          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
@@
-          JSON
-                  
+          JSON
@@
-      - name: Prepare reports 
+      - name: Prepare reports
@@
-          
-        
+ 
+ 
@@
-          retention-days: 7
-        
+          retention-days: 7
+

Also applies to: 33-36, 79-82, 107-109, 207-207, 209-209, 462-463, 473-473


140-167: Optionally assert FRAMING preamble before declaring bridge ready.

Given the new strict FRAMING=1 handshake, probe a short preamble slice to catch regressions early. Non‑intrusive and fast.

-            if [ -n "${PORT:-}" ] && { try_connect_host "$PORT" || docker exec unity-mcp bash -lc "timeout 1 bash -lc 'exec 3<>/dev/tcp/127.0.0.1/$PORT' || (command -v nc >/dev/null 2>&1 && nc -6 -z ::1 $PORT)"; }; then
-              READY=1; echo "Bridge ready on port $PORT"; break
+            if [ -n "${PORT:-}" ] && { try_connect_host "$PORT" || docker exec unity-mcp bash -lc "timeout 1 bash -lc 'exec 3<>/dev/tcp/127.0.0.1/$PORT' || (command -v nc >/dev/null 2>&1 && nc -6 -z ::1 $PORT)"; }; then
+              # Best-effort preamble assert (expect 'FRAMING=1' within first 16 bytes)
+              PRE=$(timeout 1 bash -lc "exec 3<>/dev/tcp/127.0.0.1/$PORT; dd bs=1 count=16 <&3 2>/dev/null || true" || true)
+              if printf '%s' "$PRE" | grep -q 'FRAMING=1'; then
+                READY=1; echo "Bridge ready on port $PORT (preamble OK)"; break
+              else
+                echo "Port $PORT open but preamble missing; will continue waiting…"
+              fi
             fi

75-88: Make license priming non-fatal to avoid blocking the run.

If license seeding flakes, the container step may still succeed with EBL/ULF. Let the job continue.

-      - name: Prime Unity license on host (GameCI)
+      - name: Prime Unity license on host (GameCI)
         if: steps.detect.outputs.unity_ok == 'true'
         uses: game-ci/unity-test-runner@v4
+        continue-on-error: true
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 98e41eb and a26f073.

📒 Files selected for processing (2)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
  • .github/workflows/claude-nl-suite.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml

[warning] 26-26: too many spaces after colon

(colons)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 207-207: trailing spaces

(trailing-spaces)


[error] 209-209: trailing spaces

(trailing-spaces)


[error] 450-450: trailing spaces

(trailing-spaces)


[error] 462-462: trailing spaces

(trailing-spaces)


[error] 463-463: trailing spaces

(trailing-spaces)


[error] 473-473: trailing spaces

(trailing-spaces)

🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (level: "standard"`). Edits within a batch are applied atomica...

(QB_NEW_EN)


[grammar] ~25-~25: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT if set, otherwise ...

(QB_NEW_EN)


[grammar] ~29-~29: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...

(QB_NEW_EN)


[grammar] ~41-~41: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...

(QB_NEW_EN)


[grammar] ~44-~44: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...

(QB_NEW_EN)


[grammar] ~49-~49: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources/`read_r...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...ist_resources/read_resource, specify: - project_root: "TestProjects/UnityMCPTests" -ct...

(QB_NEW_EN)


[grammar] ~51-~51: There might be a mistake here.
Context: ...resource, specify: - project_root: "TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://pa...

(QB_NEW_EN)


[grammar] ~52-~52: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://path/Assets...

(QB_NEW_EN)


[grammar] ~59-~59: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...,T-G,T-H,T-I,T-J (len=16 inc. bootstrap) After each testcase, emit: PROGRESS: ...

(QB_NEW_EN)


[grammar] ~65-~65: There might be a mistake here.
Context: ...c. bootstrap) After each testcase, emit: PROGRESS: /16 completed ### NL-0. Sa...

(QB_NEW_EN)


[grammar] ~68-~68: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...

(QB_NEW_EN)


[grammar] ~73-~73: There might be a mistake here.
Context: ...er GetCurrentTarget logging "1,2,3". - Verify windows, then delete `PrintSeries...

(QB_NEW_EN)


[grammar] ~74-~74: There might be a mistake here.
Context: ...y windows, then delete PrintSeries(); confirm original hash. ### NL-2. Anchor commen...

(QB_NEW_EN)


[grammar] ~76-~76: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK immediately ...

(QB_NEW_EN)


[grammar] ~79-~79: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C ...

(QB_NEW_EN)


[grammar] ~80-~80: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C before final class brace; preserve indentation...

(QB_NEW_EN)


[grammar] ~82-~82: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...

(QB_NEW_EN)


[grammar] ~85-~85: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget, insert `privat...

(QB_NEW_EN)


[grammar] ~86-~86: There might be a mistake here.
Context: ..., int b) => a + b;viareplace_range` at insertion point; verify; then delete vi...

(QB_NEW_EN)


[grammar] ~91-~91: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend, modify interior lines ...

(QB_NEW_EN)


[grammar] ~94-~94: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...

(QB_NEW_EN)


[grammar] ~106-~106: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use validate_scriptwithlevel: "stan...

(QB_NEW_EN)


[grammar] ~109-~109: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"} - Stale file (old hash) → `{status:"stale_...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...

(QB_NEW_EN)


[grammar] ~113-~113: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"} - Parameter aliasing accepted; server echo...

(QB_NEW_EN)


[grammar] ~115-~115: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...

(QB_NEW_EN)


[grammar] ~123-~123: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...

(QB_NEW_EN)


[grammar] ~126-~126: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...

(QB_NEW_EN)


[grammar] ~128-~128: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...

(QB_NEW_EN)


[grammar] ~128-~128: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...

(QB_NEW_EN)


[grammar] ~136-~136: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...

(QB_NEW_EN)


[grammar] ~142-~142: There might be a mistake here.
Context: ...; re-read and confirm the hash matches. 6) Append VERDICT: PASSorVERDICT: FAIL...

(QB_NEW_EN)


[grammar] ~144-~144: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...

(QB_NEW_EN)


[grammar] ~180-~180: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf to restore exact content,...

(QB_NEW_EN)


[grammar] ~180-~180: There might be a mistake here.
Context: ...e minimal edit against current buf to restore exact content, then confirm hash matche...

(QB_NEW_EN)


[grammar] ~180-~180: There might be a mistake here.
Context: ...nt buf to restore exact content, then confirm hash matches the baseline. ### Status ...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: nl-suite
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (3)
.claude/prompts/nl-unity-suite-full.md (3)

17-23: Tool mapping and atomicity note look good.

Accurately distinguishes text vs. structured edits and clarifies atomic multi-edit batches. No change needed.


33-41: Confirm fragment filename pattern matches CI assembler.

Assembler globs reports/*_results.xml; your recommended reports/nl_final_results.xml is compatible. Keep this exact suffix to ensure pickup.

If you ever rename, ensure it still matches *_results.xml.


124-129: Hashing semantics are precise and aligned with server behavior.

Raw‑byte SHA‑256, guarded retry with server‑provided hash, and limited re‑reads will minimize false stale conflicts and reduce I/O.

dsarno added 2 commits August 27, 2025 20:01
…<cases> root and only <testcase> children; no raw text outside CDATA
…extracts <testcase> via regex on bad fragments
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
.claude/prompts/nl-unity-suite-full.md (1)

123-126: Good: precondition hashing over raw bytes is now explicit and consistent.

🧹 Nitpick comments (3)
.claude/prompts/nl-unity-suite-full.md (3)

156-165: Tighten null-safe hash selection in stale retry pseudo-code.

Use explicit null-safe semantics to avoid implying attribute errors in runner implementations.

-      next_sha = (res.data.current_sha256 or res.data.expected_sha256) if hasattr(res, 'data') else None
+      next_sha = res.data?.current_sha256 ?? res.data?.expected_sha256 ?? None

108-111: Clarify “too_large” threshold to match transport cap.

Add the concrete limit to reduce ambiguity.

-- Too large payload → `{status:"too_large"}`
+- Too large payload → `{status:"too_large"}` (e.g., payload >64 MiB per frame/request)

28-29: Specify AllowedTools logging format.

Make the required format explicit to avoid parsing ambiguity.

-- Log allowed tools once as a single line: `AllowedTools: ...`.
+- Log allowed tools once as a single line: `AllowedTools: <tool_id1,tool_id2,...>`.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a26f073 and 995529a.

📒 Files selected for processing (1)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (level: "standard"`). Edits within a batch are applied atomica...

(QB_NEW_EN)


[grammar] ~25-~25: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT if set, otherwise ...

(QB_NEW_EN)


[grammar] ~29-~29: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...

(QB_NEW_EN)


[grammar] ~40-~40: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...

(QB_NEW_EN)


[grammar] ~43-~43: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...

(QB_NEW_EN)


[grammar] ~48-~48: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources/`read_r...

(QB_NEW_EN)


[grammar] ~49-~49: There might be a mistake here.
Context: ...ist_resources/read_resource, specify: - project_root: "TestProjects/UnityMCPTests" -ct...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...resource, specify: - project_root: "TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://pa...

(QB_NEW_EN)


[grammar] ~51-~51: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://path/Assets...

(QB_NEW_EN)


[grammar] ~58-~58: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...

(QB_NEW_EN)


[grammar] ~59-~59: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...,T-G,T-H,T-I,T-J (len=16 inc. bootstrap) After each testcase, emit: PROGRESS: ...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...c. bootstrap) After each testcase, emit: PROGRESS: /16 completed ### NL-0. Sa...

(QB_NEW_EN)


[grammar] ~67-~67: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...

(QB_NEW_EN)


[grammar] ~72-~72: There might be a mistake here.
Context: ...er GetCurrentTarget logging "1,2,3". - Verify windows, then delete `PrintSeries...

(QB_NEW_EN)


[grammar] ~73-~73: There might be a mistake here.
Context: ...y windows, then delete PrintSeries(); confirm original hash. ### NL-2. Anchor commen...

(QB_NEW_EN)


[grammar] ~75-~75: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK immediately ...

(QB_NEW_EN)


[grammar] ~78-~78: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C ...

(QB_NEW_EN)


[grammar] ~79-~79: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C before final class brace; preserve indentation...

(QB_NEW_EN)


[grammar] ~81-~81: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...

(QB_NEW_EN)


[grammar] ~84-~84: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget, insert `privat...

(QB_NEW_EN)


[grammar] ~85-~85: There might be a mistake here.
Context: ..., int b) => a + b;viareplace_range` at insertion point; verify; then delete vi...

(QB_NEW_EN)


[grammar] ~90-~90: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend, modify interior lines ...

(QB_NEW_EN)


[grammar] ~93-~93: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...

(QB_NEW_EN)


[grammar] ~105-~105: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use validate_scriptwithlevel: "stan...

(QB_NEW_EN)


[grammar] ~108-~108: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...

(QB_NEW_EN)


[grammar] ~109-~109: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"} - Stale file (old hash) → `{status:"stale_...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...

(QB_NEW_EN)


[grammar] ~113-~113: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"} - Parameter aliasing accepted; server echo...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...

(QB_NEW_EN)


[grammar] ~122-~122: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...

(QB_NEW_EN)


[grammar] ~125-~125: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...

(QB_NEW_EN)


[grammar] ~127-~127: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...

(QB_NEW_EN)


[grammar] ~127-~127: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...

(QB_NEW_EN)


[grammar] ~135-~135: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...

(QB_NEW_EN)


[grammar] ~141-~141: There might be a mistake here.
Context: ...; re-read and confirm the hash matches. 6) Append VERDICT: PASSorVERDICT: FAIL...

(QB_NEW_EN)


[grammar] ~143-~143: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...

(QB_NEW_EN)


[grammar] ~179-~179: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf to restore exact content,...

(QB_NEW_EN)


[grammar] ~179-~179: There might be a mistake here.
Context: ...e minimal edit against current buf to restore exact content, then confirm hash matche...

(QB_NEW_EN)


[grammar] ~179-~179: There might be a mistake here.
Context: ...nt buf to restore exact content, then confirm hash matches the baseline. ### Status ...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot

…pt: require re-read after every revert; correct PLAN/PROGRESS to 15
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (5)
.github/workflows/claude-nl-suite-mini.yml (2)

47-53: Pin all third‑party Actions by immutable SHAs (supply‑chain hardening).

-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<commit-sha>

-      - uses: astral-sh/setup-uv@v4
+      - uses: astral-sh/setup-uv@<commit-sha>

-        uses: game-ci/unity-test-runner@v4
+        uses: game-ci/unity-test-runner@<commit-sha>

-        uses: anthropics/claude-code-base-action@beta
+        uses: anthropics/claude-code-base-action@<commit-sha>

-        uses: mikepenz/action-junit-report@v5
+        uses: mikepenz/action-junit-report@<commit-sha>

-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@<commit-sha>

Also applies to: 74-88, 214-229, 333-350


14-18: Pin Unity Docker image by digest to prevent tag drift.

   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pinned to immutable digest (replace <DIGEST> with resolved sha256)
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>

Also applies to: 126-139

.github/workflows/claude-nl-suite.yml (3)

460-462: Fix stale suite/classname: use NL‑T consistently.

-                '  <testcase classname="UnityMCP.NL" name="NL-Suite.Execution" time="0.0">' \
+                '  <testcase classname="UnityMCP.NL-T" name="NL-Suite.Execution" time="0.0">' \

47-47: Pin all third‑party Actions by immutable SHAs.

-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<commit-sha>
-      - uses: astral-sh/setup-uv@v4
+      - uses: astral-sh/setup-uv@<commit-sha>
-        uses: game-ci/unity-test-runner@v4
+        uses: game-ci/unity-test-runner@<commit-sha>
-        uses: anthropics/claude-code-base-action@beta
+        uses: anthropics/claude-code-base-action@<commit-sha>
-        uses: mikepenz/action-junit-report@v5
+        uses: mikepenz/action-junit-report@<commit-sha>
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@<commit-sha>

Also applies to: 52-52, 77-77, 251-261, 471-471, 483-483


14-18: Pin Unity Docker image by digest to prevent tag drift.

   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pin to immutable digest (replace <DIGEST>)
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>

Also applies to: 126-139

🧹 Nitpick comments (7)
.github/workflows/claude-nl-suite-mini.yml (3)

25-27: YAMLlint: remove extra spaces after colons (env maps).

Normalize to single space after colon to satisfy linters.

-      MD_OUT:    reports/junit-nl-suite.md
+      MD_OUT: reports/junit-nl-suite.md
-          UNITY_LICENSE:  ${{ secrets.UNITY_LICENSE }}
-          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
+          UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
+          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
-          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
-          UNITY_SERIAL:   ${{ secrets.UNITY_SERIAL }}
+          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
+          UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
-          UNITY_EMAIL:    ${{ secrets.UNITY_EMAIL }}
-          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
-          UNITY_SERIAL:   ${{ secrets.UNITY_SERIAL }}
+          UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
+          UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
+          UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}

Also applies to: 33-38, 79-82, 107-110, 218-221


206-206: Strip trailing spaces to fix YAMLlint errors.

-          
+
@@
-        
+
@@
-        
+

Also applies to: 331-331, 343-343


344-350: Artifacts: add retention and keep block well‑formed.

       with:
         name: claude-nl-suite-artifacts
         path: reports/**
+        retention-days: 7
.claude/prompts/nl-unity-suite-full.md (1)

25-39: Ensure CI normalizer ingests the “preferred” nl_final_results.xml format.

Doc says to write a single reports/nl_final_results.xml with <cases>/<testcase> elements. The full workflow’s normalizer currently imports *_results.xml fragments only. Please either (a) keep this “preferred” output and update the workflow to merge nl_final_results.xml, or (b) change the doc to prefer per‑test *_results.xml. I’ve proposed the workflow change in its file.

.github/workflows/claude-nl-suite.yml (3)

25-26: YAMLlint: remove extra spaces after colon (env).

-      MD_OUT:    reports/junit-nl-suite.md
+      MD_OUT: reports/junit-nl-suite.md

149-149: Broaden log redaction patterns (cover bearer/api/secret).

-docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$!
+docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token|api[_-]?key|bearer|secret)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$!

-docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
+docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token|api[_-]?key|bearer|secret)[^[:space:]]*)/[REDACTED]/ig' || true

-docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
+docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token|api[_-]?key|bearer|secret)[^[:space:]]*)/[REDACTED]/ig' || true

Also applies to: 182-182, 496-496


207-207: Strip trailing spaces flagged by YAMLlint.

-          JSON
-                  
+          JSON
+
@@
-      - name: Fallback JUnit if missing
+      - name: Fallback JUnit if missing
@@
-          fail_on_parse_error: true
-          
+          fail_on_parse_error: true
@@
-          retention-days: 7
-        
+          retention-days: 7

Also applies to: 209-209, 467-467, 479-480, 490-490

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 995529a and 9d2047c.

📒 Files selected for processing (3)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
  • .github/workflows/claude-nl-suite-mini.yml (1 hunks)
  • .github/workflows/claude-nl-suite.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite-mini.yml

[warning] 26-26: too many spaces after colon

(colons)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 206-206: trailing spaces

(trailing-spaces)


[warning] 219-219: too many spaces after colon

(colons)


[error] 331-331: trailing spaces

(trailing-spaces)


[error] 343-343: trailing spaces

(trailing-spaces)

.github/workflows/claude-nl-suite.yml

[warning] 26-26: too many spaces after colon

(colons)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 207-207: trailing spaces

(trailing-spaces)


[error] 209-209: trailing spaces

(trailing-spaces)


[error] 467-467: trailing spaces

(trailing-spaces)


[error] 479-479: trailing spaces

(trailing-spaces)


[error] 480-480: trailing spaces

(trailing-spaces)


[error] 490-490: trailing spaces

(trailing-spaces)

🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (level: "standard"`). Edits within a batch are applied atomica...

(QB_NEW_EN)


[grammar] ~25-~25: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT if set, otherwise ...

(QB_NEW_EN)


[grammar] ~29-~29: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...

(QB_NEW_EN)


[grammar] ~40-~40: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...

(QB_NEW_EN)


[grammar] ~43-~43: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...

(QB_NEW_EN)


[grammar] ~44-~44: There might be a mistake here.
Context: ...to confirm the revert before proceeding. - Never push commits from CI. - Do not mod...

(QB_NEW_EN)


[grammar] ~48-~48: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources/`read_r...

(QB_NEW_EN)


[grammar] ~49-~49: There might be a mistake here.
Context: ...ist_resources/read_resource, specify: - project_root: "TestProjects/UnityMCPTests" -ct...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...resource, specify: - project_root: "TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://pa...

(QB_NEW_EN)


[grammar] ~51-~51: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://path/Assets...

(QB_NEW_EN)


[grammar] ~58-~58: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...

(QB_NEW_EN)


[grammar] ~59-~59: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...T-C,T-D,T-E,T-F,T-G,T-H,T-I,T-J (len=15) After each testcase, emit: PROGRESS: ...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...,T-J (len=15) After each testcase, emit: PROGRESS: /15 completed ### NL-0. Sa...

(QB_NEW_EN)


[grammar] ~67-~67: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...

(QB_NEW_EN)


[grammar] ~72-~72: There might be a mistake here.
Context: ...er GetCurrentTarget logging "1,2,3". - Verify windows, then delete `PrintSeries...

(QB_NEW_EN)


[grammar] ~73-~73: There might be a mistake here.
Context: ...y windows, then delete PrintSeries(); confirm original hash. ### NL-2. Anchor commen...

(QB_NEW_EN)


[grammar] ~75-~75: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK immediately ...

(QB_NEW_EN)


[grammar] ~78-~78: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C ...

(QB_NEW_EN)


[grammar] ~79-~79: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C before final class brace; preserve indentation...

(QB_NEW_EN)


[grammar] ~81-~81: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...

(QB_NEW_EN)


[grammar] ~84-~84: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget, insert `privat...

(QB_NEW_EN)


[grammar] ~85-~85: There might be a mistake here.
Context: ..., int b) => a + b;viareplace_range` at insertion point; verify; then delete vi...

(QB_NEW_EN)


[grammar] ~90-~90: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend, modify interior lines ...

(QB_NEW_EN)


[grammar] ~93-~93: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...

(QB_NEW_EN)


[grammar] ~94-~94: There might be a mistake here.
Context: ...tion (anchor) - Find final class brace; insert helper before; then remove. ### T-E. T...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...

(QB_NEW_EN)


[grammar] ~105-~105: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use validate_scriptwithlevel: "stan...

(QB_NEW_EN)


[grammar] ~108-~108: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...

(QB_NEW_EN)


[grammar] ~109-~109: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"} - Stale file (old hash) → `{status:"stale_...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...

(QB_NEW_EN)


[grammar] ~113-~113: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"} - Parameter aliasing accepted; server echo...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...

(QB_NEW_EN)


[grammar] ~122-~122: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...

(QB_NEW_EN)


[grammar] ~125-~125: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...

(QB_NEW_EN)


[grammar] ~127-~127: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...

(QB_NEW_EN)


[grammar] ~127-~127: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...

(QB_NEW_EN)


[grammar] ~135-~135: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...

(QB_NEW_EN)


[grammar] ~140-~140: There might be a mistake here.
Context: ...windows; write JUnit + Markdown entries. 5) REVERT: if the test mutated the file, re...

(QB_NEW_EN)


[grammar] ~141-~141: There might be a mistake here.
Context: ...firm the hash matches before continuing. 6) Append VERDICT: PASS or `VERDICT: FAIL...

(QB_NEW_EN)


[grammar] ~143-~143: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...

(QB_NEW_EN)


[grammar] ~179-~179: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf to restore exact content,...

(QB_NEW_EN)


[grammar] ~179-~179: There might be a mistake here.
Context: ...e minimal edit against current buf to restore exact content, then confirm hash matche...

(QB_NEW_EN)


[grammar] ~179-~179: There might be a mistake here.
Context: ...nt buf to restore exact content, then confirm hash matches the baseline. ### Status ...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
.claude/prompts/nl-unity-suite-full.md (1)

29-31: Stale-file/guarded write flow is consistent and specific. LGTM.

Also applies to: 121-129, 145-175

dsarno added 2 commits August 27, 2025 20:24
…id create_script and env/mkdir checks, enforce single baseline-byte revert flow and post-revert re-read; add corruption-handling guidance
…ha; prefer script_apply_edits for anchors; avoid header/using changes
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
.github/workflows/claude-nl-suite.yml (4)

164-167: Refactor fragile JSON one-liner for port detection.

The double json.load and race-prone one-liner is brittle. Replace with a short Python snippet.

-            PORT=$(python -c "import os,glob,json,sys,time; b=os.path.expanduser('~/.unity-mcp'); fs=sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True); print(next((json.load(open(f,'r',encoding='utf-8')).get('unity_port') for f in fs if time.time()-os.path.getmtime(f)<=300 and json.load(open(f,'r',encoding='utf-8')).get('unity_port')), '' ))" 2>/dev/null || true)
+            PORT=$(python - <<'PY' 2>/dev/null || true
+import os, glob, json, time, sys
+b = os.path.expanduser('~/.unity-mcp')
+ports = []
+for f in sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True):
+    try:
+        if time.time() - os.path.getmtime(f) > 300: 
+            continue
+        with open(f, 'r', encoding='utf-8') as fh:
+            data = json.load(fh)
+        p = data.get('unity_port')
+        if p: 
+            ports.append(str(p))
+    except Exception:
+        pass
+print(ports[0] if ports else(''))
+PY
+)

47-47: Pin Actions to immutable commit SHAs.

Mutable tags are supply-chain risk. Pin each Action to a full commit SHA.

-      - uses: actions/checkout@v4
+      - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955  # v4.1.7

-      - uses: astral-sh/setup-uv@v4
+      - uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a

-        uses: game-ci/unity-test-runner@v4
+        uses: game-ci/unity-test-runner@0ff419b913a3630032cbe0de48a0099b5a9f0ed9

-        uses: anthropics/claude-code-base-action@beta
+        uses: anthropics/claude-code-base-action@e9863f822497ff36abdac4571937150d27397a34

-        uses: mikepenz/action-junit-report@v5
+        uses: mikepenz/action-junit-report@db71d41eb79864e25ab0337e395c352e84523afe

-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02

Also applies to: 52-52, 75-78, 251-251, 471-471, 483-483


14-17: Pin Unity image by digest to avoid tag drift.

Pin the Docker image to a sha256 digest.

 env:
   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pinned for reproducibility (replace <DIGEST> with resolved sha256)
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>
   UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home

290-321: Normalizer should import preferred nl_final_results.xml and roots.

Doc’s “preferred single-file” isn’t currently ingested. Extend the normalizer.

-                  # Append any testcase fragments from reports/*_results.xml
-                  fragments = sorted(Path('reports').glob('*_results.xml'))
+                  # Append any testcase fragments from reports/*_results.xml
+                  fragments = sorted(Path('reports').glob('*_results.xml'))
+                  # Also support preferred single-file output
+                  preferred = Path('reports/nl_final_results.xml')
+                  if preferred.exists():
+                      try:
+                          proot = ET.parse(preferred).getroot()
+                          if localname(proot.tag) == 'cases':
+                              for tc in proot.findall('./testcase'):
+                                  suite.append(tc)
+                      except Exception as pe:
+                          print(f"Parse error for preferred file {preferred}: {pe}")
🧹 Nitpick comments (4)
.claude/prompts/nl-unity-suite-full.md (2)

124-128: Unify post-write re-read policy (conflicting guidance).

“Implementation notes” says to avoid re-read when positions are stable, while “Guarded write pattern” says to immediately re-read after every successful write. Pick one policy and state it once.

-- CRITICAL: After every successful write, immediately re-read raw bytes from disk and set `pre_sha` to the on-disk hash before any further edits within the same test.
+- CRITICAL: After a successful write, refresh `pre_sha` to the on-disk hash before any further edit that depends on absolute offsets. Otherwise, you may continue using the local buf and defer the re-read until validation or revert requires it.

Also delete the “Optionally refresh pre_sha…” comment in the pseudo-code to avoid mixed signals.

Also applies to: 149-161


153-181: Clarify response shape in pseudo-code.

Avoid hasattr(res, 'data') in examples; specify a stable field for the server-provided hash to prevent ambiguous client implementations.

- next_sha = (res.data.current_sha256 or res.data.expected_sha256) if hasattr(res, 'data') else None
+ next_sha = (res.current_sha256 or res.expected_sha256 or (res.data or {}).get('current_sha256') or (res.data or {}).get('expected_sha256'))
.github/workflows/claude-nl-suite.yml (2)

207-209: Strip trailing spaces; fix minor YAML lint warnings.

Remove trailing spaces at noted lines to satisfy linters.

-          JSON
-                  
+          JSON
@@
-        
+ 
@@
-          
-        
+ 
@@
-          retention-days: 7
-        
+          retention-days: 7

Also applies to: 467-467, 479-480, 490-490


178-183: Redact potential secrets in status dump as well.

Mask obvious secret-like tokens when printing status files.

-            echo "== status contents =="; for f in "$HOME"/.unity-mcp/unity-mcp-status-*.json; do [ -f "$f" ] && { echo "--- $f"; sed -n '1,120p' "$f"; }; done
+            echo "== status contents =="; for f in "$HOME"/.unity-mcp/unity-mcp-status-*.json; do
+              [ -f "$f" ] || continue
+              echo "--- $f"
+              sed -n '1,120p' "$f" | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig'
+            done
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9d2047c and b032f33.

📒 Files selected for processing (2)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
  • .github/workflows/claude-nl-suite.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml

[warning] 26-26: too many spaces after colon

(colons)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 207-207: trailing spaces

(trailing-spaces)


[error] 209-209: trailing spaces

(trailing-spaces)


[error] 467-467: trailing spaces

(trailing-spaces)


[error] 479-479: trailing spaces

(trailing-spaces)


[error] 480-480: trailing spaces

(trailing-spaces)


[error] 490-490: trailing spaces

(trailing-spaces)

🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (level: "standard"). - Do not use mcp__unity__create_script`; ...

(QB_NEW_EN)


[grammar] ~26-~26: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT if set, otherwise ...

(QB_NEW_EN)


[grammar] ~30-~30: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...

(QB_NEW_EN)


[grammar] ~34-~34: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...

(QB_NEW_EN)


[grammar] ~42-~42: There might be a mistake here.
Context: ...hesize the final markdown from JUnit. - Keep transient state in memory; if persisten...

(QB_NEW_EN)


[grammar] ~45-~45: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources/`read_r...

(QB_NEW_EN)


[grammar] ~51-~51: There might be a mistake here.
Context: ...ist_resources/read_resource, specify: - project_root: "TestProjects/UnityMCPTests" -ct...

(QB_NEW_EN)


[grammar] ~52-~52: There might be a mistake here.
Context: ...resource, specify: - project_root: "TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://pa...

(QB_NEW_EN)


[grammar] ~53-~53: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://path/Assets...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...

(QB_NEW_EN)


[grammar] ~64-~64: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...

(QB_NEW_EN)


[grammar] ~65-~65: There might be a mistake here.
Context: ...T-C,T-D,T-E,T-F,T-G,T-H,T-I,T-J (len=15) After each testcase, emit: PROGRESS: ...

(QB_NEW_EN)


[grammar] ~66-~66: There might be a mistake here.
Context: ...,T-J (len=15) After each testcase, emit: PROGRESS: /15 completed ### NL-0. Sa...

(QB_NEW_EN)


[grammar] ~69-~69: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...

(QB_NEW_EN)


[grammar] ~74-~74: There might be a mistake here.
Context: ...er GetCurrentTarget logging "1,2,3". - Verify windows, then delete `PrintSeries...

(QB_NEW_EN)


[grammar] ~75-~75: There might be a mistake here.
Context: ...y windows, then delete PrintSeries(); confirm original hash. ### NL-2. Anchor commen...

(QB_NEW_EN)


[grammar] ~77-~77: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK immediately ...

(QB_NEW_EN)


[grammar] ~80-~80: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C ...

(QB_NEW_EN)


[grammar] ~81-~81: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C before final class brace; preserve indentation...

(QB_NEW_EN)


[grammar] ~83-~83: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...

(QB_NEW_EN)


[grammar] ~86-~86: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget, insert `privat...

(QB_NEW_EN)


[grammar] ~87-~87: There might be a mistake here.
Context: ..., int b) => a + b;viareplace_range` at insertion point; verify; then delete vi...

(QB_NEW_EN)


[grammar] ~92-~92: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend, modify interior lines ...

(QB_NEW_EN)


[grammar] ~95-~95: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...tion (anchor) - Find final class brace; insert helper before; then remove. ### T-E. T...

(QB_NEW_EN)


[grammar] ~105-~105: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...

(QB_NEW_EN)


[grammar] ~107-~107: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use validate_scriptwithlevel: "stan...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"} - Stale file (old hash) → `{status:"stale_...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...

(QB_NEW_EN)


[grammar] ~113-~113: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...

(QB_NEW_EN)


[grammar] ~115-~115: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"} - Parameter aliasing accepted; server echo...

(QB_NEW_EN)


[grammar] ~116-~116: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...

(QB_NEW_EN)


[grammar] ~124-~124: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...

(QB_NEW_EN)


[grammar] ~127-~127: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...

(QB_NEW_EN)


[grammar] ~129-~129: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...

(QB_NEW_EN)


[grammar] ~129-~129: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...

(QB_NEW_EN)


[grammar] ~137-~137: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...

(QB_NEW_EN)


[grammar] ~143-~143: There might be a mistake here.
Context: ...irm the baseline hash before continuing. 6) Append VERDICT: PASS or `VERDICT: FAIL...

(QB_NEW_EN)


[grammar] ~145-~145: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...

(QB_NEW_EN)


[grammar] ~147-~147: There might be a mistake here.
Context: ... write pattern (must use for every edit) Hash refresh and anchors (priority rules...

(QB_NEW_EN)


[grammar] ~148-~148: There might be a mistake here.
Context: ...sh refresh and anchors (priority rules): - CRITICAL: After every successful write, ...

(QB_NEW_EN)


[grammar] ~149-~149: There might be a mistake here.
Context: ... any further edits within the same test. - Prefer mcp__unity__script_apply_edits ...

(QB_NEW_EN)


[grammar] ~188-~188: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf to restore exact content,...

(QB_NEW_EN)


[grammar] ~188-~188: There might be a mistake here.
Context: ...e minimal edit against current buf to restore exact content, then confirm hash matche...

(QB_NEW_EN)


[grammar] ~188-~188: There might be a mistake here.
Context: ...nt buf to restore exact content, then confirm hash matches the baseline. ### Status ...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: nl-suite
  • GitHub Check: Cursor Bugbot

…ends via Write or Bash(printf/echo); forbid wrappers and full-file round-trips
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
.claude/prompts/nl-unity-suite-full.md (1)

29-29: Specify exactly where to log AllowedTools.

To avoid duplicate/stray logs, specify that the single “AllowedTools: …” line must be emitted inside the NL-0 testcase’s <system-out> only.

-- Log allowed tools once as a single line: `AllowedTools: ...`.
+- Log allowed tools once as a single line: `AllowedTools: ...` inside NL-0 `<system-out>` only (do not repeat in later testcases).

Also applies to: 34-39, 66-66

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b032f33 and 9c07afc.

📒 Files selected for processing (1)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~17-~17: There might be a mistake here.
Context: ...tools. ## Tool mapping (use these APIs) When the tests say replace_range or ...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...t for validation (level: "standard"). - Do not use mcp__unity__create_script`; ...

(QB_NEW_EN)


[grammar] ~26-~26: There might be a mistake here.
Context: ...equirements (match NL suite conventions) - JUnit at $JUNIT_OUT (canonical). Suite...

(QB_NEW_EN)


[grammar] ~28-~28: There might be a mistake here.
Context: ...t $MD_OUT (canonical). CI synthesizes at end; you may append small fragments but...

(QB_NEW_EN)


[grammar] ~28-~28: There might be a mistake here.
Context: ...gments but do not round‑trip full files. - Log allowed tools once as a single line:...

(QB_NEW_EN)


[grammar] ~30-~30: There might be a mistake here.
Context: ...wise perform a single re-read and retry. - Evidence windows only (±20–40 lines); ca...

(QB_NEW_EN)


[grammar] ~34-~34: There might be a mistake here.
Context: ... ### Reporting discipline (must-follow) - CI pre-creates the report skeletons. Do ...

(QB_NEW_EN)


[grammar] ~37-~37: There might be a mistake here.
Context: ...o full‑file round‑trips and no wrappers. - All human‑readable lines (PLAN, AllowedT...

(QB_NEW_EN)


[grammar] ~38-~38: There might be a mistake here.
Context: ...]]>within a`. - Keep transient state in memory. ## Safe...

(QB_NEW_EN)


[grammar] ~42-~42: There might be a mistake here.
Context: ...er validation so the workspace is clean. - At suite start, capture baseline `{ text...

(QB_NEW_EN)


[grammar] ~47-~47: There might be a mistake here.
Context: ...ning per workflow. ## CI headless hints - For mcp__unity__list_resources/`read_r...

(QB_NEW_EN)


[grammar] ~48-~48: There might be a mistake here.
Context: ...ist_resources/read_resource, specify: - project_root: "TestProjects/UnityMCPTests" -ct...

(QB_NEW_EN)


[grammar] ~49-~49: There might be a mistake here.
Context: ...resource, specify: - project_root: "TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://pa...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...TestProjects/UnityMCPTests" -ctx: {}- Canonical URIs: -unity://path/Assets...

(QB_NEW_EN)


[grammar] ~57-~57: There might be a mistake here.
Context: ...order (must follow; do not regex-filter) Run tests exactly in this order: NL-0, N...

(QB_NEW_EN)


[grammar] ~58-~58: There might be a mistake here.
Context: ...filter) Run tests exactly in this order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, ...

(QB_NEW_EN)


[grammar] ~59-~59: There might be a mistake here.
Context: ...his order: NL-0, NL-1, NL-2, NL-3, NL-4, T-A, T-B, T-C, T-D, T-E, T-F, T-G, T-H, ...

(QB_NEW_EN)


[grammar] ~60-~60: There might be a mistake here.
Context: ... T-C, T-D, T-E, T-F, T-G, T-H, T-I, T-J. At suite start, emit a single line plan:...

(QB_NEW_EN)


[grammar] ~61-~61: There might be a mistake here.
Context: ...At suite start, emit a single line plan: PLAN: NL-0,NL-1,NL-2,NL-3,NL-4,T-A,T-B,T...

(QB_NEW_EN)


[grammar] ~62-~62: There might be a mistake here.
Context: ...T-C,T-D,T-E,T-F,T-G,T-H,T-I,T-J (len=15) After each testcase, emit: PROGRESS: ...

(QB_NEW_EN)


[grammar] ~63-~63: There might be a mistake here.
Context: ...,T-J (len=15) After each testcase, emit: PROGRESS: /15 completed ### NL-0. Sa...

(QB_NEW_EN)


[grammar] ~66-~66: There might be a mistake here.
Context: ...leted ### NL-0. Sanity Reads (windowed) - Tail 120 lines; read 40 lines around `Up...

(QB_NEW_EN)


[grammar] ~71-~71: There might be a mistake here.
Context: ...er GetCurrentTarget logging "1,2,3". - Verify windows, then delete `PrintSeries...

(QB_NEW_EN)


[grammar] ~72-~72: There might be a mistake here.
Context: ...y windows, then delete PrintSeries(); confirm original hash. ### NL-2. Anchor commen...

(QB_NEW_EN)


[grammar] ~74-~74: There might be a mistake here.
Context: ...ash. ### NL-2. Anchor comment insertion - Insert // Build marker OK immediately ...

(QB_NEW_EN)


[grammar] ~77-~77: There might be a mistake here.
Context: ...docs). ### NL-3. End-of-class insertion - Insert three lines // Tail test A/B/C ...

(QB_NEW_EN)


[grammar] ~78-~78: There might be a mistake here.
Context: ...Insert three lines // Tail test A/B/C before final class brace; preserve indentation...

(QB_NEW_EN)


[grammar] ~80-~80: There might be a mistake here.
Context: ... ### NL-4. Compile trigger (record-only) - Ensure no obvious syntax issues; record ...

(QB_NEW_EN)


[grammar] ~83-~83: There might be a mistake here.
Context: ...NFO. ### T-A. Anchor insert (text path) - After GetCurrentTarget, insert `privat...

(QB_NEW_EN)


[grammar] ~84-~84: There might be a mistake here.
Context: ..., int b) => a + b;viareplace_range` at insertion point; verify; then delete vi...

(QB_NEW_EN)


[grammar] ~89-~89: There might be a mistake here.
Context: ...rt. ### T-C. Header/region preservation - For ApplyBlend, modify interior lines ...

(QB_NEW_EN)


[grammar] ~92-~92: There might be a mistake here.
Context: ...### T-D. End-of-class insertion (anchor) - Find final class brace; insert helper be...

(QB_NEW_EN)


[grammar] ~102-~102: There might be a mistake here.
Context: ...alization - Run the same edit with both URIs; second attempt should return `{ status:...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ..._change" }. ### T-H. Validation levels - Use validate_scriptwithlevel: "stan...

(QB_NEW_EN)


[grammar] ~107-~107: There might be a mistake here.
Context: ...s. ### T-I. Failure surfaces (expected) - Too large payload → `{status:"too_large"...

(QB_NEW_EN)


[grammar] ~108-~108: There might be a mistake here.
Context: ...rfaces (expected) - Too large payload → {status:"too_large"} - Stale file (old hash) → `{status:"stale_...

(QB_NEW_EN)


[grammar] ~109-~109: There might be a mistake here.
Context: ..."too_large"}- Stale file (old hash) →{status:"stale_file"}` - Overlap → rejection - Unbalanced braces ...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ...tus:"stale_file"}` - Overlap → rejection - Unbalanced braces → validation failure -...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...- Unbalanced braces → validation failure - Using-directives guard → `{status:"using...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...tion failure - Using-directives guard → {status:"using_guard"} - Parameter aliasing accepted; server echo...

(QB_NEW_EN)


[grammar] ~113-~113: There might be a mistake here.
Context: ... accepted; server echoes canonical keys. - Auto-upgrade: prefer structured edits or...

(QB_NEW_EN)


[grammar] ~121-~121: There might be a mistake here.
Context: ...indows; include pre/post hashes in logs. - Maintain a per-test in-memory working bu...

(QB_NEW_EN)


[grammar] ~124-~124: There might be a mistake here.
Context: ...; otherwise record failure and continue. - Re-read only at well-defined points: (a)...

(QB_NEW_EN)


[grammar] ~126-~126: There might be a mistake here.
Context: ...t the end of each test, then re-read to confirm clean state before the next test. - Nev...

(QB_NEW_EN)


[grammar] ~126-~126: There might be a mistake here.
Context: ...onfirm clean state before the next test. - Never abort the suite on a single test f...

(QB_NEW_EN)


[grammar] ~134-~134: There might be a mistake here.
Context: ... bytes)>` ### Test driver (must follow) For each test NL-0..NL-4, then T-A..T-J:...

(QB_NEW_EN)


[grammar] ~140-~140: There might be a mistake here.
Context: ...irm the baseline hash before continuing. 6) Append VERDICT: PASS or `VERDICT: FAIL...

(QB_NEW_EN)


[grammar] ~142-~142: There might be a mistake here.
Context: ...7) Continue to the next test regardless of outcome. ### Guarded write pattern (mu...

(QB_NEW_EN)


[grammar] ~144-~144: There might be a mistake here.
Context: ... write pattern (must use for every edit) Hash refresh and anchors (priority rules...

(QB_NEW_EN)


[grammar] ~145-~145: There might be a mistake here.
Context: ...sh refresh and anchors (priority rules): - CRITICAL: After every successful write o...

(QB_NEW_EN)


[grammar] ~146-~146: There might be a mistake here.
Context: ... any further edits within the same test. - Prefer mcp__unity__script_apply_edits ...

(QB_NEW_EN)


[grammar] ~185-~185: There might be a mistake here.
Context: ...not available, compute the minimal edit against current buf to restore exact content,...

(QB_NEW_EN)


[grammar] ~185-~185: There might be a mistake here.
Context: ...e minimal edit against current buf to restore exact content, then confirm hash matche...

(QB_NEW_EN)


[grammar] ~185-~185: There might be a mistake here.
Context: ...nt buf to restore exact content, then confirm hash matches the baseline. ### Status ...

(QB_NEW_EN)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
.claude/prompts/nl-unity-suite-full.md (1)

30-31: Stale-file retry semantics are now consistent. LGTM.

Output Requirements (Line 30) and Implementation notes (Lines 124–125) agree on a single guarded retry using server-provided hashes before any re-read. Good alignment.

Also applies to: 124-125

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (8)
.github/workflows/claude-nl-suite-mini.yml (3)

14-18: Pin Unity Docker image by digest (prevent tag drift).

Use an immutable sha256 to ensure reproducible CI.

 env:
   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pin to immutable digest
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>
   UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home

47-55: Pin all third‑party Actions by commit SHA (supply‑chain hardening).

Replace mutable tags (@v4/@beta/@v5) with exact SHAs.

-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<commit-sha>

-      - uses: astral-sh/setup-uv@v4
+      - uses: astral-sh/setup-uv@<commit-sha>

-        uses: game-ci/unity-test-runner@v4
+        uses: game-ci/unity-test-runner@<commit-sha>

-        uses: anthropics/claude-code-base-action@beta
+        uses: anthropics/claude-code-base-action@<commit-sha>

-        uses: mikepenz/action-junit-report@v5
+        uses: mikepenz/action-junit-report@<commit-sha>

-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@<commit-sha>

Also applies to: 74-88, 213-229, 333-351


221-224: Fix prompt_file path (likely mismatch → file-not-found).

Align to the actual prompt file name used elsewhere in the repo/PR.

-          prompt_file: .claude/prompts/nl-unity-claude-tests-mini.md
+          prompt_file: .claude/prompts/nl-unity-tests-mini.md
.claude/prompts/nl-unity-suite-full.md (2)

73-76: Revert policy: explicitly require re-read to confirm baseline.

Make the revert confirmation unambiguous.

-- Restore exact pre-test bytes via a single full-file replace with `precondition_sha256` = current on-disk sha (or server-provided hash on stale), then re-read to confirm baseline hash.
+- Restore exact pre-test bytes via a single full-file replace with `precondition_sha256` = current on-disk sha (or server-provided hash on stale), then re-read and verify sha256 matches the captured baseline before proceeding.

61-72: Guarded write: avoid mandatory post-write disk re-read.

Re-reading after every write harms perf and contradicts “minimal reads” guidance. Refresh from disk only when required (validation/anchors/before exit).

-- After every successful write:
-  - Immediately re-read raw bytes and set `pre_sha = sha256(read_bytes(uri))` before any further edits in the same test.
+- After a successful write:
+  - Update in-memory buffer. Refresh `pre_sha` from on-disk bytes only when the next step requires exact sync (validation, anchor recompute) or before leaving the test.
.github/workflows/claude-nl-suite.yml (3)

246-299: Normalizer: also import preferred single-file nl_final_results.xml and <cases> roots.

Ensure we consume the documented “preferred” output path.

-                # Append any testcase fragments from reports/*_results.xml
-                fragments = sorted(Path('reports').glob('*_results.xml'))
+                # Append testcase fragments from shards and preferred single-file
+                fragments = sorted(Path('reports').glob('*_results.xml'))
+                preferred = Path('reports/nl_final_results.xml')
+                if preferred.exists():
+                    fragments.append(preferred)
@@
-                        if localname(froot.tag) == 'testcase':
+                        tag = localname(froot.tag)
+                        if tag == 'testcase':
                             suite.append(froot); added += 1
-                        else:
+                        elif tag == 'cases':
+                            for tc in froot.findall('./testcase'):
+                                suite.append(tc); added += 1
+                        else:
                             for tc in froot.findall('.//testcase'):
                                 suite.append(tc); added += 1

14-18: Pin Unity Docker image by digest (prevent tag drift).

Use an immutable sha256 to stabilize runs.

 env:
   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pin to immutable digest
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>
   UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home

47-55: Pin all third‑party Actions by commit SHA.

Replace mutable tags to reduce supply‑chain risk.

-        - uses: actions/checkout@v4
+        - uses: actions/checkout@<commit-sha>
-        - uses: astral-sh/setup-uv@v4
+        - uses: astral-sh/setup-uv@<commit-sha>
-          uses: game-ci/unity-test-runner@v4
+          uses: game-ci/unity-test-runner@<commit-sha>
-          uses: anthropics/claude-code-base-action@beta
+          uses: anthropics/claude-code-base-action@<commit-sha>
-          uses: mikepenz/action-junit-report@v5
+          uses: mikepenz/action-junit-report@<commit-sha>
-          uses: actions/upload-artifact@v4
+          uses: actions/upload-artifact@<commit-sha>

Also applies to: 74-88, 222-245, 417-427, 428-439

🧹 Nitpick comments (4)
.github/workflows/claude-nl-suite-mini.yml (2)

206-206: YAML lint: remove trailing spaces and extra alignment after colons.

Clean up trailing spaces and over-aligned values to satisfy YAML/actionlint.

-          JSON
-          
+          JSON
@@
-          MD_OUT:    reports/junit-nl-suite.md
+          MD_OUT: reports/junit-nl-suite.md
@@
-        
+
@@
-        
+

Also applies to: 219-219, 331-331, 343-343


344-350: Artifacts: add retention-days.

Keep artifacts for a bounded time and fix indent.

       - name: Upload artifacts
         if: always()
         uses: actions/upload-artifact@v4
         with:
-          name: claude-nl-suite-artifacts
-          path: reports/**
+          name: claude-nl-suite-artifacts
+          path: reports/**
+          retention-days: 7
.claude/prompts/nl-unity-suite-full.md (1)

31-37: Standardize read_console tool ID to mcp__unity__read_console

  • In .claude/prompts/nl-unity-suite-full.md (lines 31–40), replace the stray mcp__read__console entry with mcp__unity__read_console.
  • Ensure mcp__unity__read_console is also included in the allowed_tools list of .github/workflows/claude-nl-suite-full.yml.
.github/workflows/claude-nl-suite.yml (1)

331-346: YAML lint: trailing spaces and over-aligned colons.

Tighten formatting to silence YAMLlint.

-            lines += ['# Unity NL/T Editing Suite Test Results','',f'Totals: {passed} passed, {failures} failed, {total} total','', '## Test Checklist']
+            lines += ['# Unity NL/T Editing Suite Test Results','',f'Totals: {passed} passed, {failures} failed, {total} total','', '## Test Checklist']
@@
-            if [ ! -f "$JUNIT_OUT" ]; then
+            if [ ! -f "$JUNIT_OUT" ]; then
               printf '%s\n' \
                 '<?xml version="1.0" encoding="UTF-8"?>' \
                 '<testsuite name="UnityMCP.NL-T" tests="1" failures="1" time="0">' \
                 '  <testcase classname="UnityMCP.NL-T" name="NL-Suite.Execution" time="0.0">' \
                 '    <failure><![CDATA[No JUnit was produced by the NL suite step. See the step logs.]]></failure>' \
                 '  </testcase>' \
                 '</testsuite>' \
                 > "$JUNIT_OUT"
             fi
@@
-            docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
+            docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
             docker rm -f unity-mcp || true

Also applies to: 401-416, 439-446

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9c07afc and e016171.

📒 Files selected for processing (3)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
  • .github/workflows/claude-nl-suite-mini.yml (1 hunks)
  • .github/workflows/claude-nl-suite.yml (1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~5-~5: There might be a mistake here.
Context: ...this once, verbatim, early in the run:** AllowedTools: Write,Bash(printf:*),Bash(...

(QB_NEW_EN)


[grammar] ~16-~16: There might be a mistake here.
Context: ...5) Revert file changes after each test; keep workspace clean. --- ## Environment &...

(QB_NEW_EN)


[grammar] ~20-~20: There might be a mistake here.
Context: ...clean. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...nd ctx: {} on list/read/edit/validate. - Canonical URIs only: - Primary: `uni...

(QB_NEW_EN)


[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - Canonical URIs only: - Primary: unity://path/Assets/... (neve...

(QB_NEW_EN)


[grammar] ~23-~23: There might be a mistake here.
Context: ...never embed project_root into the URI) - Relative (when supported): Assets/... ...

(QB_NEW_EN)


[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI) - Relative (when supported): Assets/... - CI prepares: - `$JUNIT_OUT=reports/jun...

(QB_NEW_EN)


[grammar] ~31-~31: There might be a mistake here.
Context: ...esizes from JUnit) --- ## Tool Mapping - Anchors/regex/structured: `mcp__unity_...

(QB_NEW_EN)


[grammar] ~32-~32: There might be a mistake here.
Context: ...Mapping - Anchors/regex/structured: mcp__unity__script_apply_edits - **Precise ranges / atomic multi‑edit batch...

(QB_NEW_EN)


[grammar] ~33-~33: There might be a mistake here.
Context: ...ply_text_edits(non‑overlapping ranges) - **Validation**:mcp__unity__validate_scri...

(QB_NEW_EN)


[grammar] ~34-~34: There might be a mistake here.
Context: ...n‑overlapping ranges) - Validation: mcp__unity__validate_script(level:"standard") - Reporting: Write small XML fragments...

(QB_NEW_EN)


[grammar] ~35-~35: There might be a mistake here.
Context: ...ML fragments to reports/*_results.xml. Bash is allowed but not required; do not...

(QB_NEW_EN)


[grammar] ~38-~38: There might be a mistake here.
Context: ...nsole”, or any tool not in AllowedTools. > Never edit using directives or the hea...

(QB_NEW_EN)


[grammar] ~45-~45: There might be a mistake here.
Context: ... ]]>of that testcase’s`. - Evidence windows only (±20–40 lines). If...

(QB_NEW_EN)

🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml

[warning] 20-20: wrong indentation: expected 2 but found 4

(indentation)


[warning] 26-26: too many spaces after colon

(colons)


[error] 27-27: trailing spaces

(trailing-spaces)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[error] 46-46: trailing spaces

(trailing-spaces)


[error] 50-50: trailing spaces

(trailing-spaces)


[error] 55-55: trailing spaces

(trailing-spaces)


[error] 73-73: trailing spaces

(trailing-spaces)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[error] 88-88: trailing spaces

(trailing-spaces)


[error] 95-95: trailing spaces

(trailing-spaces)


[error] 102-102: trailing spaces

(trailing-spaces)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 139-139: trailing spaces

(trailing-spaces)


[error] 179-179: trailing spaces

(trailing-spaces)


[error] 201-201: trailing spaces

(trailing-spaces)


[error] 208-208: trailing spaces

(trailing-spaces)


[error] 221-221: trailing spaces

(trailing-spaces)


[error] 245-245: trailing spaces

(trailing-spaces)


[error] 255-255: trailing spaces

(trailing-spaces)


[error] 258-258: trailing spaces

(trailing-spaces)


[error] 264-264: trailing spaces

(trailing-spaces)


[error] 273-273: trailing spaces

(trailing-spaces)


[error] 299-299: trailing spaces

(trailing-spaces)


[error] 346-346: trailing spaces

(trailing-spaces)


[error] 358-358: trailing spaces

(trailing-spaces)


[error] 370-370: trailing spaces

(trailing-spaces)


[error] 383-383: trailing spaces

(trailing-spaces)


[error] 400-400: trailing spaces

(trailing-spaces)


[error] 416-416: trailing spaces

(trailing-spaces)


[error] 427-427: trailing spaces

(trailing-spaces)


[error] 439-439: trailing spaces

(trailing-spaces)


[error] 446-446: no new line character at the end of file

(new-line-at-end-of-file)


[error] 446-446: trailing spaces

(trailing-spaces)

.github/workflows/claude-nl-suite-mini.yml

[warning] 26-26: too many spaces after colon

(colons)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 206-206: trailing spaces

(trailing-spaces)


[warning] 219-219: too many spaces after colon

(colons)


[error] 331-331: trailing spaces

(trailing-spaces)


[error] 343-343: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: nl-suite
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (3)
.github/workflows/claude-nl-suite.yml (3)

212-221: Heredoc indentation: keep the entire payload indented consistently.

This block looks correct now; leaving a note to retain exact indent to avoid YAML parse errors.


221-245: Workflow step gating and parameters look correct.

Gated on both Anthropic and Unity; good use of continue-on-error for resilience.


428-439: Artifacts block: good coverage and retention; keep.

Includes JUnit, MD, fragments, transcript with retention-days.

…s, Status as proper markdown lists and code fences
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
.claude/prompts/nl-unity-suite-full.md (3)

14-14: Clarify validation exception for read-only steps.

Avoid forcing validation when no mutation occurred.

-3) Validate each edit with `mcp__unity__validate_script(level:"standard")`.
+3) Validate each edit with `mcp__unity__validate_script(level:"standard")` (skip for read‑only steps).

52-52: Use a proper heading for the example block (MD036).

-**Example fragment**
+### Example fragment

68-76: Ensure snapshot directory exists before writing baseline.

Prevents failures on first run in clean workspaces.

 - Snapshot (once after confirming the target):
   ```bash
+  mkdir -p reports/_snapshots
   scripts/nlt-revert.sh snapshot "TestProjects/UnityMCPTests/Assets/Scripts/LongUnityScriptClaudeTest.cs" "reports/_snapshots/LongUnityScriptClaudeTest.cs.baseline"

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used**: CodeRabbit UI

**Review profile**: CHILL

**Plan**: Pro

**💡 Knowledge Base configuration:**

- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between e016171cf891432712ee721194800594b315a545 and 5dad550df1d7d7ebf18f4dee14eb2ce17c2493af.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `.claude/prompts/nl-unity-suite-full.md` (1 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 LanguageTool</summary>

<details>
<summary>.claude/prompts/nl-unity-suite-full.md</summary>

[grammar] ~5-~5: There might be a mistake here.
Context: ...this once, verbatim, early in the run:** AllowedTools: Write,Bash(printf:*),Bash(...

(QB_NEW_EN)

---

[grammar] ~10-~10: There might be a mistake here.
Context: ...cp__unity__read_console  ---  ## Mission 1) Pick target file (prefer):    - `unity:/...

(QB_NEW_EN)

---

[grammar] ~20-~20: There might be a mistake here.
Context: ...write.  ---  ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...

(QB_NEW_EN)

---

[grammar] ~21-~21: There might be a mistake here.
Context: ...nd `ctx: {}` on list/read/edit/validate. - **Canonical URIs only**:   - Primary: `uni...

(QB_NEW_EN)

---

[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - **Canonical URIs only**:   - Primary: `unity://path/Assets/...` (neve...

(QB_NEW_EN)

---

[grammar] ~23-~23: There might be a mistake here.
Context: ... (never embed `project_root` in the URI)   - Relative (when supported): `Assets/...` ...

(QB_NEW_EN)

---

[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI)   - Relative (when supported): `Assets/...` - File paths for the helper script are wor...

(QB_NEW_EN)

---

[grammar] ~30-~30: There might be a mistake here.
Context: ...it-nl-suite.md` (synthesized from JUnit) - Helper script: `scripts/nlt-revert.sh` (...

(QB_NEW_EN)

---

[grammar] ~35-~35: There might be a mistake here.
Context: ...(snapshot/restore)  ---  ## Tool Mapping - **Anchors/regex/structured**: `mcp__unity_...

(QB_NEW_EN)

---

[grammar] ~36-~36: There might be a mistake here.
Context: ...Mapping - **Anchors/regex/structured**: `mcp__unity__script_apply_edits` - **Precise ranges / atomic batch**: `mcp__u...

(QB_NEW_EN)

---

[grammar] ~37-~37: There might be a mistake here.
Context: ...ply_text_edits` (non‑overlapping ranges) - **Validation**: `mcp__unity__validate_scri...

(QB_NEW_EN)

---

[grammar] ~38-~38: There might be a mistake here.
Context: ...n‑overlapping ranges) - **Validation**: `mcp__unity__validate_script(level:"standard")` - **Reporting**: `Write` small XML fragments...

(QB_NEW_EN)

---

[grammar] ~39-~39: There might be a mistake here.
Context: ...rting**: `Write` small XML fragments to `reports/*_results.xml` - **Snapshot/Restore**: `Bash(scripts/nlt-re...

(QB_NEW_EN)

---

[grammar] ~48-~48: There might be a mistake here.
Context: ...tem-out><![CDATA[ ... ]]></system-out>`. - Evidence windows only (±20–40 lines). If...

(QB_NEW_EN)

---

[grammar] ~86-~86: Ensure spelling is correct
Context: ...a.expected_sha256`).   - If absent, one re‑read then a final retry. No loops. - After s...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

---

[grammar] ~87-~87: There might be a mistake here.
Context: ...fore any further edits in the same test. - Prefer anchors (`script_apply_edits`) fo...

(QB_NEW_EN)

---

[grammar] ~92-~92: There might be a mistake here.
Context: ...T-E, T-F, T-G, T-H, T-I, T-J (15 total). - NL‑0 must include the PLAN line (len=15)...

(QB_NEW_EN)

---

[grammar] ~99-~99: There might be a mistake here.
Context: ...verify; delete `PrintSeries()`; restore. - NL‑2. Anchor comment — Insert `// Build ...

(QB_NEW_EN)

---

[grammar] ~100-~100: There might be a mistake here.
Context: ...bove `public void Update(...)`; restore. - NL‑3. End‑of‑class — Insert `// Tail tes...

(QB_NEW_EN)

---

[grammar] ~101-~101: There might be a mistake here.
Context: ...— Insert `// Tail test A/B/C` (3 lines) before final brace; restore. - NL‑4. Compile t...

(QB_NEW_EN)

---

[grammar] ~101-~101: There might be a mistake here.
Context: ...` (3 lines) before final brace; restore. - NL‑4. Compile trigger — Record INFO only...

(QB_NEW_EN)

---

[grammar] ~104-~104: There might be a mistake here.
Context: ...fy; delete via `regex_replace`; restore. - T‑B. Replace body — Single `replace_rang...

(QB_NEW_EN)

---

[grammar] ~105-~105: There might be a mistake here.
Context: ...lace_range` inside `HasTarget`; restore. - T‑C. Header/region preservation — Edit i...

(QB_NEW_EN)

---

[grammar] ~106-~106: There might be a mistake here.
Context: ...reserve signature/docs/regions; restore. - T‑D. End‑of‑class (anchor) — Insert help...

(QB_NEW_EN)

---

[grammar] ~107-~107: There might be a mistake here.
Context: ...per before final brace; remove; restore. - T‑E. Lifecycle — Insert → update → delet...

(QB_NEW_EN)

---

[grammar] ~108-~108: There might be a mistake here.
Context: ...rt → update → delete via regex; restore. - T‑F. Atomic batch — One call: two small ...

(QB_NEW_EN)

---

[grammar] ~109-~109: There might be a mistake here.
Context: ...‑class comment; all‑or‑nothing; restore. - T‑G. Path normalization — Same edit with...

(QB_NEW_EN)

---

[grammar] ~110-~110: There might be a mistake here.
Context: ...dit with `unity://path/Assets/...` then `Assets/...`; second returns `{status:"no_change"}`. ...

(QB_NEW_EN)

---

[grammar] ~110-~110: There might be a mistake here.
Context: ...; second returns `{status:"no_change"}`. - T‑H. Validation — `standard` after edits...

(QB_NEW_EN)

---

[grammar] ~111-~111: There might be a mistake here.
Context: ...dits; `basic` only for transient checks. - T‑I. Failure surfaces — Record INFO on `...

(QB_NEW_EN)

---

[grammar] ~117-~117: There might be a mistake here.
Context: ...uses are non‑fatal; record and continue. - End each testcase `<system-out>` with `V...

(QB_NEW_EN)

</details>

</details>
<details>
<summary>🪛 markdownlint-cli2 (0.17.2)</summary>

<details>
<summary>.claude/prompts/nl-unity-suite-full.md</summary>

52-52: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)</summary>

* GitHub Check: Cursor Bugbot

</details>

<details>
<summary>🔇 Additional comments (1)</summary><blockquote>

<details>
<summary>.claude/prompts/nl-unity-suite-full.md (1)</summary><blockquote>

`46-51`: **Output rules are crisp and consistent (fragments-only, no `$JUNIT_OUT/$MD_OUT` writes).**

</blockquote></details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

{
throw new System.IO.IOException($"Invalid framed length: {payloadLen}");
}
if (payloadLen > int.MaxValue)
Copy link

Choose a reason for hiding this comment

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

Bug: Asymmetric Frame Handling Blocks Empty Messages

The framed I/O implementation is asymmetric: WriteFrameAsync allows zero-length payloads, but ReadFrameAsUtf8Async rejects them as invalid. This prevents clients from sending legitimate empty messages (e.g., pings or acknowledgments) and means the bridge can send frames it cannot receive.

Fix in Cursor Fix in Web

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
.github/workflows/claude-nl-suite.yml (4)

141-169: Replace fragile Python one‑liner for port detection with robust snippet.

-              PORT=$(python -c "import os,glob,json,sys,time; b=os.path.expanduser('~/.unity-mcp'); fs=sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True); print(next((json.load(open(f,'r',encoding='utf-8')).get('unity_port') for f in fs if time.time()-os.path.getmtime(f)<=300 and json.load(open(f,'r',encoding='utf-8')).get('unity_port')), '' ))" 2>/dev/null || true)
+              PORT="$(python3 - <<'PY' 2>/dev/null
+import os, glob, json, time, sys
+b = os.path.expanduser('~/.unity-mcp')
+fs = sorted(glob.glob(os.path.join(b, 'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True)
+for f in fs:
+    try:
+        if time.time() - os.path.getmtime(f) > 300:  # stale
+            continue
+        with open(f, 'r', encoding='utf-8') as fh:
+            p = (json.load(fh) or {}).get('unity_port')
+            if p:
+                print(p); sys.exit(0)
+    except Exception:
+        pass
+print("")
+PY
+)"

285-317: Normalizer should also import preferred single‑file and roots.

-            fragments = sorted(Path('reports').glob('*_results.xml'))
+            fragments = sorted(Path('reports').glob('*_results.xml'))
+            preferred = Path('reports/nl_final_results.xml')
+            if preferred.exists():
+                try:
+                    proot = ET.parse(preferred).getroot()
+                    if localname(proot.tag) == 'cases':
+                        for tc in proot.findall('./testcase'):
+                            suite.append(tc); added += 1
+                    else:
+                        for tc in proot.findall('.//testcase'):
+                            suite.append(tc); added += 1
+                except Exception as pe:
+                    print(f"Parse error for preferred file {preferred}: {pe}")

48-54: Pin third‑party Actions by immutable commit SHAs (supply‑chain hardening).

Apply:

-        - uses: actions/checkout@v4
+        - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955  # v4

-        - uses: astral-sh/setup-uv@v4
+        - uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a  # v4

Do the same for:

  • game-ci/unity-test-runner@v4 → 0ff419b913a3630032cbe0de48a0099b5a9f0ed9
  • anthropics/claude-code-base-action@beta → e9863f822497ff36abdac4571937150d27397a34
  • mikepenz/action-junit-report@v5 → replace with its exact commit SHA
  • actions/upload-artifact@v4 → ea165f8d65b6e75b540449e92b4886f43607fa02

16-18: Pin Unity Docker image by digest to prevent tag drift.

 env:
   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>
   UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home

Resolve via:
docker buildx imagetools inspect unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3 | rg -n 'Digest:' | head -1

🧹 Nitpick comments (3)
.github/workflows/claude-nl-suite.yml (3)

401-417: Use MD_OUT env when adding job summary (avoid hardcoded path).

-            p = Path('reports/junit-nl-suite.md')
+            import os
+            p = Path(os.environ.get('MD_OUT', 'reports/junit-nl-suite.md'))

279-283: Avoid mutable model alias in CI for reproducibility.

Consider pinning model: claude-3-7-sonnet-<dated-id> instead of -latest. Please confirm the exact stable model identifier you want here.


434-455: Artifacts/JUnit publishing look correct; just ensure actions are pinned.

Once SHAs are pinned, run actionlint/yamllint locally to confirm no remaining warnings. I can provide a pre-commit config if helpful.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5dad550 and df97ab2.

📒 Files selected for processing (1)
  • .github/workflows/claude-nl-suite.yml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/claude-nl-suite.yml

4-4: could not parse as YAML: yaml: line 4: mapping values are not allowed in this context

(syntax-check)

🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml

[error] 3-3: trailing spaces

(trailing-spaces)


[error] 6-6: trailing spaces

(trailing-spaces)


[error] 10-10: trailing spaces

(trailing-spaces)


[error] 14-14: trailing spaces

(trailing-spaces)


[error] 19-19: trailing spaces

(trailing-spaces)


[error] 28-28: trailing spaces

(trailing-spaces)


[error] 47-47: trailing spaces

(trailing-spaces)


[error] 51-51: trailing spaces

(trailing-spaces)


[error] 56-56: trailing spaces

(trailing-spaces)


[error] 74-74: trailing spaces

(trailing-spaces)


[error] 89-89: trailing spaces

(trailing-spaces)


[error] 96-96: trailing spaces

(trailing-spaces)


[error] 103-103: trailing spaces

(trailing-spaces)


[error] 140-140: trailing spaces

(trailing-spaces)


[error] 180-180: trailing spaces

(trailing-spaces)


[error] 202-202: trailing spaces

(trailing-spaces)


[error] 209-209: trailing spaces

(trailing-spaces)


[error] 222-222: trailing spaces

(trailing-spaces)


[error] 258-258: trailing spaces

(trailing-spaces)


[error] 283-283: trailing spaces

(trailing-spaces)


[error] 318-318: trailing spaces

(trailing-spaces)


[error] 363-363: trailing spaces

(trailing-spaces)


[error] 375-375: trailing spaces

(trailing-spaces)


[error] 387-387: trailing spaces

(trailing-spaces)


[error] 400-400: trailing spaces

(trailing-spaces)


[error] 417-417: trailing spaces

(trailing-spaces)


[error] 433-433: trailing spaces

(trailing-spaces)


[error] 444-444: trailing spaces

(trailing-spaces)


[error] 456-456: trailing spaces

(trailing-spaces)


[error] 463-463: no new line character at the end of file

(new-line-at-end-of-file)


[error] 463-463: trailing spaces

(trailing-spaces)


[error] 4-4: syntax error: mapping values are not allowed here

(syntax)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (1)
.github/workflows/claude-nl-suite.yml (1)

261-263: Good: gate NL run on both Anthropic and Unity.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
.claude/prompts/nl-unity-suite-full.md (1)

86-92: Replace pseudo APIs with read_resource and drop mandatory post-write re-read.

Current guidance uses nonexistent read_text/read_bytes and forces an immediate re-read after every write, contradicting prior resolved comments and adding needless I/O.

-### Guarded Write Pattern (for edits, not restores)
-
-- Before any mutation: `buf = read_text(uri)`; `pre_sha = sha256(read_bytes(uri))`.
-- Write with `precondition_sha256 = pre_sha`.
-- On `{status:"stale_file"}`:
-  - Retry once using the server hash (`data.current_sha256` or `data.expected_sha256`).
-  - If absent, one re‑read then a final retry. No loops.
-- After success: immediately re‑read raw bytes and set `pre_sha = sha256(read_bytes(uri))` before any further edits in the same test.
- - Prefer anchors (`script_apply_edits`) for end‑of‑class / above‑method insertions. Keep edits inside method bodies. Avoid header/using.
+### Guarded Write Pattern (for edits, not restores)
+
+- Before any mutation: `res = mcp__unity__read_resource(uri, project_root)`; set `buf = res.text`; set `pre_sha = res.sha256` (server‑computed over raw on‑disk bytes).
+- Write with `precondition_sha256 = pre_sha`.
+- On `{status:"stale_file"}`: retry once using a server hash (`data.current_sha256` or `data.expected_sha256`) if present; otherwise perform one `read_resource(...)` to refresh `pre_sha` and retry. No loops.
+- After success: prefer not to re‑read. Update `buf` locally; refresh `pre_sha = read_resource(...).sha256` only if the next step requires exact on‑disk sync (validation, anchor recompute) or before leaving the test.
+- Prefer anchors (`script_apply_edits`) for end‑of‑class / above‑method insertions. Keep edits inside method bodies. Avoid header/using.
🧹 Nitpick comments (2)
.claude/prompts/nl-unity-suite-full.md (2)

5-5: Use a proper heading instead of emphasis (markdownlint MD036).

Switch the emphasized line to a heading for consistency and to satisfy linters.

-**Print this once, verbatim, early in the run:**
+### Print this once, verbatim, early in the run

71-82: Ensure snapshot directory exists or document helper behavior.

If reports/_snapshots isn’t pre-created, snapshot/restore can fail. Either guarantee the helper creates parent dirs or note it here.

 - Snapshot once at NL‑0, then restore after each test via the helper.
+ - Snapshot once at NL‑0, then restore after each test via the helper.
+ - The helper creates parent directories for the snapshot path (`reports/_snapshots`) if missing.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between df97ab2 and 6a86db3.

📒 Files selected for processing (1)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~5-~5: There might be a mistake here.
Context: ...this once, verbatim, early in the run:** AllowedTools: Write,Bash(printf:*),Bash(...

(QB_NEW_EN)


[grammar] ~20-~20: There might be a mistake here.
Context: ...write. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...nd ctx: {} on list/read/edit/validate. - Canonical URIs only: - Primary: `uni...

(QB_NEW_EN)


[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - Canonical URIs only: - Primary: unity://path/Assets/... (neve...

(QB_NEW_EN)


[grammar] ~23-~23: There might be a mistake here.
Context: ... (never embed project_root in the URI) - Relative (when supported): Assets/... ...

(QB_NEW_EN)


[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI) - Relative (when supported): Assets/... - File paths for the helper script are wor...

(QB_NEW_EN)


[grammar] ~30-~30: There might be a mistake here.
Context: ...it-nl-suite.md(synthesized from JUnit) - Helper script:scripts/nlt-revert.sh` (...

(QB_NEW_EN)


[grammar] ~35-~35: There might be a mistake here.
Context: ...(snapshot/restore) --- ## Tool Mapping - Anchors/regex/structured: `mcp__unity_...

(QB_NEW_EN)


[grammar] ~36-~36: There might be a mistake here.
Context: ...Mapping - Anchors/regex/structured: mcp__unity__script_apply_edits - Precise ranges / atomic batch: `mcp__u...

(QB_NEW_EN)


[grammar] ~37-~37: There might be a mistake here.
Context: ...ply_text_edits(non‑overlapping ranges) - **Validation**:mcp__unity__validate_scri...

(QB_NEW_EN)


[grammar] ~38-~38: There might be a mistake here.
Context: ...n‑overlapping ranges) - Validation: mcp__unity__validate_script(level:"standard") - Reporting: Write small XML fragments...

(QB_NEW_EN)


[grammar] ~39-~39: There might be a mistake here.
Context: ...rting**: Write small XML fragments to reports/*_results.xml - Snapshot/Restore: `Bash(scripts/nlt-re...

(QB_NEW_EN)


[grammar] ~48-~48: There might be a mistake here.
Context: ...tem-out>`. - Evidence windows only (±20–40 lines). If...

(QB_NEW_EN)


[grammar] ~90-~90: Ensure spelling is correct
Context: ...a.expected_sha256`). - If absent, one re‑read then a final retry. No loops. - After s...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~91-~91: There might be a mistake here.
Context: ...fore any further edits in the same test. - Prefer anchors (script_apply_edits) fo...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...T-E, T-F, T-G, T-H, T-I, T-J (15 total). - NL‑0 must include the PLAN line (len=15)...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...verify; delete PrintSeries(); restore. - NL‑2. Anchor comment — Insert `// Build ...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ...bove public void Update(...); restore. - NL‑3. End‑of‑class — Insert `// Tail tes...

(QB_NEW_EN)


[grammar] ~105-~105: There might be a mistake here.
Context: ...— Insert // Tail test A/B/C (3 lines) before final brace; restore. - NL‑4. Compile t...

(QB_NEW_EN)


[grammar] ~105-~105: There might be a mistake here.
Context: ...` (3 lines) before final brace; restore. - NL‑4. Compile trigger — Record INFO only...

(QB_NEW_EN)


[grammar] ~108-~108: There might be a mistake here.
Context: ...fy; delete via regex_replace; restore. - T‑B. Replace body — Single `replace_rang...

(QB_NEW_EN)


[grammar] ~109-~109: There might be a mistake here.
Context: ...lace_rangeinsideHasTarget`; restore. - T‑C. Header/region preservation — Edit i...

(QB_NEW_EN)


[grammar] ~110-~110: There might be a mistake here.
Context: ...reserve signature/docs/regions; restore. - T‑D. End‑of‑class (anchor) — Insert help...

(QB_NEW_EN)


[grammar] ~111-~111: There might be a mistake here.
Context: ...per before final brace; remove; restore. - T‑E. Lifecycle — Insert → update → delet...

(QB_NEW_EN)


[grammar] ~112-~112: There might be a mistake here.
Context: ...rt → update → delete via regex; restore. - T‑F. Atomic batch — One call: two small ...

(QB_NEW_EN)


[grammar] ~113-~113: There might be a mistake here.
Context: ...‑class comment; all‑or‑nothing; restore. - T‑G. Path normalization — Same edit with...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ...dit with unity://path/Assets/... then Assets/...; second returns {status:"no_change"}. ...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ...; second returns {status:"no_change"}. - T‑H. Validation — standard after edits...

(QB_NEW_EN)


[grammar] ~115-~115: There might be a mistake here.
Context: ...dits; basic only for transient checks. - T‑I. Failure surfaces — Record INFO on `...

(QB_NEW_EN)


[grammar] ~121-~121: There might be a mistake here.
Context: ...uses are non‑fatal; record and continue. - End each testcase <system-out> with `V...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.claude/prompts/nl-unity-suite-full.md

52-52: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cursor Bugbot
🔇 Additional comments (4)
.claude/prompts/nl-unity-suite-full.md (4)

35-38: Tool mapping reads accurately reflect atomic multi-edit support.

Good correction on apply_text_edits (non-overlapping atomic batches) and division of responsibilities with script_apply_edits.


52-66: Suite name consistency looks correct.

Example uses classname="UnityMCP.NL-T" and the PLAN/PROGRESS totals are 15; both match the current workflows/docs.


96-99: Execution order and totals are coherent (15 tests, NL‑0 includes PLAN).

No changes needed.


6-6: AllowedTools list is correct; mcp__unity__read_console is permitted in both workflows.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
.github/workflows/claude-nl-suite.yml (3)

283-333: Support preferred single-file results (nl_final_results.xml) and <cases> root in normalizer.

Matches the prompt’s “preferred single-file” output path and improves robustness.

-            fragments = sorted(Path('reports').glob('*_results.xml'))
+            fragments = sorted(Path('reports').glob('*_results.xml'))
+            # Also import preferred single-file results if present
+            preferred = Path('reports/nl_final_results.xml')
+            if preferred.exists():
+                fragments.insert(0, preferred)
@@
-                    if localname(froot.tag) == 'testcase':
+                    if localname(froot.tag) == 'testcase':
                         suite.append(froot); added += 1
-                    else:
+                    elif localname(froot.tag) == 'cases':
+                        for tc in froot.findall('./testcase'):
+                            suite.append(tc); added += 1
+                    else:
                         for tc in froot.findall('.//testcase'):
                             suite.append(tc); added += 1

47-50: Pin all third‑party Actions by commit SHA (supply‑chain hardening).

Mutable tags can drift. Replace with immutable SHAs.

-        - uses: actions/checkout@v4
+        - uses: actions/checkout@<COMMIT_SHA>
...
-        - uses: astral-sh/setup-uv@v4
+        - uses: astral-sh/setup-uv@<COMMIT_SHA>
...
-          uses: game-ci/unity-test-runner@v4
+          uses: game-ci/unity-test-runner@<COMMIT_SHA>
...
-        - name: Run Claude NL suite (single pass)
-          uses: anthropics/claude-code-base-action@beta
+        - name: Run Claude NL suite (single pass)
+          uses: anthropics/claude-code-base-action@<COMMIT_SHA>
...
-          uses: mikepenz/action-junit-report@v5
+          uses: mikepenz/action-junit-report@<COMMIT_SHA>
...
-          uses: actions/upload-artifact@v4
+          uses: actions/upload-artifact@<COMMIT_SHA>

Note: apply the same SHA to each occurrence of the same Action.

Also applies to: 52-55, 75-88, 258-282, 478-488, 489-499


14-17: Pin Unity Docker image by digest to prevent tag drift.

Locks the editor layer for reproducible runs.

 env:
   UNITY_VERSION: 2021.3.45f1
-  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
+  # Pin to immutable digest (replace <DIGEST>)
+  UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3@sha256:<DIGEST>
   UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home
🧹 Nitpick comments (5)
.claude/prompts/nl-unity-suite-full.md (3)

5-6: Fix heading level (MD001) in “Print this once…”

Use H2 after H1 to avoid heading jumps.

-### Print this once, verbatim, early in the run
+## Print this once, verbatim, early in the run

60-72: Use a heading instead of emphasized text for the example block (MD036).

Minor readability/markdownlint improvement.

-**Example fragment**
+### Example fragment

<testcase ...>
...


48-50: Avoid brittle “scan braces” fallback; leverage find_in_file for ranges.

Computing ranges by manual brace scans is error‑prone with nested types/regions. Prefer mcp__unity__find_in_file to derive exact start/end offsets for the helper method before calling apply_text_edits.

-  2) If that returns `missing_field` or `bad_request`, fallback to `apply_text_edits` with a single `replace_range` computed from the method’s start/end offsets (found by scanning braces).
+  2) If that returns `missing_field` or `bad_request`, use `mcp__unity__find_in_file` to locate the method’s exact span and then `apply_text_edits` with a single `replace_range` for that span.
.github/workflows/claude-nl-suite.yml (2)

148-149: Harden log redaction: include api keys and similar tokens.

Extend the regex to catch common API key patterns.

-            docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$!
+            docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token|api[-_]?key)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$!
@@
-              docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
+              docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token|api[-_]?key)[^[:space:]]*)/[REDACTED]/ig' || true
@@
-            docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
+            docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token|api[-_]?key)[^[:space:]]*)/[REDACTED]/ig' || true

Also applies to: 176-176, 505-506


26-26: Fix spacing after colon (YAMLlint MD_OUT).

Removes extra spaces flagged by linters.

-        MD_OUT:    reports/junit-nl-suite.md
+        MD_OUT: reports/junit-nl-suite.md
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6a86db3 and f0b3bba.

📒 Files selected for processing (2)
  • .claude/prompts/nl-unity-suite-full.md (1 hunks)
  • .github/workflows/claude-nl-suite.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/claude-nl-suite.yml

[error] 5-5: trailing spaces

(trailing-spaces)


[error] 9-9: trailing spaces

(trailing-spaces)


[error] 13-13: trailing spaces

(trailing-spaces)


[error] 18-18: trailing spaces

(trailing-spaces)


[warning] 21-21: wrong indentation: expected 8 but found 6

(indentation)


[warning] 25-25: wrong indentation: expected 10 but found 8

(indentation)


[warning] 26-26: too many spaces after colon

(colons)


[error] 27-27: trailing spaces

(trailing-spaces)


[warning] 30-30: wrong indentation: expected 10 but found 8

(indentation)


[warning] 33-33: wrong indentation: expected 14 but found 12

(indentation)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[error] 46-46: trailing spaces

(trailing-spaces)


[warning] 49-49: wrong indentation: expected 14 but found 12

(indentation)


[error] 50-50: trailing spaces

(trailing-spaces)


[warning] 54-54: wrong indentation: expected 14 but found 12

(indentation)


[error] 55-55: trailing spaces

(trailing-spaces)


[error] 73-73: trailing spaces

(trailing-spaces)


[warning] 79-79: wrong indentation: expected 14 but found 12

(indentation)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 84-84: wrong indentation: expected 14 but found 12

(indentation)


[error] 88-88: trailing spaces

(trailing-spaces)


[error] 95-95: trailing spaces

(trailing-spaces)


[error] 102-102: trailing spaces

(trailing-spaces)


[warning] 107-107: wrong indentation: expected 14 but found 12

(indentation)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 139-139: trailing spaces

(trailing-spaces)


[error] 179-179: trailing spaces

(trailing-spaces)


[error] 201-201: trailing spaces

(trailing-spaces)


[error] 208-208: trailing spaces

(trailing-spaces)


[error] 221-221: trailing spaces

(trailing-spaces)


[error] 257-257: trailing spaces

(trailing-spaces)


[warning] 264-264: wrong indentation: expected 14 but found 12

(indentation)


[error] 282-282: trailing spaces

(trailing-spaces)


[error] 333-333: trailing spaces

(trailing-spaces)


[error] 407-407: trailing spaces

(trailing-spaces)


[error] 419-419: trailing spaces

(trailing-spaces)


[error] 431-431: trailing spaces

(trailing-spaces)


[error] 444-444: trailing spaces

(trailing-spaces)


[error] 461-461: trailing spaces

(trailing-spaces)


[error] 477-477: trailing spaces

(trailing-spaces)


[warning] 482-482: wrong indentation: expected 14 but found 12

(indentation)


[error] 488-488: trailing spaces

(trailing-spaces)


[warning] 493-493: wrong indentation: expected 14 but found 12

(indentation)


[error] 500-500: trailing spaces

(trailing-spaces)


[error] 507-507: no new line character at the end of file

(new-line-at-end-of-file)


[error] 507-507: trailing spaces

(trailing-spaces)

🪛 LanguageTool
.claude/prompts/nl-unity-suite-full.md

[grammar] ~10-~10: There might be a mistake here.
Context: ...cp__unity__read_console --- ## Mission 1) Pick target file (prefer): - `unity:/...

(QB_NEW_EN)


[grammar] ~20-~20: There might be a mistake here.
Context: ...write. --- ## Environment & Paths (CI) - Always pass: `project_root: "TestProject...

(QB_NEW_EN)


[grammar] ~21-~21: There might be a mistake here.
Context: ...nd ctx: {} on list/read/edit/validate. - Canonical URIs only: - Primary: `uni...

(QB_NEW_EN)


[grammar] ~22-~22: There might be a mistake here.
Context: ...dit/validate. - Canonical URIs only: - Primary: unity://path/Assets/... (neve...

(QB_NEW_EN)


[grammar] ~23-~23: There might be a mistake here.
Context: ... (never embed project_root in the URI) - Relative (when supported): Assets/... ...

(QB_NEW_EN)


[grammar] ~24-~24: There might be a mistake here.
Context: ...the URI) - Relative (when supported): Assets/... - File paths for the helper script are wor...

(QB_NEW_EN)


[grammar] ~30-~30: There might be a mistake here.
Context: ...it-nl-suite.md(synthesized from JUnit) - Helper script:scripts/nlt-revert.sh` (...

(QB_NEW_EN)


[grammar] ~35-~35: There might be a mistake here.
Context: ...(snapshot/restore) --- ## Tool Mapping - Anchors/regex/structured: `mcp__unity_...

(QB_NEW_EN)


[grammar] ~36-~36: There might be a mistake here.
Context: ...Mapping - Anchors/regex/structured: mcp__unity__script_apply_edits - Precise ranges / atomic batch: `mcp__u...

(QB_NEW_EN)


[grammar] ~37-~37: There might be a mistake here.
Context: ...ply_text_edits(non‑overlapping ranges) - **Validation**:mcp__unity__validate_scri...

(QB_NEW_EN)


[grammar] ~38-~38: There might be a mistake here.
Context: ...n‑overlapping ranges) - Validation: mcp__unity__validate_script(level:"standard") - Reporting: Write small XML fragments...

(QB_NEW_EN)


[grammar] ~39-~39: There might be a mistake here.
Context: ...rting**: Write small XML fragments to reports/*_results.xml - Snapshot/Restore: `Bash(scripts/nlt-re...

(QB_NEW_EN)


[grammar] ~49-~49: There might be a mistake here.
Context: .../end offsets (found by scanning braces). - If any write returns missing_field, `b...

(QB_NEW_EN)


[grammar] ~50-~50: There might be a mistake here.
Context: ...restore* and proceed to the next test. - Never call generic Bash like mkdir; th...

(QB_NEW_EN)


[grammar] ~56-~56: There might be a mistake here.
Context: ...tem-out>`. - Evidence windows only (±20–40 lines). If...

(QB_NEW_EN)


[grammar] ~95-~95: There might be a mistake here.
Context: ...s, not restores) - Before any mutation: - Call `mcp__unity__read_resource(uri, pro...

(QB_NEW_EN)


[grammar] ~96-~96: There might be a mistake here.
Context: ...server‑computed over raw on‑disk bytes). - Write with `precondition_sha256 = pre_sh...

(QB_NEW_EN)


[grammar] ~101-~101: There might be a mistake here.
Context: ...aand retry. No loops. - After success: - Prefer not to re‑read. Updatebuf` loca...

(QB_NEW_EN)


[grammar] ~102-~102: Ensure spelling is correct
Context: ...ops. - After success: - Prefer not to re‑read. Update buf locally; refresh `pre_sha...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~102-~102: There might be a mistake here.
Context: ...r recompute) or before leaving the test. - Prefer anchors (script_apply_edits) fo...

(QB_NEW_EN)


[grammar] ~107-~107: There might be a mistake here.
Context: ...T-E, T-F, T-G, T-H, T-I, T-J (15 total). - NL‑0 must include the PLAN line (len=15)...

(QB_NEW_EN)


[grammar] ~114-~114: There might be a mistake here.
Context: ...verify; delete PrintSeries(); restore. - NL‑2. Anchor comment — Insert `// Build ...

(QB_NEW_EN)


[grammar] ~115-~115: There might be a mistake here.
Context: ...bove public void Update(...); restore. - NL‑3. End‑of‑class — Insert `// Tail tes...

(QB_NEW_EN)


[grammar] ~116-~116: There might be a mistake here.
Context: ...— Insert // Tail test A/B/C (3 lines) before final brace; restore. - NL‑4. Compile t...

(QB_NEW_EN)


[grammar] ~116-~116: There might be a mistake here.
Context: ...` (3 lines) before final brace; restore. - NL‑4. Compile trigger — Record INFO only...

(QB_NEW_EN)


[grammar] ~119-~119: There might be a mistake here.
Context: ...fy; delete via regex_replace; restore. - T‑B. Replace body — Single `replace_rang...

(QB_NEW_EN)


[grammar] ~120-~120: There might be a mistake here.
Context: ...lace_rangeinsideHasTarget`; restore. - T‑C. Header/region preservation — Edit i...

(QB_NEW_EN)


[grammar] ~121-~121: There might be a mistake here.
Context: ...reserve signature/docs/regions; restore. - T‑D. End‑of‑class (anchor) — Insert help...

(QB_NEW_EN)


[grammar] ~122-~122: There might be a mistake here.
Context: ...per before final brace; remove; restore. - T‑E. Lifecycle — Insert → update → delet...

(QB_NEW_EN)


[grammar] ~123-~123: There might be a mistake here.
Context: ...rt → update → delete via regex; restore. - T‑F. Atomic batch — One call: two small ...

(QB_NEW_EN)


[grammar] ~124-~124: There might be a mistake here.
Context: ...‑class comment; all‑or‑nothing; restore. - T‑G. Path normalization — Same edit with...

(QB_NEW_EN)


[grammar] ~125-~125: There might be a mistake here.
Context: ...dit with unity://path/Assets/... then Assets/...; second returns {status:"no_change"}. ...

(QB_NEW_EN)


[grammar] ~125-~125: There might be a mistake here.
Context: ...; second returns {status:"no_change"}. - T‑H. Validation — standard after edits...

(QB_NEW_EN)


[grammar] ~126-~126: There might be a mistake here.
Context: ...dits; basic only for transient checks. - T‑I. Failure surfaces — Record INFO on `...

(QB_NEW_EN)


[grammar] ~132-~132: There might be a mistake here.
Context: ...uses are non‑fatal; record and continue. - End each testcase <system-out> with `V...

(QB_NEW_EN)

🪛 markdownlint-cli2 (0.17.2)
.claude/prompts/nl-unity-suite-full.md

5-5: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


60-60: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: nl-suite
  • GitHub Check: Cursor Bugbot

Comment on lines +1 to +507
name: Claude NL/T Full Suite (Unity live)

on:
workflow_dispatch: {}

workflow_dispatch: {}
permissions:
contents: write # allow Claude to write test artifacts
pull-requests: write # allow annotations / comments
issues: write

contents: read
checks: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
UNITY_VERSION: 2021.3.45f1
UNITY_IMAGE: unityci/editor:ubuntu-2021.3.45f1-linux-il2cpp-3
UNITY_CACHE_ROOT: /home/runner/work/_temp/_github_home

jobs:
nl-suite:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 60

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

# Python + uv for the Unity MCP server
- name: Install Python + uv
uses: astral-sh/setup-uv@v4
with:
python-version: '3.11'

- name: Install UnityMcpServer deps
run: |
set -eux
if [ -f "UnityMcpBridge/UnityMcpServer~/src/pyproject.toml" ]; then
uv venv
. .venv/bin/activate
uv pip install -e "UnityMcpBridge/UnityMcpServer~/src"
elif [ -f "UnityMcpBridge/UnityMcpServer~/src/requirements.txt" ]; then
nl-suite:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
timeout-minutes: 60
env:
JUNIT_OUT: reports/junit-nl-suite.xml
MD_OUT: reports/junit-nl-suite.md

steps:
# ---------- Secrets check ----------
- name: Detect secrets (outputs)
id: detect
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
set -e
if [ -n "$ANTHROPIC_API_KEY" ]; then echo "anthropic_ok=true" >> "$GITHUB_OUTPUT"; else echo "anthropic_ok=false" >> "$GITHUB_OUTPUT"; fi
if [ -n "$UNITY_LICENSE" ] || { [ -n "$UNITY_EMAIL" ] && [ -n "$UNITY_PASSWORD" ]; } || [ -n "$UNITY_SERIAL" ]; then
echo "unity_ok=true" >> "$GITHUB_OUTPUT"
else
echo "unity_ok=false" >> "$GITHUB_OUTPUT"
fi
- uses: actions/checkout@v4
with:
fetch-depth: 0

# ---------- Python env for MCP server (uv) ----------
- uses: astral-sh/setup-uv@v4
with:
python-version: '3.11'

- name: Install MCP server
run: |
set -eux
uv venv
. .venv/bin/activate
uv pip install -r "UnityMcpBridge/UnityMcpServer~/src/requirements.txt"
else
echo "No Python deps found (skipping)"
fi
- name: Run Claude NL/T test suite
id: claude
uses: anthropics/claude-code-base-action@beta
with:
# Test instructions live here
prompt_file: .claude/prompts/nl-unity-suite.md

# Tight tool allowlist
allowed_tools: "Bash(git:*),View,GlobTool,GrepTool,BatchTool,mcp__unity__*"

# MCP server path (matches your screenshots)
mcp_config: |
echo "VIRTUAL_ENV=$GITHUB_WORKSPACE/.venv" >> "$GITHUB_ENV"
echo "$GITHUB_WORKSPACE/.venv/bin" >> "$GITHUB_PATH"
if [ -f UnityMcpBridge/UnityMcpServer~/src/pyproject.toml ]; then
uv pip install -e UnityMcpBridge/UnityMcpServer~/src
elif [ -f UnityMcpBridge/UnityMcpServer~/src/requirements.txt ]; then
uv pip install -r UnityMcpBridge/UnityMcpServer~/src/requirements.txt
elif [ -f UnityMcpBridge/UnityMcpServer~/pyproject.toml ]; then
uv pip install -e UnityMcpBridge/UnityMcpServer~/
elif [ -f UnityMcpBridge/UnityMcpServer~/requirements.txt ]; then
uv pip install -r UnityMcpBridge/UnityMcpServer~/requirements.txt
else
echo "No MCP Python deps found (skipping)"
fi
# ---------- License prime on host (GameCI) ----------
- name: Prime Unity license on host (GameCI)
if: steps.detect.outputs.unity_ok == 'true'
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
with:
projectPath: TestProjects/UnityMCPTests
testMode: EditMode
customParameters: -runTests -testFilter __NoSuchTest__ -batchmode -nographics
unityVersion: ${{ env.UNITY_VERSION }}

# (Optional) Inspect license caches
- name: Inspect GameCI license caches (host)
if: steps.detect.outputs.unity_ok == 'true'
run: |
set -eux
find "${{ env.UNITY_CACHE_ROOT }}" -maxdepth 4 \( -path "*/.cache" -prune -o -type f \( -name '*.ulf' -o -name 'user.json' \) -print \) 2>/dev/null || true
# ---------- Clean old MCP status ----------
- name: Clean old MCP status
run: |
set -eux
mkdir -p "$HOME/.unity-mcp"
rm -f "$HOME/.unity-mcp"/unity-mcp-status-*.json || true
# ---------- Start headless Unity (persistent bridge) ----------
- name: Start Unity (persistent bridge)
if: steps.detect.outputs.unity_ok == 'true'
env:
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
UNITY_SERIAL: ${{ secrets.UNITY_SERIAL }}
run: |
set -eu
if [ ! -d "${{ github.workspace }}/TestProjects/UnityMCPTests/ProjectSettings" ]; then
echo "Unity project not found; failing fast."
exit 1
fi
mkdir -p "$HOME/.unity-mcp"
MANUAL_ARG=()
if [ -f "${UNITY_CACHE_ROOT}/.local/share/unity3d/Unity_lic.ulf" ]; then
MANUAL_ARG=(-manualLicenseFile /root/.local/share/unity3d/Unity_lic.ulf)
fi
EBL_ARGS=()
[ -n "${UNITY_SERIAL:-}" ] && EBL_ARGS+=(-serial "$UNITY_SERIAL")
[ -n "${UNITY_EMAIL:-}" ] && EBL_ARGS+=(-username "$UNITY_EMAIL")
[ -n "${UNITY_PASSWORD:-}" ] && EBL_ARGS+=(-password "$UNITY_PASSWORD")
docker rm -f unity-mcp >/dev/null 2>&1 || true
docker run -d --name unity-mcp --network host \
-e HOME=/root \
-e UNITY_MCP_ALLOW_BATCH=1 -e UNITY_MCP_STATUS_DIR=/root/.unity-mcp \
-e UNITY_MCP_BIND_HOST=127.0.0.1 \
-v "${{ github.workspace }}:/workspace" -w /workspace \
-v "${{ env.UNITY_CACHE_ROOT }}:/root" \
-v "$HOME/.unity-mcp:/root/.unity-mcp" \
${{ env.UNITY_IMAGE }} /opt/unity/Editor/Unity -batchmode -nographics -logFile - \
-stackTraceLogType Full \
-projectPath /workspace/TestProjects/UnityMCPTests \
"${MANUAL_ARG[@]}" \
"${EBL_ARGS[@]}" \
-executeMethod MCPForUnity.Editor.MCPForUnityBridge.StartAutoConnect
# ---------- Wait for Unity bridge ----------
- name: Wait for Unity bridge (robust)
if: steps.detect.outputs.unity_ok == 'true'
run: |
set -euo pipefail
if ! docker ps --format '{{.Names}}' | grep -qx 'unity-mcp'; then
echo "Unity container failed to start"; docker ps -a || true; exit 1
fi
docker logs -f unity-mcp 2>&1 | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' & LOGPID=$!
deadline=$((SECONDS+420)); READY=0
try_connect_host() {
P="$1"
timeout 1 bash -lc "exec 3<>/dev/tcp/127.0.0.1/$P; head -c 8 <&3 >/dev/null" && return 0 || true
if command -v nc >/dev/null 2>&1; then nc -6 -z ::1 "$P" && return 0 || true; fi
return 1
}
while [ $SECONDS -lt $deadline ]; do
if docker logs unity-mcp 2>&1 | grep -qE "MCP Bridge listening|Bridge ready|Server started"; then
READY=1; echo "Bridge ready (log markers)"; break
fi
PORT=$(python -c "import os,glob,json,sys,time; b=os.path.expanduser('~/.unity-mcp'); fs=sorted(glob.glob(os.path.join(b,'unity-mcp-status-*.json')), key=os.path.getmtime, reverse=True); print(next((json.load(open(f,'r',encoding='utf-8')).get('unity_port') for f in fs if time.time()-os.path.getmtime(f)<=300 and json.load(open(f,'r',encoding='utf-8')).get('unity_port')), '' ))" 2>/dev/null || true)
if [ -n "${PORT:-}" ] && { try_connect_host "$PORT" || docker exec unity-mcp bash -lc "timeout 1 bash -lc 'exec 3<>/dev/tcp/127.0.0.1/$PORT' || (command -v nc >/dev/null 2>&1 && nc -6 -z ::1 $PORT)"; }; then
READY=1; echo "Bridge ready on port $PORT"; break
fi
if docker logs unity-mcp 2>&1 | grep -qE "No valid Unity Editor license|Token not found in cache|com\.unity\.editor\.headless"; then
echo "Licensing error detected"; break
fi
sleep 2
done
kill $LOGPID || true
if [ "$READY" != "1" ]; then
echo "Bridge not ready; diagnostics:"
echo "== status files =="; ls -la "$HOME/.unity-mcp" || true
echo "== status contents =="; for f in "$HOME"/.unity-mcp/unity-mcp-status-*.json; do [ -f "$f" ] && { echo "--- $f"; sed -n '1,120p' "$f"; }; done
echo "== sockets (inside container) =="; docker exec unity-mcp bash -lc 'ss -lntp || netstat -tulpen || true'
echo "== tail of Unity log =="
docker logs --tail 200 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
exit 1
fi
# ---------- MCP client config ----------
- name: Write MCP config (.claude/mcp.json)
run: |
set -eux
mkdir -p .claude
cat > .claude/mcp.json <<JSON
{
"mcpServers": {
"unity": {
"command": "python",
"args": ["UnityMcpBridge/UnityMcpServer~/src/server.py"]
"command": "uv",
"args": ["run","--active","--directory","UnityMcpBridge/UnityMcpServer~/src","python","server.py"],
"transport": { "type": "stdio" },
"env": {
"PYTHONUNBUFFERED": "1",
"MCP_LOG_LEVEL": "debug",
"UNITY_PROJECT_ROOT": "$GITHUB_WORKSPACE/TestProjects/UnityMCPTests"
}
}
}
}
# Guardrails
model: "claude-3-7-sonnet-20250219"
max_turns: "10"
timeout_minutes: "20"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

- name: Upload JUnit (Claude NL/T)
if: always()
uses: actions/upload-artifact@v4
with:
name: claude-nl-tests
path: reports/claude-nl-tests.xml
if-no-files-found: ignore

- name: Annotate PR with test results (Claude NL/T)
if: always()
uses: dorny/test-reporter@v1
with:
name: Claude NL/T
path: reports/claude-nl-tests.xml
reporter: java-junit
fail-on-empty: false

# Detect secrets + project/package mode WITHOUT using secrets in `if:`
- name: Detect Unity mode & secrets
id: detect
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
run: |
if [ -n "$UNITY_LICENSE" ]; then echo "has_license=true" >> "$GITHUB_OUTPUT"; else echo "has_license=false" >> "$GITHUB_OUTPUT"; fi
if [ -f "ProjectSettings/ProjectVersion.txt" ]; then echo "is_project=true" >> "$GITHUB_OUTPUT"; else echo "is_project=false" >> "$GITHUB_OUTPUT"; fi
if [ -f "Packages/manifest.json" ] && [ ! -f "ProjectSettings/ProjectVersion.txt" ]; then echo "is_package=true" >> "$GITHUB_OUTPUT"; else echo "is_package=false" >> "$GITHUB_OUTPUT"; fi
# --- Optional: Unity compile after Claude’s edits (satisfies NL-4) ---
- name: Unity compile (Project)
if: always() && steps.detect.outputs.has_license == 'true' && steps.detect.outputs.is_project == 'true'
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
projectPath: .
githubToken: ${{ secrets.GITHUB_TOKEN }}
testMode: EditMode

- name: Unity compile (Package)
if: always() && steps.detect.outputs.has_license == 'true' && steps.detect.outputs.is_package == 'true'
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }}
UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }}
with:
packageMode: true
unityVersion: 2022.3.45f1 # set your exact version
projectPath: .
githubToken: ${{ secrets.GITHUB_TOKEN }}

- name: Clean working tree (discard temp edits)
if: always()
run: |
git restore -SW :/
git clean -fd
JSON
# ---------- Reports & helper ----------
- name: Prepare reports and dirs
run: |
set -eux
rm -f reports/*.xml reports/*.md || true
mkdir -p reports reports/_snapshots scripts
- name: Create report skeletons
run: |
set -eu
cat > "$JUNIT_OUT" <<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<testsuites><testsuite name="UnityMCP.NL-T" tests="1" failures="1" errors="0" skipped="0" time="0">
<testcase name="NL-Suite.Bootstrap" classname="UnityMCP.NL-T">
<failure message="bootstrap">Bootstrap placeholder; suite will append real tests.</failure>
</testcase>
</testsuite></testsuites>
XML
printf '# Unity NL/T Editing Suite Test Results\n\n' > "$MD_OUT"
- name: Write safe revert helper (scripts/nlt-revert.sh)
shell: bash
run: |
set -eux
cat > scripts/nlt-revert.sh <<'BASH'
#!/usr/bin/env bash
set -euo pipefail
sub="${1:-}"; target_rel="${2:-}"; snap="${3:-}"
WS="${GITHUB_WORKSPACE:-$PWD}"
ROOT="$WS/TestProjects/UnityMCPTests"
t_abs="$(realpath -m "$WS/$target_rel")"
s_abs="$(realpath -m "$WS/$snap")"
if [[ "$t_abs" != "$ROOT/Assets/"* ]]; then
echo "refuse: target outside allowed scope: $t_abs" >&2; exit 2
fi
mkdir -p "$(dirname "$s_abs")"
case "$sub" in
snapshot)
cp -f "$t_abs" "$s_abs"
sha=$(sha256sum "$s_abs" | awk '{print $1}')
echo "snapshot_sha=$sha"
;;
restore)
if [[ ! -f "$s_abs" ]]; then echo "snapshot missing: $s_abs" >&2; exit 3; fi
cp -f "$s_abs" "$t_abs"
touch "$t_abs"
sha=$(sha256sum "$t_abs" | awk '{print $1}')
echo "restored_sha=$sha"
;;
*)
echo "usage: $0 snapshot|restore <target_rel_path> <snapshot_path>" >&2; exit 1
;;
esac
BASH
chmod +x scripts/nlt-revert.sh
# ---------- Run suite ----------
- name: Run Claude NL suite (single pass)
uses: anthropics/claude-code-base-action@beta
if: steps.detect.outputs.anthropic_ok == 'true' && steps.detect.outputs.unity_ok == 'true'
continue-on-error: true
with:
use_node_cache: false
prompt_file: .claude/prompts/nl-unity-suite-full.md
mcp_config: .claude/mcp.json
allowed_tools: >-
Write,
Bash(printf:*),Bash(echo:*),Bash(scripts/nlt-revert.sh:*),
mcp__unity__manage_editor,
mcp__unity__list_resources,
mcp__unity__read_resource,
mcp__unity__apply_text_edits,
mcp__unity__script_apply_edits,
mcp__unity__validate_script,
mcp__unity__find_in_file,
mcp__unity__read_console
disallowed_tools: TodoWrite,Task
model: claude-3-7-sonnet-latest
timeout_minutes: "30"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

# ---------- Merge testcase fragments into JUnit ----------
- name: Normalize/assemble JUnit in-place (single file)
if: always()
shell: bash
run: |
python3 - <<'PY'
from pathlib import Path
import xml.etree.ElementTree as ET
import re, os
def localname(tag: str) -> str: return tag.rsplit('}', 1)[-1] if '}' in tag else tag
src = Path(os.environ.get('JUNIT_OUT', 'reports/junit-nl-suite.xml'))
if not src.exists(): raise SystemExit(0)
tree = ET.parse(src); root = tree.getroot()
suite = root.find('./*') if localname(root.tag) == 'testsuites' else root
if suite is None: raise SystemExit(0)
fragments = sorted(Path('reports').glob('*_results.xml'))
added = 0
for frag in fragments:
try:
froot = ET.parse(frag).getroot()
if localname(froot.tag) == 'testcase':
suite.append(froot); added += 1
else:
for tc in froot.findall('.//testcase'):
suite.append(tc); added += 1
except Exception:
txt = Path(frag).read_text(encoding='utf-8', errors='replace')
for m in re.findall(r'<testcase[\\s\\S]*?</testcase>', txt, flags=re.DOTALL):
try: suite.append(ET.fromstring(m)); added += 1
except Exception: pass
if added:
# If we added real testcases, drop the bootstrap placeholder and recompute counts
removed_bootstrap = 0
for tc in list(suite.findall('.//testcase')):
name = (tc.get('name') or '')
fail = tc.find('failure')
if name == 'NL-Suite.Bootstrap' and (added > 0):
suite.remove(tc)
removed_bootstrap += 1
# Recompute suite attributes
testcases = suite.findall('.//testcase')
tests_cnt = len(testcases)
failures_cnt = sum(1 for tc in testcases if (tc.find('failure') is not None or tc.find('error') is not None))
suite.set('tests', str(tests_cnt))
suite.set('failures', str(failures_cnt))
suite.set('errors', str(0))
suite.set('skipped', str(0))
tree.write(src, encoding='utf-8', xml_declaration=True)
print(f"Added {added} testcase fragments, removed bootstrap={removed_bootstrap}, tests={tests_cnt}, failures={failures_cnt}")
PY
# ---------- Markdown summary from JUnit ----------
- name: Build markdown summary from JUnit
if: always()
shell: bash
run: |
python3 - <<'PY'
import xml.etree.ElementTree as ET
from pathlib import Path
import os
def localname(tag: str) -> str: return tag.rsplit('}', 1)[-1] if '}' in tag else tag
src = Path(os.environ.get('JUNIT_OUT', 'reports/junit-nl-suite.xml'))
md_out = Path(os.environ.get('MD_OUT', 'reports/junit-nl-suite.md'))
if not src.exists():
md_out.write_text("# Unity NL/T Editing Suite Test Results\n\n(No JUnit found)\n", encoding='utf-8'); raise SystemExit(0)
tree = ET.parse(src); root = tree.getroot()
suite = root.find('./*') if localname(root.tag) == 'testsuites' else root
cases = [] if suite is None else [tc for tc in suite.findall('.//testcase')]
total = len(cases)
failures = sum(1 for tc in cases if (tc.find('failure') is not None or tc.find('error') is not None))
passed = total - failures
desired = ['NL-0','NL-1','NL-2','NL-3','NL-4','T-A','T-B','T-C','T-D','T-E','T-F','T-G','T-H','T-I','T-J']
name_to_case = {(tc.get('name') or ''): tc for tc in cases}
def status_for(prefix: str):
for name, tc in name_to_case.items():
if name.startswith(prefix):
return not ((tc.find('failure') is not None) or (tc.find('error') is not None))
return None
lines = []
lines += ['# Unity NL/T Editing Suite Test Results','',f'Totals: {passed} passed, {failures} failed, {total} total','', '## Test Checklist']
for p in desired:
st = status_for(p)
lines.append(f"- [x] {p}" if st is True else (f"- [ ] {p} (fail)" if st is False else f"- [ ] {p} (not run)"))
lines.append('')
# Rich per-test details (pull from <system-out>)
lines.append('## Test Details')
# Sort by canonical order where possible
def order_key(n: str):
try:
if n.startswith('NL-') and n[3].isdigit():
return (0, int(n.split('.')[0].split('-')[1]))
except Exception:
pass
if n.startswith('T-') and len(n)>2 and n[2].isalpha():
return (1, ord(n[2]))
return (2, n)
for name in sorted(name_to_case.keys(), key=order_key):
tc = name_to_case[name]
so = tc.find('system-out')
text = '' if so is None or so.text is None else so.text
text = text.replace('\r\n','\n')
# Trim overly long outputs
MAX_CHARS = 2000
if len(text) > MAX_CHARS:
text = text[:MAX_CHARS] + "\n…(truncated)"
lines.append(f"### {name}")
if text.strip():
lines.append('```')
lines.append(text.strip())
lines.append('```')
else:
lines.append('(no system-out)')
lines.append('')
for name, tc in name_to_case.items():
node = tc.find('failure') or tc.find('error')
if node is None: continue
msg = (node.get('message') or '').strip()
text = (node.text or '').strip()
lines.append(f"### {name}")
if msg: lines.append(f"- Message: {msg}")
if text: lines.append(f"- Detail: {text.splitlines()[0][:500]}")
lines.append('')
md_out.write_text('\n'.join(lines), encoding='utf-8')
PY
- name: "Debug: list report files"
if: always()
shell: bash
run: |
set -eux
ls -la reports || true
shopt -s nullglob
for f in reports/*.xml; do
echo "===== $f ====="
head -n 40 "$f" || true
done
# ---------- Collect execution transcript (if present) ----------
- name: Collect action execution transcript
if: always()
shell: bash
run: |
set -eux
if [ -f "$RUNNER_TEMP/claude-execution-output.json" ]; then
cp "$RUNNER_TEMP/claude-execution-output.json" reports/claude-execution-output.json
elif [ -f "/home/runner/work/_temp/claude-execution-output.json" ]; then
cp "/home/runner/work/_temp/claude-execution-output.json" reports/claude-execution-output.json
fi
- name: Sanitize markdown (normalize newlines)
if: always()
run: |
set -eu
python - <<'PY'
from pathlib import Path
rp=Path('reports'); rp.mkdir(parents=True, exist_ok=True)
for p in rp.glob('*.md'):
b=p.read_bytes().replace(b'\x00', b'')
s=b.decode('utf-8','replace').replace('\r\n','\n')
p.write_text(s, encoding='utf-8', newline='\n')
PY
- name: NL/T details → Job Summary
if: always()
run: |
echo "## Unity NL/T Editing Suite — Summary" >> $GITHUB_STEP_SUMMARY
python - <<'PY' >> $GITHUB_STEP_SUMMARY
from pathlib import Path
p = Path('reports/junit-nl-suite.md')
if p.exists():
text = p.read_bytes().decode('utf-8', 'replace')
MAX = 65000
print(text[:MAX])
if len(text) > MAX:
print("\n\n_…truncated; full report in artifacts._")
else:
print("_No markdown report found._")
PY
- name: Fallback JUnit if missing
if: always()
run: |
set -eu
mkdir -p reports
if [ ! -f "$JUNIT_OUT" ]; then
printf '%s\n' \
'<?xml version="1.0" encoding="UTF-8"?>' \
'<testsuite name="UnityMCP.NL-T" tests="1" failures="1" time="0">' \
' <testcase classname="UnityMCP.NL-T" name="NL-Suite.Execution" time="0.0">' \
' <failure><![CDATA[No JUnit was produced by the NL suite step. See the step logs.]]></failure>' \
' </testcase>' \
'</testsuite>' \
> "$JUNIT_OUT"
fi
- name: Publish JUnit report
if: always()
uses: mikepenz/action-junit-report@v5
with:
report_paths: '${{ env.JUNIT_OUT }}'
include_passed: true
detailed_summary: true
annotate_notice: true
require_tests: false
fail_on_parse_error: true

- name: Upload artifacts (reports + fragments + transcript)
if: always()
uses: actions/upload-artifact@v4
with:
name: claude-nl-suite-artifacts
path: |
${{ env.JUNIT_OUT }}
${{ env.MD_OUT }}
reports/*_results.xml
reports/claude-execution-output.json
retention-days: 7

# ---------- Always stop Unity ----------
- name: Stop Unity
if: always()
run: |
docker logs --tail 400 unity-mcp | sed -E 's/((serial|license|password|token)[^[:space:]]*)/[REDACTED]/ig' || true
docker rm -f unity-mcp || true
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Strip trailing spaces and ensure newline at EOF.

Several lines carry trailing spaces; no newline at EOF. Clean to satisfy actionlint/YAMLlint.

Run:


🏁 Script executed:

#!/bin/bash
yamllint -f parsable .github/workflows/claude-nl-suite.yml || true
sed -n '1,999p' .github/workflows/claude-nl-suite.yml | nl -ba | sed -n '1,120p'

Length of output: 11004


Fix YAML lint errors in .github/workflows/claude-nl-suite.yml

  • Add the missing document start marker (---) at the top of the file.
  • Replace truthy values ({}) with valid YAML booleans (true/false).
  • Correct indentation throughout (e.g. around jobs/steps definitions).
  • Remove all trailing spaces.
  • Ensure the file ends with a single newline.
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 5-5: trailing spaces

(trailing-spaces)


[error] 9-9: trailing spaces

(trailing-spaces)


[error] 13-13: trailing spaces

(trailing-spaces)


[error] 18-18: trailing spaces

(trailing-spaces)


[warning] 21-21: wrong indentation: expected 8 but found 6

(indentation)


[warning] 25-25: wrong indentation: expected 10 but found 8

(indentation)


[warning] 26-26: too many spaces after colon

(colons)


[error] 27-27: trailing spaces

(trailing-spaces)


[warning] 30-30: wrong indentation: expected 10 but found 8

(indentation)


[warning] 33-33: wrong indentation: expected 14 but found 12

(indentation)


[warning] 33-33: too many spaces after colon

(colons)


[warning] 34-34: too many spaces after colon

(colons)


[warning] 36-36: too many spaces after colon

(colons)


[error] 46-46: trailing spaces

(trailing-spaces)


[warning] 49-49: wrong indentation: expected 14 but found 12

(indentation)


[error] 50-50: trailing spaces

(trailing-spaces)


[warning] 54-54: wrong indentation: expected 14 but found 12

(indentation)


[error] 55-55: trailing spaces

(trailing-spaces)


[error] 73-73: trailing spaces

(trailing-spaces)


[warning] 79-79: wrong indentation: expected 14 but found 12

(indentation)


[warning] 79-79: too many spaces after colon

(colons)


[warning] 80-80: too many spaces after colon

(colons)


[warning] 82-82: too many spaces after colon

(colons)


[warning] 84-84: wrong indentation: expected 14 but found 12

(indentation)


[error] 88-88: trailing spaces

(trailing-spaces)


[error] 95-95: trailing spaces

(trailing-spaces)


[error] 102-102: trailing spaces

(trailing-spaces)


[warning] 107-107: wrong indentation: expected 14 but found 12

(indentation)


[warning] 107-107: too many spaces after colon

(colons)


[warning] 109-109: too many spaces after colon

(colons)


[error] 139-139: trailing spaces

(trailing-spaces)


[error] 179-179: trailing spaces

(trailing-spaces)


[error] 201-201: trailing spaces

(trailing-spaces)


[error] 208-208: trailing spaces

(trailing-spaces)


[error] 221-221: trailing spaces

(trailing-spaces)


[error] 257-257: trailing spaces

(trailing-spaces)


[warning] 264-264: wrong indentation: expected 14 but found 12

(indentation)


[error] 282-282: trailing spaces

(trailing-spaces)


[error] 333-333: trailing spaces

(trailing-spaces)


[error] 407-407: trailing spaces

(trailing-spaces)


[error] 419-419: trailing spaces

(trailing-spaces)


[error] 431-431: trailing spaces

(trailing-spaces)


[error] 444-444: trailing spaces

(trailing-spaces)


[error] 461-461: trailing spaces

(trailing-spaces)


[error] 477-477: trailing spaces

(trailing-spaces)


[warning] 482-482: wrong indentation: expected 14 but found 12

(indentation)


[error] 488-488: trailing spaces

(trailing-spaces)


[warning] 493-493: wrong indentation: expected 14 but found 12

(indentation)


[error] 500-500: trailing spaces

(trailing-spaces)


[error] 507-507: no new line character at the end of file

(new-line-at-end-of-file)


[error] 507-507: trailing spaces

(trailing-spaces)

🤖 Prompt for AI Agents
In .github/workflows/claude-nl-suite.yml (lines 1-507): the file is failing YAML
lint due to a missing document start marker, use of {} where booleans are
required, inconsistent indentation and trailing spaces, and missing final
newline; fix by (1) add a top-line document marker ---, (2) replace occurrences
of {} used as truthy values (e.g. workflow_dispatch: {}) with explicit YAML
booleans (workflow_dispatch: true or false as appropriate), (3) correct
indentation under top-level keys (on permissions, concurrency, env, jobs, and
every jobs.*.steps block) so sequences and mappings follow YAML rules, (4)
remove all trailing spaces and ensure consistent indentation (2 spaces per level
or match repository style), and (5) ensure the file ends with exactly one
newline character.

@dsarno dsarno closed this Aug 30, 2025
@dsarno dsarno deleted the feat/pre-split-edit-framing-testes branch August 30, 2025 16:22
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