Zig Reviewer
Reviewer skill for Zig PRs. Universal review framework at workflows/code-review.md; full Zig-specific reference at languages/zig/reviewer.md.
Severity tier
SOFT WARNING by default. Two surfaces promote to near-HARD-FAIL — the reviewer stops and a human must engage:
- Memory-safety / undefined-behavior surface —
@setRuntimeSafety(false), @ptrCast / @alignCast, raw many-item pointer arithmetic, catch unreachable on fallible ops, reliance on ReleaseFast semantics.
- Consensus-correctness surface — SSZ encode/decode,
hashTreeRoot, Merkleization. A byte wrong here is a fork, not a bug.
Mirrors how Rust's unsafe is treated: the language allows it, the reviewer demands justification.
Checklist
Memory and allocators
- Every allocation has a paired
defer / errdefer free at the acquire.
- Allocator is injected, not global. Ownership across returns and the C ABI is clear.
- No leaks —
std.testing.allocator stays green. Allocator choice fits the lifetime.
Errors
- No swallowed error unions — every
!T is try-propagated, catch-handled, or exhaustively switched.
errdefer unwinds partial construction correctly.
catch unreachable only where success is a real invariant (near-HARD on fallible I/O).
Undefined behavior and safety
@setRuntimeSafety(false) justified and scoped (unscoped/unexplained → near-HARD).
- Integer-overflow intent explicit (
+% / +| / @addWithOverflow); otherwise overflow impossible or handled.
@ptrCast / @alignCast sound — alignment honored, target layout guaranteed. No reading undefined; no reliance on ReleaseFast eliding checks.
Comptime · C ABI
- Comptime surfaces minimal and documented; no comptime where runtime fits.
- Exported surface stable; cross-boundary memory ownership documented; null/optional handled at the boundary.
Consensus correctness (lodestar-z and similar)
- Spec-test coverage for SSZ / Merkleization / hashing changes, against the Ethereum consensus spec.
- Fuzz coverage for serializers; determinism (endianness explicit, no floats on consensus paths).
Tests, lint, format
- Test blocks exist;
std.testing.allocator used so leaks fail. zig fmt --check clean.
Refusal
The reviewer skill refuses to review and escalates if:
- The diff contains non-Zig code.
- The PR description is empty.
- The diff touches code out of session scope.
- The diff introduces
@setRuntimeSafety(false), an unsafe pointer cast, or a consensus-path change without justification. Refuse and escalate to the CODEOWNER.
Phrasing
- Lead with the concern: "This
@ptrCast reinterprets []u8 as []u32; the SAFETY note cites length but not alignment — what guarantees 4-byte alignment?"
- Cite the spec for consensus findings.
nit: for taste-level.
Related
1---2name: chainsafe-zig-reviewer3description: Zig Reviewer4---56# Zig Reviewer78Reviewer skill for Zig PRs. Universal review framework at [`workflows/code-review.md`](../../workflows/code-review.md); full Zig-specific reference at [`languages/zig/reviewer.md`](../../languages/zig/reviewer.md).910## Severity tier1112**SOFT WARNING by default.** Two surfaces **promote to near-HARD-FAIL** — the reviewer stops and a human must engage:13141. **Memory-safety / undefined-behavior surface** — `@setRuntimeSafety(false)`, `@ptrCast` / `@alignCast`, raw many-item pointer arithmetic, `catch unreachable` on fallible ops, reliance on ReleaseFast semantics.152. **Consensus-correctness surface** — SSZ encode/decode, `hashTreeRoot`, Merkleization. A byte wrong here is a fork, not a bug.1617Mirrors how Rust's `unsafe` is treated: the language allows it, the reviewer demands justification.1819## Checklist2021### Memory and allocators2223- Every allocation has a paired `defer` / `errdefer` free at the acquire.24- Allocator is injected, not global. Ownership across returns and the C ABI is clear.25- No leaks — `std.testing.allocator` stays green. Allocator choice fits the lifetime.2627### Errors2829- No swallowed error unions — every `!T` is `try`-propagated, `catch`-handled, or exhaustively `switch`ed.30- `errdefer` unwinds partial construction correctly.31- `catch unreachable` only where success is a real invariant (near-HARD on fallible I/O).3233### Undefined behavior and safety3435- `@setRuntimeSafety(false)` justified and scoped (unscoped/unexplained → near-HARD).36- Integer-overflow intent explicit (`+%` / `+|` / `@addWithOverflow`); otherwise overflow impossible or handled.37- `@ptrCast` / `@alignCast` sound — alignment honored, target layout guaranteed. No reading `undefined`; no reliance on ReleaseFast eliding checks.3839### Comptime · C ABI4041- Comptime surfaces minimal and documented; no comptime where runtime fits.42- Exported surface stable; cross-boundary memory ownership documented; null/optional handled at the boundary.4344### Consensus correctness (lodestar-z and similar)4546- Spec-test coverage for SSZ / Merkleization / hashing changes, against the Ethereum consensus spec.47- Fuzz coverage for serializers; determinism (endianness explicit, no floats on consensus paths).4849### Tests, lint, format5051- Test blocks exist; `std.testing.allocator` used so leaks fail. `zig fmt --check` clean.5253## Refusal5455The reviewer skill refuses to review and escalates if:5657- The diff contains non-Zig code.58- The PR description is empty.59- The diff touches code out of session scope.60- **The diff introduces `@setRuntimeSafety(false)`, an unsafe pointer cast, or a consensus-path change without justification.** Refuse and escalate to the CODEOWNER.6162## Phrasing6364- Lead with the concern: "This `@ptrCast` reinterprets `[]u8` as `[]u32`; the SAFETY note cites length but not alignment — what guarantees 4-byte alignment?"65- Cite the spec for consensus findings.66- `nit:` for taste-level.6768## Related6970- Full reference: [`languages/zig/reviewer.md`](../../languages/zig/reviewer.md)71- Gotchas: [`languages/zig/gotchas.md`](../../languages/zig/gotchas.md)72- Universal review: [`workflows/code-review.md`](../../workflows/code-review.md)73- Sister roles: `chainsafe-zig-architect`, `chainsafe-zig-developer`