Skip to content

Commit 668704d

Browse files
authored
Merge pull request #9441 from decentraland/release/2026-07-20
release: 2026-07-20
2 parents 330a4af + 89f53c0 commit 668704d

390 files changed

Lines changed: 11447 additions & 1723 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/skills/code-standards/SKILL.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ user-invocable: false
2727
| Events | Past tense, no `On` prefix | `ViewShowingComplete` |
2828
| Unused parameters | `_`, `__`, `___` | `Update(float _)` |
2929

30+
**Exception:** serialized JSON DTO fields keep their wire-format casing — see *Serialized JSON DTOs* below.
31+
32+
**Namespaces are domain names, not folder paths** — never suppress a folder-namespace mismatch with `// ReSharper disable once CheckNamespace`; fix the namespace or leave the warning visible. Full rule: `docs/code-style-guidelines.md` § Namespaces.
33+
3034
## Member Ordering
3135

3236
Within a class, group members in this order:
@@ -131,7 +135,17 @@ The project is migrating to nullable reference types. ~80 of ~153 assemblies alr
131135
- **Parameters that legitimately accept null** must be typed `T?` (e.g., `string? name`).
132136
- **Return types that may return null** must be typed `T?`.
133137
- **Fields and properties that can be null** must be typed `T?`.
134-
- **Never use the null-forgiving operator `!`** to silence warnings — fix the root cause instead. The only acceptable use is in test code where NSubstitute returns null proxies.
138+
- **Never use the null-forgiving operator `!`** to silence warnings — fix the root cause instead. The only acceptable uses are test code where NSubstitute returns null proxies, and schema-required serialized DTO fields (see below).
139+
140+
## Serialized JSON DTOs (wire-format exceptions)
141+
142+
Deserialized DTO fields follow the wire format, not local conventions:
143+
144+
- **Naming:** field names keep the JSON key casing — suppress per file with `// ReSharper disable InconsistentNaming` above the namespace declaration.
145+
- **Nullability (CS8618):** schema-*required* fields are initialized `= null!` (`= default!` when the field's type is a generic parameter); schema-*optional* fields are declared `T?`. The DTO class must carry a schema-link comment (e.g. `// Server schema: <repo>/<file>#/SchemaName`).
146+
- **Guards follow the declaration:** never null-guard a `null!` field (see anti-pattern 4); an optional `T?` field keeps its guards.
147+
148+
These exceptions apply **only** to deserialized DTO fields — never to locals, return types, or non-DTO code. Authoritative rules, edge cases (strengthened contracts, fields absent from the schema), and the reference example: [`docs/code-style-guidelines.md` § Serialized JSON DTOs](../../../docs/code-style-guidelines.md#serialized-json-dtos-wire-format-exceptions).
135149

136150
## Comments
137151

.github/prompts/review-instructions.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# PR REVIEW PROTOCOL
22

3-
You are the single automated reviewer for this PR. Execute STEP 1 → STEP 9 below **in order, as one pass**, and record each step's required output in your summary comment before moving on. The ordering is the method, not a suggestion — a line is not worth fixing if Steps 2–3 show the change is built in the wrong place. Steps differ in the context they need: Step 3 reads the surrounding files from Step 1; Steps 4–5 work only from the diff. The four lines in STEP 9 are the single verdict downstream automation parses — emit them exactly.
3+
You are the single automated reviewer for this PR. Execute STEP 1 → STEP 9 below **in order, as one pass**, and record each step's required output in your review body before moving on. The ordering is the method, not a suggestion — a line is not worth fixing if Steps 2–3 show the change is built in the wrong place. Steps differ in the context they need: Step 3 reads the surrounding files from Step 1; Steps 4–5 work only from the diff. The four lines in STEP 9 are the single verdict downstream automation parses — emit them exactly.
44

55
Cite the specific rule or doc section (CLAUDE.md, the code-standards skill, `docs/code-style-guidelines.md`, or the relevant subsystem doc) whenever you flag a violation.
66

77
--- STEP 1 — Load context & set scope ---
88
- Read `CLAUDE.md` and `docs/README.md`; load the relevant subsystem doc(s) for the diff.
99
- Get the diff (`gh pr diff`) and the changed-file list.
10-
- The PR head is checked out in the working tree and you have `Read`, `Glob`, and `Grep` (ripgrep) over the whole repo — use them. `Grep` is how you run the repo searches later steps require: lifecycle owners in Step 3, leak-opener mirrors in Step 5. Raw shell is limited to the listed `gh` commands, so search with the `Grep` tool, not `Bash(rg)`/`Bash(grep)`.
10+
- Clone the repo and check out the PR head into a temporary directory (`gh repo clone {owner}/{repo} <tmp-dir> -- --depth 1`, then `gh pr checkout {number}` inside it) so you can read any file in full context. Use ripgrep (`rg`) over that tree for the repo searches later steps require: lifecycle owners in Step 3, leak-opener mirrors in Step 5.
1111
- Don't review the diff in isolation: open the systems, facades, caches, and lifecycle owners it touches, plus the neighbouring files in the same folder. Steps 2–3 judge whether the change is built in the *right place*, which the diff alone can't show.
1212

1313
--- STEP 2 — Root-cause check ---
@@ -56,7 +56,7 @@ Report ONLY issues that require fixes. Make two passes over the changed lines.
5656
4. Performance issues
5757
5. Missing error handling
5858
6. Unclear or problematic logic
59-
7. Resource / subscription leaks — an acquisition without a matching teardown at the corresponding disposal point. Scan for the concrete openers and confirm each has its mirror: `Subscribe(``Unsubscribe`, `AddListener(``RemoveListener`, `+=` on an event/`Action``-=`, a pool `Get(`/`Rent(``Release`/`Return`, `new CancellationTokenSource(``Cancel`+`Dispose`, a `Connect`/room/handle/`IDisposable` open→`Dispose`. Do this with `Grep`: search each changed `*.cs` file for the openers, then grep the same file/type for the matching mirror, and flag any opener whose mirror is missing.
59+
7. Resource / subscription leaks — an acquisition without a matching teardown at the corresponding disposal point. Scan for the concrete openers and confirm each has its mirror: `Subscribe(``Unsubscribe`, `AddListener(``RemoveListener`, `+=` on an event/`Action``-=`, a pool `Get(`/`Rent(``Release`/`Return`, `new CancellationTokenSource(``Cancel`+`Dispose`, a `Connect`/room/handle/`IDisposable` open→`Dispose`. Do this with `rg`: search each changed `*.cs` file for the openers, then grep the same file/type for the matching mirror, and flag any opener whose mirror is missing.
6060
8. Allocated-but-unconsumed infrastructure — buffers, measurements, events, or caches that are populated/written but never read anywhere in the diff or the codebase.
6161
9. Detached async for essential work — `.Forget()` or fire-and-forget `UniTaskVoid` that performs setup the feature depends on. Essential async must be awaited inside the relevant lifecycle, not left detached (CLAUDE.md §9).
6262
10. Nullability-contract violations — assigning `null` or a maybe-null value to a non-nullable declaration, or a defensive null-check against a non-nullable declaration. Both lie about what can be null (CLAUDE.md anti-patterns).
@@ -93,7 +93,7 @@ Report ONLY issues that require fixes. Make two passes over the changed lines.
9393
- Per-frame expense: a GPU/CPU-heavy op (`Blit`, `Render`, allocation) run every frame for a result that changes only on an event — move it to the event.
9494
- RAII for native resources: a native handle (`RenderTexture`, `NativeArray`, `ComputeBuffer`, room/connection, `IDisposable`) whose release is a manual `Release()`/`Dispose()` reachable only on the happy path — an early return or exception leaks it. Prefer `using`, or ownership by a type whose own `Dispose()` frees it, so the release cannot be skipped.
9595

96-
**Reporting (Steps 3–5).** For each issue: Location (file and line), Problem (be specific), Fix (exact change needed), Why (brief impact). Use `mcp__github_inline_comment__create_inline_comment` for specific line issues and `Bash(gh pr comment)` for the top-level summary. Do NOT include praise or subjective style opinions. But a violation of a project standard is NOT a "nice-to-have": naming, magic numbers, member ordering, encapsulation, and resource ownership are required by CLAUDE.md / the code-standards skill / `docs/code-style-guidelines.md`. Report them as blocking and cite the rule — do not soften them into optional suggestions or skip them as nitpicks.
96+
**Reporting (Steps 3–5).** For each issue: Location (file and line), Problem (be specific), Fix (exact change needed), Why (brief impact). Post ONE review via `gh api repos/{owner}/{repo}/pulls/{number}/reviews --method POST` with `"event": "COMMENT"`: the top-level summary goes in the review `body` and each line-level finding goes in the `comments[]` array (with a ```suggestion block per finding). Do not post the summary as a separate issue comment. Do NOT include praise or subjective style opinions. But a violation of a project standard is NOT a "nice-to-have": naming, magic numbers, member ordering, encapsulation, and resource ownership are required by CLAUDE.md / the code-standards skill / `docs/code-style-guidelines.md`. Report them as blocking and cite the rule — do not soften them into optional suggestions or skip them as nitpicks.
9797

9898
--- STEP 6 — Complexity assessment ---
9999
Classify the PR complexity as SIMPLE or COMPLEX.
@@ -144,13 +144,13 @@ QA_REQUIRED: YES when ANY of the following are true:
144144
- Changes asset loading, authentication, or navigation flows
145145

146146
--- STEP 8 — Non-blocking warnings ---
147-
Emit these as warnings in the summary comment. They do NOT cause a FAIL on their own.
147+
Emit these as warnings in the review body. They do NOT cause a FAIL on their own.
148148

149149
- **Main Scene Modified** — If `Explorer/Assets/Scenes/Main.unity` or its `.meta` appears in the changed files:
150150
> ⚠️ **Main scene modified** (`Explorer/Assets/Scenes/Main.unity`). This file is rarely changed intentionally — verify this wasn't pushed by mistake.
151151
152152
--- STEP 9 — Verdict ---
153-
At the very end of your output, emit exactly these four lines (order matters — downstream automation parses them):
153+
Emit exactly these four lines at the end of the review body you post to GitHub, immediately before the attribution line (order matters — downstream automation parses them):
154154
REVIEW_RESULT: PASS ✅ (or FAIL ❌)
155155
COMPLEXITY: SIMPLE (or COMPLEX)
156156
COMPLEXITY_REASON: <one sentence citing which subsystem(s) the diff touches>

.github/scripts/report-review-cost.js

Lines changed: 0 additions & 48 deletions
This file was deleted.

.github/workflows/claude-pr-review-require.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Require Claude Review
1+
name: Require Jarvis Review
22
on:
33
workflow_dispatch:
44
pull_request:
@@ -30,5 +30,5 @@ jobs:
3030
sha: context.payload.pull_request.head.sha,
3131
state: 'pending',
3232
context: 'Claude Review',
33-
description: 'Awaiting Claude review — comment @claude review to trigger'
33+
description: 'Awaiting Jarvis review — auto-requested for team PRs, or request decentraland-bot'
3434
});

0 commit comments

Comments
 (0)