Skip to content

feat/chores: Serialization Behaviour, CI Improvements#261

Open
Eli Pinkerton (wallstop) wants to merge 31 commits into
mainfrom
dev/wallstop/serialization-fixes
Open

feat/chores: Serialization Behaviour, CI Improvements#261
Eli Pinkerton (wallstop) wants to merge 31 commits into
mainfrom
dev/wallstop/serialization-fixes

Conversation

@wallstop

@wallstop Eli Pinkerton (wallstop) commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Description

This branch tightens serialization behavior and expands the validation around it.

  • Refines the runtime serializer and adds a dedicated failure exception for clearer error handling.
  • Adds broader serialization test coverage, including API contract, exception contract, fuzz, and try-pattern tests.
  • Updates runtime singleton and related helper code to support the serialization changes.
  • Expands pre-push, preflight, and CI automation for Unity, MCP, documentation, and validation workflows.
  • Refreshes supporting docs and repo configuration so the new checks and workflows are documented and enforced consistently.

Related Issue

Fixes #

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactor (code change that neither fixes a bug nor adds a feature)

Checklist

  • I have added tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have updated the CHANGELOG
  • My changes do not introduce breaking changes, or breaking changes are documented

Note

Medium Risk
Hooks no longer run many checks locally on commit/push, so developers depend on preflight/CI unless they run it; Unity/bootstrap workflows reference scripts not yet ported and can hard-fail maintenance until those land.

Overview
Git hooks are restructured: thin sh entrypoints delegate to new *.ps1 implementations and require PowerShell 7. Pre-commit drops the large bash pipeline (formatting, spelling, linters, license checks, etc.) in favor of a fast path—version sync, final newlines, LLM/meta checks, staged #region guard—with heavier work pointed at npm run agent:preflight and CI. Pre-push is similarly slimmed (focused C# #region checks on pushed changes with optional agent:preflight:fix hints). Post-rewrite now clears the license-year cache via git rev-parse --git-path in PowerShell. Both hook layers add cleanup/validation for stray gitignored hook artifact files.

CI and automation add a substantial Unity self-hosted surface: canonical JSON for Unity versions, test-project modules, and OpenUPM integration packages; composite actions for assembly discovery, license validate/return, result verification, log dumps, and runner diagnostics; plus a runner-bootstrap workflow (with a noted gap until maintain-windows-runner.ps1 is ported). Lint workflows change behavior: doc links split internal (PR-gated) vs scheduled external lychee; asmdef lint includes **.cs; LLM lint runs on ubuntu + windows and enforces an up-to-date .llm/skills/index.md; pwsh-invocations lint covers actions and workflow run-expression length.

Smaller updates: actionlint config for custom runner labels, docs issue template placeholder URL, and integration-package pins for DI test legs.

Reviewed by Cursor Bugbot for commit fe4b841. Bugbot is set up for automated code reviews on this repo. Configure here.

Eli Pinkerton (wallstop) and others added 10 commits June 14, 2026 01:47
…idator

- Gitignore machine-local .mcp.json + .cursor/mcp.json; drop stale DxMessaging cruft.
- Fix a command-injection in probe-unity-mcp-endpoint.sh, align arg/env precedence,
  and correct a misplaced shellcheck directive in both copied MCP scripts.
- Remove the dangling "Claude Desktop helper" README section and add a session-binding note.
- Add scripts/validate-mcp-config.ps1 (+ self-test + validate-mcp-config.yml CI)
  enforcing configs are gitignored, valid, target /mcp, and doc refs resolve.
- Add the mcp-configuration skill, MCP Local Setup nav entry, and the "mcp" cspell term.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atrix

- .github/unity-versions.json (2021.3.45f1 / 2022.3.45f1 / 6000.3.16f1) as the
  single version source; .github/actionlint.yaml declares the RAM-64GB runner label.
- unity-tests.yml: matrix-config (secrets gate) -> runner-preflight (soft-pass) ->
  [self-hosted, Windows, RAM-64GB] matrix (version x editmode/playmode/standalone),
  max-parallel:1, org build-lock acquire/release, perf excluded (!Performance;!Stress).
- unity-benchmarks.yml: dedicated perf job (Performance;Stress) + a full-N Random leg
  (UH_RANDOM_SAMPLE_COUNT) + auto-commit of raw results to top-level perf-results/.
- 6 composite actions + scripts/unity/{run-ci-tests.ps1, ensure-editor.ps1,
  lib/asmdef-discovery.js}; stuck-job-watchdog / unstick-run / runner-bootstrap +
  the unity-runners-after-transfer runbook.
- The matrix cleanly SKIPS until ORG_BUILD_LOCK_TOKEN + UNITY_SERIAL/EMAIL/PASSWORD exist.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s taxonomy + lint

- RandomTestBase: SampleCount 12.75M -> env-overridable 250k fast default
  (UH_RANDOM_SAMPLE_COUNT restores the full count for the benchmark job); add a
  sqrt(average) deviation floor so reduced-N runs stay reliably green while the
  large-N run keeps its original tighter sensitivity. Monte-Carlo validated.
- Add lint rules UNH007 (giant literal loops outside perf fixtures), UNH008 (perf
  fixtures must carry [Category("Performance"|"Stress")] so the CI filter excludes
  them) and UNH009 (advisory: per-test AssetDatabase churn) + red-green tests.
- Tag the 14 Tests/Runtime/Performance fixtures + 2 wall-clock pool tests Performance;
  trim the Proto RoundTripLargeCollections correctness test 100k -> 10k.
- Add the test-performance skill.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ress tests

- SerializationFailureException (+ sealed subclasses); Serializer deserialize paths
  wrapped so every public entry point throws SerializationFailureException or has a
  Try* sibling, enforced by SerializerApiContractTests.
- New contract/fuzz/Try-API/exception tests; rename test methods to PascalCase (UNH004)
  and replace Assert.IsNull/IsNotNull with Assert.IsTrue(== null / != null) (UNH005).
- Update defensive-programming / use-serialization / forbidden-patterns concepts and
  add the serialization-safety skill (the documented "never throw" carve-out).
- Trim the JSON RoundTripLargeCollections correctness test 100k -> 10k.
- Drop stray .llm/skills/*.md.meta (skills carry no Unity .meta); regenerate skills index.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eaks

Pre-existing branch work, committed to keep the tree clean. Lint + csharpier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…porter

Importer metadata change (DefaultImporter -> ScriptedImporter) for the docs SVGs
plus a material tweak; pre-existing branch work. Isolated for easy revert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atrix

Goal 1 (special defines): add -AdditionalScriptingDefines to run-ci-tests.ps1,
injected via a PlayerSettings.SetScriptingDefineSymbols + SaveAssets configure pass
BEFORE -runTests so the asmdef test assemblies compile with them; add a Unity-6-only
`unity-tests-single-threaded` job (editmode+playmode, core-only, SINGLE_THREADED)
with its own org-lock/preflight/license/verify scaffolding and -single-threaded
cache/artifact paths. Exercises the 10-file SINGLE_THREADED path never compiled in
the normal matrix.

Goal 2 (integrations): add .github/integration-packages.json (Reflex/VContainer/
Extenject from OpenUPM) + -IncludeIntegrations; the main matrix now installs the 3
DI packages and runs the Reflex/VContainer/Zenject integration asmdefs across all
Unity versions.

Also prettier-fix asmdef-discovery.js. Unverified without a self-hosted run: define
persistence+recompile and OpenUPM pin resolution. Matrix still skips until secrets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- extract-perf-metrics.js parses the benchmark NUnit results (unity-helpers perf
  tests emit Stopwatch timings as GFM markdown tables in each test's <output> CDATA)
  into normalized metrics; render-perf-deltas.js diffs vs a committed rolling
  baseline and renders Markdown + JSON with regression classification (report-only).
- Seed perf-results/baseline.json; the benchmark commit job now extracts, diffs,
  updates the baseline, writes perf-deltas.md, and commits perf-results/**.
- Ignore perf-results/** in prettier + cspell so generated reports never trip CI.
- Both JS pass --self-test. Unverified without a real results.xml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 14, 2026 16:09
on:
push:
branches:
- main

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MCP push skips master branch

Low Severity

The new MCP validation workflow’s push trigger lists only main, while unity-tests.yml in the same change set runs on pushes to both master and main. Direct pushes to master that touch MCP-related paths therefore skip this validator even though Unity CI can still run for that branch.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 21a6c97. Configure here.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR tightens and formalizes runtime serialization error behavior (typed exception hierarchy + non-throwing Try* APIs), expands test coverage around those contracts (including fuzz/contract tests), and adds/extends automation around CI + developer workflows (hooks, license header tooling, MCP config validation).

Changes:

  • Introduce and enforce a typed serialization failure contract (SerializationFailureException hierarchy) across serializer entry points; update existing tests to the new contract.
  • Add new serialization test suites (API contract, Try* contract, fuzzing, exception hierarchy tests) and adjust performance/correctness tests to keep the main suite fast.
  • Expand repo automation: MCP local setup tooling + validation workflow, hook install improvements, doc-link lint path-scoping, and license-year cache/worktree safety.

Reviewed changes

Copilot reviewed 155 out of 158 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
Tests/Runtime/Utils/RuntimeSingletonTests.cs Adds coverage for singleton ClearInstance + registry clearing.
Tests/Runtime/Serialization/SerializerTryApiTests.cs.meta Unity meta for new test file.
Tests/Runtime/Serialization/SerializerTryApiTests.cs Adds tests for Try* serializer APIs and exception propagation rules.
Tests/Runtime/Serialization/SerializerFuzzTests.cs.meta Unity meta for new test file.
Tests/Runtime/Serialization/SerializerFuzzTests.cs Adds fuzz tests + allocation guard for lazy exception message composition.
Tests/Runtime/Serialization/SerializerExceptionContractTests.cs.meta Unity meta for new test file.
Tests/Runtime/Serialization/SerializerApiContractTests.cs.meta Unity meta for new test file.
Tests/Runtime/Serialization/SerializerApiContractTests.cs Adds reflection-based “forever gate” for deserializer/Try* sibling parity + null-input Try* contract test.
Tests/Runtime/Serialization/SerializerAdditionalTests.cs Updates existing tests to new configuration/input exception types.
Tests/Runtime/Serialization/SerializationFailureExceptionTests.cs.meta Unity meta for new test file.
Tests/Runtime/Serialization/SerializationFailureExceptionTests.cs Tests the new serialization exception hierarchy (immutability, lazy Message, serialization).
Tests/Runtime/Serialization/ProtoSerializationTests.cs Aligns protobuf tests to typed serialization exception contract.
Tests/Runtime/Serialization/ProtoSerializationCorrectnessTests.cs Reduces large collection sizes to keep correctness tests fast.
Tests/Runtime/Serialization/ProtoInterfaceResolutionEdgeTests.cs Updates interface/abstract resolution tests to expect typed type exceptions.
Tests/Runtime/Serialization/JsonSerializationCorrectnessTests.cs Updates JSON tests to typed corrupt-data exception + reduces large collection sizes.
Tests/Runtime/Random/RandomTestBase.cs Makes sampling count configurable (env override) + adds statistical deviation floor for stability.
Tests/Runtime/Pool/WallstopGenericPoolTests.cs Tags a perf-sensitive test with Performance.
Tests/Runtime/Pool/RollingHighWaterMarkTests.cs Tags a perf-sensitive test with Performance.
Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs Adds Performance category marker.
Tests/Runtime/Performance/ReflectionPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/RandomPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/ProtoSerializationPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/ProtoEqualsPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/PoolPurgeTriggerPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/PerformanceBaselineTests.cs Adds Performance category marker.
Tests/Runtime/Performance/ListExtensionPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/IListSortingPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/ConvexHullPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Performance/ConcaveHullPerformanceTests.cs Adds Performance category marker.
Tests/Runtime/Extensions/UnityExtensionsBasicTests.cs Updates Rigidbody2D stop test (velocity property usage changed).
Tests/Editor/CustomDrawers/SerializableSetPropertyDrawerTests.cs Adds explicit alias using for TestData type.
Shaders/Materials/BackgroundMask-Material.mat Unity material serialization version update + new locking flag.
scripts/validate-mcp-config.ps1.meta Unity meta for new script.
scripts/validate-mcp-config.ps1 Adds MCP client config validation (gitignore, structural validity, doc references).
scripts/update-license-headers.sh Makes license header updates worktree-safe + path-scoped + tracked-file enumeration.
scripts/unity/run-ci-tests.ps1.meta Unity meta for new/updated script asset.
scripts/unity/lib/render-perf-deltas.js.meta Unity meta for script asset.
scripts/unity/lib/extract-perf-metrics.js.meta Unity meta for script asset.
scripts/unity/lib/asmdef-discovery.js.meta Unity meta for script asset.
scripts/unity/lib.meta Unity meta for new folder.
scripts/unity/ensure-editor.ps1.meta Unity meta for script asset.
scripts/tests/test-validate-mcp-config.ps1.meta Unity meta for new test script asset.
scripts/tests/test-sync-script-contracts.ps1 Adds additional contract checks (pwsh path binding, hook installer, Prettier LF override, markdown fence fixer wiring).
scripts/tests/test-pre-push-changed-files.sh Expands changed-file collection tests (diff-filter deletes/renames, doc-link triggers, doc-link scope).
scripts/tests/test-lint-tests.ps1 Adds tests for UNH007/UNH008/UNH009 lint behavior.
scripts/tests/test-lint-doc-links.ps1 Adds path-scoped invocation support and additional markdown lint scenarios.
scripts/tests/test-license-cache.sh Adds worktree-safe cache checks + validates dynamic year + staged-license wiring.
scripts/tests/test-hook-patterns.sh Adds coverage for rename-aware diff filters in pre-commit.
scripts/normalize-eol.ps1 Adds support for trailing args under pwsh -File + merges path inputs.
scripts/mcp/start-unity-mcp-bridge.ps1.meta Unity meta for new script.
scripts/mcp/start-unity-mcp-bridge.ps1 Adds Windows-side supergateway bridge launcher for Unity MCP.
scripts/mcp/README.md.meta Unity meta for new docs asset.
scripts/mcp/README.md Documents Unity MCP bridge workflow for Windows host + Linux devcontainer.
scripts/mcp/probe-unity-mcp-endpoint.sh.meta Unity meta for new script.
scripts/mcp/probe-unity-mcp-endpoint.sh Adds endpoint probing/diagnostics for MCP bridge reachability.
scripts/mcp/configure-unity-mcp-endpoint.sh.meta Unity meta for new script.
scripts/mcp/configure-unity-mcp-endpoint.sh Generates/updates local MCP client configs (VS Code, Claude Code, Cursor, Codex).
scripts/mcp.meta Unity meta for new folder.
scripts/lint-tests.ps1 Adds UNH007/UNH008 blocking rules + UNH009 advisory reporting for test perf budgets/churn.
scripts/lint-staged-markdown.ps1 Runs markdown fence language fixer before markdownlint.
scripts/install-hooks.ps1 Adds -HooksOnly flow + executable bit restoration on non-Windows.
scripts/fix-markdown-fence-languages.ps1.meta Updates Unity meta GUID for the script asset.
scripts/check-eol.ps1 Adds support for trailing args under pwsh -File + merges path inputs.
scripts/audit-license-years.sh Makes cache worktree-safe, computes year dynamically, enumerates tracked files, adds path normalization.
Runtime/WallstopStudios.UnityHelpers.asmdef Switches to overrideReferences: true for assembly reference control.
Runtime/Utils/RuntimeSingletonRegistry.cs Renames init hook and exposes a manual clear entry point for singleton registry.
Runtime/Utils/RuntimeSingleton.cs Makes ClearInstance public + documents registry-based domain reload clearing.
Runtime/Protobuf-Net/System.Collections.Immutable.dll.meta Adjusts plugin importer settings (reference validation + editor enablement).
Runtime/Core/Serialization/SerializationFailureException.cs.meta Unity meta for new exception hierarchy file.
Runtime/Core/Extension/Partials/Physics.cs Updates Rigidbody2D Stop implementation (velocity property usage changed).
perf-results/baseline.json.meta Unity meta for new perf baseline artifact.
perf-results/baseline.json Seeds rolling perf baseline storage for benchmark workflow.
perf-results.meta Unity meta for new folder.
package.json Adds MCP config validation + expands test/validation scripts; updates hooks installer entrypoint.
mkdocs.yml Adds MCP local setup guide to docs nav.
docs/runbooks/unity-runners-after-transfer.md.meta Unity meta for new docs asset.
docs/runbooks.meta Unity meta for new folder.
docs/images/utilities/singletons/singletons-lifecycle.svg.meta Updates SVG importer metadata.
docs/images/utilities/singletons/data-distribution-decision.svg.meta Updates SVG importer metadata.
docs/images/utilities/reflection/reflection-scan.svg.meta Updates SVG importer metadata.
docs/images/utilities/random/random-generators.svg.meta Updates SVG importer metadata.
docs/images/utilities/math/polyline-simplify.svg.meta Updates SVG importer metadata.
docs/images/utilities/math/geometry-edge-cases.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/trie.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/sparse-set.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/heap.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/disjoint-set.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/deque.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/deque-queue.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/cyclic-buffer.svg.meta Updates SVG importer metadata.
docs/images/utilities/data-structures/bitset.svg.meta Updates SVG importer metadata.
docs/images/unity-helpers-banner.svg.meta Updates SVG importer metadata.
docs/images/spatial/r-tree-3d.svg.meta Updates SVG importer metadata.
docs/images/spatial/r-tree-2d.svg.meta Updates SVG importer metadata.
docs/images/spatial/query-boundaries.svg.meta Updates SVG importer metadata.
docs/images/spatial/quadtree-2d.svg.meta Updates SVG importer metadata.
docs/images/spatial/octree-3d.svg.meta Updates SVG importer metadata.
docs/images/spatial/kd-tree-3d.svg.meta Updates SVG importer metadata.
docs/images/spatial/kd-tree-2d.svg.meta Updates SVG importer metadata.
docs/images/spatial/convex-hull.svg.meta Updates SVG importer metadata.
docs/images/spatial/concave-hull.svg.meta Updates SVG importer metadata.
docs/images/serialization/serialization-flow.svg.meta Updates SVG importer metadata.
docs/images/relational-components/relational-wiring.svg.meta Updates SVG importer metadata.
docs/images/effects/effects-pipeline.svg.meta Updates SVG importer metadata.
docs/images/effects/attribute-resolution.svg.meta Updates SVG importer metadata.
docs/guides/mcp-local-setup.md.meta Unity meta for new guide.
docs/guides/mcp-local-setup.md Adds MCP local setup documentation (devcontainer + Windows host relay).
cspell.json Ignores perf artifacts + adds new technical terms.
.prettierrc.json Adds .github/** to LF override set.
.prettierignore Ignores generated perf results tree from Prettier checks.
.llm/skills/use-serialization.md Documents serializer exception contract + Try* usage.
.llm/skills/test-performance.md Adds repository guidance for test performance budgets (UNH007/8/9).
.llm/skills/serialization-safety.md Adds detailed serializer safety contract and forbidden patterns.
.llm/skills/optimize-git-hooks.md Tightens documented hook performance budgets and guidance.
.llm/skills/mcp-configuration.md Documents Unity MCP configuration conventions and validation guarantees.
.llm/skills/markdown-reference.md Clarifies fenced block language guidance (text vs mermaid).
.llm/skills/linter-reference.md Notes scoped doc-link lint option.
.llm/skills/formatting-and-linting.md Updates hook workflow documentation (doc-link lint, license audit, fence fixer).
.llm/skills/defensive-programming.md Updates exception philosophy to include serialization carve-out (table formatting needs correction).
.llm/references/forbidden-patterns.md Adds explicit serialization forbidden patterns and required contracts.
.gitignore Ignores machine-local MCP client config files.
.github/workflows/validate-mcp-config.yml Adds workflow to run MCP config validator + its tests.
.github/unity-versions.json Adds canonical Unity version source for CI matrices.
.github/integration-packages.json Adds canonical pinned DI integration package list for CI.
.github/actions/validate-unity-license/action.yml Adds Unity serial activation preflight composite action.
.github/actions/return-unity-license/action.yml Adds best-effort license return composite action.
.github/actions/dump-unity-log-tail/action.yml Adds diagnostic log tail dump + catastrophic pattern scan on failure/cancel.
.github/actions/compute-unity-assemblies/action.yml Adds asmdef discovery-based test assembly list computation action.
.github/actionlint.yaml Adds actionlint config for custom self-hosted runner labels.
.githooks/post-rewrite Makes license cache invalidation worktree-safe via git rev-parse --git-path.
Comments suppressed due to low confidence (1)

Runtime/Utils/RuntimeSingleton.cs:135

  • ClearInstance() destroys a Unity object; calling it from a background thread can cause Unity thread-affinity errors. Since the method is now public, it should enforce main-thread execution before invoking Destroy().

Comment thread Runtime/Core/Extension/Partials/Physics.cs
Comment thread Tests/Runtime/Extensions/UnityExtensionsBasicTests.cs Outdated
Comment thread Tests/Runtime/Serialization/SerializerApiContractTests.cs
Comment thread Tests/Runtime/Serialization/SerializerApiContractTests.cs
Comment thread .llm/skills/defensive-programming.md
Comment thread .githooks/post-rewrite Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 157 out of 160 changed files in this pull request and generated 5 comments.

Comment thread Runtime/Core/Extension/Partials/Physics.cs
Comment thread Tests/Runtime/Extensions/UnityExtensionsBasicTests.cs Outdated
Comment thread .llm/skills/defensive-programming.md
Comment thread Tests/Runtime/Serialization/SerializerApiContractTests.cs
Comment thread Tests/Runtime/Serialization/SerializerApiContractTests.cs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 173 out of 176 changed files in this pull request and generated 6 comments.

Comment thread Runtime/Core/Extension/Partials/Physics.cs
Comment thread Tests/Runtime/Extensions/UnityExtensionsBasicTests.cs
Comment thread scripts/normalize-eol.ps1
Comment thread Runtime/Utils/RuntimeSingleton.cs
Comment thread Tests/Runtime/Serialization/SerializerApiContractTests.cs
Comment thread Tests/Runtime/Serialization/SerializerApiContractTests.cs
Eli Pinkerton (wallstop) and others added 7 commits June 15, 2026 19:41
Move the generated skills index out of the embedded context.md block into a standalone .llm/skills/index.md (linked from context.md). Make generation byte-for-byte deterministic across OS: ordinal sort, no timestamp, UTF-8 no-BOM + LF. Linter now validates the file, enforces ASCII-only triggers (root-causing the em-dash drift that broke CI), the no-BOM/LF contract, generator determinism, and trigger field-count/category. CI lint job runs on ubuntu+windows. index.md excluded from authored-skill size limit and Prettier.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…it lint

report-slow-tests.ps1 ranks the slowest fixtures/cases from NUnit results (+GitHub step summary) and can fail CI over a per-fixture wall-clock budget; wired into both Unity CI jobs and the devcontainer runner. UNH010 (advisory) flags literal real-time waits (WaitForSeconds/Task.Delay/Thread.Sleep) in non-perf tests. test-performance.md documents the measure-first loop, UNH010, and the logic/IO-split pattern. This is the durable measure-and-enforce backbone for keeping the suite fast.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the alpha-bounded rect + padding + pivot computation from ProcessSprite into an internal static ComputeCrop (behavior-preserving; ProcessSprite calls it). Move the 23 dimension/padding/edge [TestCase]s from full texture import round-trips (~6s each) into pure SpriteCropperMathTests (microseconds); keep 8 integration tests covering the real import/crop/output pipeline. MCP-verified: SpriteCropperAdditionalTests 185s -> 53s, 33/33 green, coverage retained and expanded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract a pure, internal `FitComputation ComputeFit(...)` from
FitTextureSizeWindow's per-asset processing path so the exhaustive
fit-mode / clamp / rounding permutations can be exercised without a
texture-import round-trip.

Move the 168 parameterized math cases out of the slow integration
fixture into a new pure fixture (FitTextureSizeMathTests) that calls
ComputeFit directly; retain the genuinely-integration tests (label/name
filters, platform overrides, selection scoping, last-run summary,
default-min clamp) in FitTextureSizeWindowTests.

Behavior-preserving: the test-file change is a pure relocation (0
insertions, only deletions) and the window now consumes
`fit.TargetSize` exactly where it previously computed the size inline.
Coverage adversarially audited as retained -- 168/168 deleted rows have
an identical pure case, all four FitMode members + min/max precedence +
RoundToNearest tie-breaking + power-of-two boundaries are covered, and
all seven ComputeFit branches are hit. Pure fixture verified green via
the Unity TestRunnerApi (168/168 pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ixture

Extract a pure, internal `bool WouldTextureSettingsChange(in
TextureSettingsState current, SpriteSettings spriteData)` plus a
`TextureSettingsState` snapshot struct from SpriteSettingsApplier's
importer path. `WillTextureSettingsChange` now builds the snapshot from
the live importer and delegates to the pure decision.

Move the per-field change-detection cases (every TextureSettingsState
field, both changed->true and matches->false, plus all-match,
one-differs, and no-apply-flags) out of the slow integration fixture
into a new pure fixture (SpriteSettingsApplierLogicTests) that calls
WouldTextureSettingsChange directly; retain the genuinely-integration
tests (path matching, profile priority, importer round-trip via
TryUpdate / buffer reuse / WillChange-vs-TryUpdate consistency) in
SpriteSettingsApplierAdditionalTests.

Behavior-preserving: the test-file change is a pure relocation (0
insertions, only deletions). Coverage adversarially audited as retained
-- all 16 deleted methods have byte-identical TestCaseSource bodies in
the pure fixture, all 14 snapshot fields are covered in both directions,
pivot vector and alignment are isolated, apply-flag on/off are both
exercised, and all 15 comparison branches are hit (the pure fixture even
adds a null-profile case). Verified green via the Unity TestRunnerApi
(92/92 pass).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract an `internal static bool AreAnimationClipsContentEqual(AnimationClip,
AnimationClip)` overload from AnimationCopierWindow's path-based comparator;
the existing path overload now loads both clips via AssetDatabase and delegates
to it (behavior-preserving -- the comparison block moved verbatim, same order /
operators / Mathf.Approximately thresholds / null->false semantics).

Add a pure fixture (AnimationClipContentEqualityTests, 45 cases) that builds
in-memory AnimationClips and exercises every comparison dimension -- frameRate,
length, wrapMode, legacy, all 10 AnimationClipSettings fields, the animation-
event sub-fields + objectReference, float-curve binding (count/path/property/
type) and keyframe detail (time/value/key-count/tangent/weight/pre+post wrap),
and object-reference-curve binding/keyframe (count/time/value). Runs in ~0.7s
with no asset I/O.

This is a coverage improvement, not a runtime cut: the content-equality logic
was previously exercised only indirectly by a few slow asset-round-trip
integration tests. The genuine integration behavior (CopyAsset GUID
preservation, mirror-delete, nested-folder creation, unchanged-after-copy
detection) remains in AnimationCopierWindowTests, which is unchanged.

Verified green via the Unity TestRunnerApi (45/45 pass); the extraction was
adversarially reviewed as 1:1 behavior-preserving.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…in clip compare

Two fixes surfaced while hardening AnimationClip content-equality coverage:

1. Remove vestigial work in AnalyzeAnimations. AnimationFileInfo.Hash was
   computed via AssetDatabase.GetAssetDependencyHash for every source clip AND
   every destination orphan on every analyze, but the field was never read
   anywhere (the classifier switched to content comparison long ago). Removed
   the field, both assignments, and GetDependencyHashString -- eliminating one
   AssetDatabase call per file in the analyze path. Classification
   (New/Changed/Unchanged/Orphan) is unaffected; it uses File.Exists +
   AreAnimationClipsContentEqual, not the hash.

2. Adopt the project's WallMath.Approximately for the clip float comparisons
   and fix cycleOffset. cycleOffset was compared with exact `!=` while its
   sibling settings floats (startTime/stopTime) used tolerant comparison, so
   sub-tolerance float round-trip noise on cycleOffset was spuriously flagged
   as a change. Switched all 14 float comparisons (frameRate, length,
   cycleOffset, start/stop time, event time/float, keyframe
   time/value/tangents/weights, objref keyframe time) to
   `x.Approximately(y, ContentEqualityTolerance)`. Tolerance is 0f so WallMath
   falls back to its built-in relative fudge (~1e-6 * magnitude) -- behavior-
   equivalent to the prior Mathf.Approximately (verified) and tight enough to
   catch real edits; the default 0.045f would mask real animation changes and
   skip a needed re-copy.

Red-green: added SubToleranceCycleOffsetDifferenceIsTreatedAsEqual (RED under
exact `!=`, GREEN after). Full pure fixture 46/46 via Unity TestRunnerApi.
Adversarially reviewed: behavior-equivalence brute-force-checked, dead-code
removal confirmed reader-free, AreObjectReferencesEqual filename comparison left
as-is (verbatim-copy workflow references identical assets, so it is inert).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread .githooks/pre-push Outdated
Comment thread .github/actions/verify-unity-results/action.yml
try {
Start-Transcript -Path $logPath -Force | Out-Null
. $script
$unityVersions = @('2021.3.45f1', '2022.3.45f1', '6000.3.16f1')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bootstrap pins stale Unity versions

Medium Severity

The runner-bootstrap workflow hardcodes Unity version strings inline while CI matrix jobs read .github/unity-versions.json, so bumping the canonical JSON alone leaves bootstrap maintaining or auditing the wrong editor versions.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0115eb6. Configure here.

Comment thread .github/workflows/unity-benchmarks.yml
Comment thread .githooks/pre-push Outdated
# This is the ONLY place UH_RANDOM_SAMPLE_COUNT is consumed.
- name: Run Random suite at full sample count
id: run_random_thorough
if: ${{ matrix.test-mode == 'editmode' && steps.compute.outputs.is-empty != 'true' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Random suite runs after failure

Medium Severity

On editmode benchmark legs, Run Random suite at full sample count only gates on editmode and a non-empty assembly list, not on run_tests succeeding. After the perf run fails, CI can still launch the long full-sample Random Unity run under the same org lock.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b332709. Configure here.

with:
results-dir: .artifacts/unity/benchmarks/${{ matrix.unity-version }}-${{ matrix.test-mode }}
label: Benchmarks ${{ matrix.unity-version }} ${{ matrix.test-mode }}
expected-empty: ${{ steps.compute.outputs.is-empty }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Random benchmark leg unverified

Medium Severity

The new edit-mode Run Random suite at full sample count step writes results under .artifacts/unity/benchmarks-random/, but Verify tests actually ran only checks .artifacts/unity/benchmarks/${{ matrix.unity-version }}-${{ matrix.test-mode }}. A broken or empty Random run can pass CI while the perf-category leg still verifies.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9ca9cf1. Configure here.

Comment thread .githooks/pre-push Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 5 total unresolved issues (including 4 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fe4b841. Configure here.

Comment thread .githooks/post-rewrite
rm -f "$CACHE_FILE"
echo "License year cache invalidated (history rewritten)."
if [ ! -f "$hook_script" ] || ! command -v pwsh >/dev/null 2>&1; then
exit 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

post-rewrite skips cache clear

Medium Severity

The post-rewrite shell wrapper exits successfully when post-rewrite.ps1 is missing or pwsh is not on PATH, so the license year cache is never removed after a history rewrite. The previous hook cleared that cache directly in shell on every successful run.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fe4b841. Configure here.

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.

2 participants