gemini-code-assist flagged 4 places on PR #235 where `scene_manifest.zig` performs multiple hash lookups + a full key iteration when a single-pass over the keys would do. Pure code quality cleanup — no correctness implication, current behavior is right, just iterated more than needed.
Sites
- `hasFlatEntityShapeKey` (line ~283): up to 4 `obj.get` calls + a full key iteration. Single pass can do both checks.
- `isBundleHeader` (line ~297): similar pattern with `hasFlatPascalCaseKey` + 2 explicit `obj.get` calls.
- `validateRootBlock` hybrid check (line ~432): could call a shared `checkHybridForm(obj)` that returns the conflicting key name.
- `validateChildrenArrayDepth` hybrid check (line ~504): same — could use the shared helper.
Proposed shape
```zig
/// Returns the conflicting wrapper key name ("overrides" or "components")
/// if both a wrapper and any flat PascalCase key are present at this scope,
/// or null if the shape is internally consistent.
fn checkHybridForm(obj: std.json.ObjectMap) ?[]const u8 { ... }
```
Single iteration over obj.keys(), tracks (has_overrides, has_components, has_pascal); decides at end.
The two call sites at `validateRootBlock` and `validateChildrenArrayDepth` switch to using the helper; `hasFlatEntityShapeKey` / `isBundleHeader` also collapse into single-pass form.
Severity
Medium per gemini, but really code-quality. Scan runs once per build; the redundant iterations don't matter in practice. Worth doing for cleanliness when someone has 30 min.
gemini-code-assist flagged 4 places on PR #235 where `scene_manifest.zig` performs multiple hash lookups + a full key iteration when a single-pass over the keys would do. Pure code quality cleanup — no correctness implication, current behavior is right, just iterated more than needed.
Sites
Proposed shape
```zig
/// Returns the conflicting wrapper key name ("overrides" or "components")
/// if both a wrapper and any flat PascalCase key are present at this scope,
/// or null if the shape is internally consistent.
fn checkHybridForm(obj: std.json.ObjectMap) ?[]const u8 { ... }
```
Single iteration over obj.keys(), tracks (has_overrides, has_components, has_pascal); decides at end.
The two call sites at `validateRootBlock` and `validateChildrenArrayDepth` switch to using the helper; `hasFlatEntityShapeKey` / `isBundleHeader` also collapse into single-pass form.
Severity
Medium per gemini, but really code-quality. Scan runs once per build; the redundant iterations don't matter in practice. Worth doing for cleanliness when someone has 30 min.