Skip to content

Commit 0b3d790

Browse files
Merge pull request #201 from RtlZeroMemory/docs/code-standards
docs(dev): add Rezi code standards and enforcement references
2 parents d838294 + dc1c848 commit 0b3d790

File tree

6 files changed

+181
-3
lines changed

6 files changed

+181
-3
lines changed

AGENTS.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ Rezi is a runtime-agnostic TypeScript TUI framework. Monorepo with `npm` workspa
1818
| `create-rezi` | `packages/create-rezi/` | Project scaffolding CLI |
1919
| `@rezi-ui/bench` | `packages/bench/` | Benchmark suite |
2020

21+
## Mandatory Code Standards
22+
23+
All code changes MUST comply with `docs/dev/code-standards.md`.
24+
Treat it as a required merge checklist for:
25+
- TypeScript strictness and API modeling
26+
- Rezi runtime/layout/reconciliation invariants
27+
- Error handling, callback safety, and async cancellation guards
28+
2129
## Exploration Protocol
2230

2331
When investigating Rezi code, follow this order:
@@ -68,9 +76,10 @@ When modifying layout code/docs, assume these features are part of the current c
6876

6977
### Before changing code
7078

71-
1. Read the target file fully.
72-
2. Check existing tests for the module (`__tests__/` directory adjacent to or near the file).
73-
3. Understand where the target sits in the render pipeline.
79+
1. Read `docs/dev/code-standards.md` and apply the relevant MUST rules.
80+
2. Read the target file fully.
81+
3. Check existing tests for the module (`__tests__/` directory adjacent to or near the file).
82+
4. Understand where the target sits in the render pipeline.
7483

7584
### Safe modification zones
7685

@@ -280,6 +289,7 @@ Before finalizing any TUI implementation, verify:
280289
## PR and Commit Protocol
281290

282291
- Run full test suite before commits: `node scripts/run-tests.mjs`
292+
- Verify `docs/dev/code-standards.md` checklist before opening/merging a PR.
283293
- Commit message format: `feat(scope):`, `fix(scope):`, `docs(scope):`, `refactor(scope):`, `test(scope):`
284294
- Keep commits atomic — one logical change per commit.
285295
- Update `CHANGELOG.md` for user-facing changes.

CLAUDE.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ npx tsx packages/bench/src/... # Run benchmarks (bypasses tsc)
1515
REZI_PERF=1 REZI_PERF_DETAIL=1 # Enable profiling (env vars, prefix any command)
1616
```
1717

18+
## Mandatory Code Standards
19+
20+
All code changes MUST follow `docs/dev/code-standards.md`.
21+
Use it as the merge gate for TypeScript rigor, Rezi-specific invariants, and
22+
error-handling patterns.
23+
1824
## Project Map
1925

2026
```
@@ -282,6 +288,7 @@ each(items, (item) => ui.text(item.name), { key: (item) => item.id });
282288

283289
## Code Standards and Guardrails
284290

291+
- Canonical standards document: `docs/dev/code-standards.md` (MUST follow).
285292
- All interactive widgets MUST have a unique `id` prop.
286293
- Hooks must be called in consistent order (no conditional hooks, no hooks in loops).
287294
- Container transition properties (`ui.box`/`ui.row`/`ui.column`/`ui.grid`) default to animating `position`, `size`, and `opacity`; constrain with explicit `properties` when needed.

docs/dev/code-standards.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Code Standards
2+
3+
This document defines mandatory code standards for Rezi contributors and AI agents.
4+
Treat this as a normative checklist for code review and PR readiness.
5+
6+
See also:
7+
- [Style Guide](style-guide.md)
8+
- [Contributing](contributing.md)
9+
10+
## Enforcement Levels
11+
12+
- `MUST`: required for merge.
13+
- `SHOULD`: expected unless there is a clear, documented reason not to.
14+
15+
## 1) Baseline Checks (MUST)
16+
17+
For any code change:
18+
19+
```bash
20+
npm run lint
21+
npm run typecheck
22+
```
23+
24+
For runtime/layout/renderer/reconcile changes, also run:
25+
26+
```bash
27+
node scripts/run-tests.mjs
28+
```
29+
30+
For drawlist protocol or command layout changes, also run:
31+
32+
```bash
33+
npm run codegen
34+
npm run codegen:check
35+
```
36+
37+
## 2) TypeScript Standards
38+
39+
### Type safety
40+
41+
- `MUST` preserve strict typing (`strict`, `noImplicitAny`, `useUnknownInCatchVariables`).
42+
- `MUST NOT` introduce `any` unless there is no safe alternative.
43+
- `MUST` narrow `unknown` before property access.
44+
- `MUST` prefer `import type { ... }` for type-only imports.
45+
46+
### Public API and domain modeling
47+
48+
- `MUST` model variants with discriminated unions (tagged unions), not class hierarchies.
49+
- `MUST` keep exported API shapes explicit and stable.
50+
- `SHOULD` use explicit return types on exported functions.
51+
52+
### Nullability and indexing
53+
54+
- `MUST` handle `undefined` from array/index lookups explicitly (`noUncheckedIndexedAccess`).
55+
- `MUST NOT` use non-null assertion (`!`) unless the invariant is proven in the same scope.
56+
57+
### Immutability and determinism
58+
59+
- `SHOULD` prefer readonly shapes (`Readonly`, readonly arrays) for shared data.
60+
- `MUST` avoid hidden mutation of shared objects in render/layout paths.
61+
62+
## 3) Rezi-Specific Architecture Standards
63+
64+
### Runtime boundaries
65+
66+
- `MUST NOT` import runtime-specific APIs into `@rezi-ui/core`.
67+
- `MUST` keep module boundaries intact:
68+
- `core` -> no imports from `node`/`jsx`/`native`
69+
- `node`/`jsx` -> may import from `core`
70+
71+
### Widget and reconciliation rules
72+
73+
- `MUST` use stable `id` for interactive widgets.
74+
- `MUST` use stable `key` values for list reconciliation.
75+
- `MUST` keep hook invocation order stable (no conditional hooks).
76+
- `MUST` preserve deterministic behavior for the same input state.
77+
78+
### API layering
79+
80+
- `SHOULD` prefer `ui.*` factories over raw vnode construction.
81+
- `MUST` keep JSX parity when changing core widget APIs (`ui.ts`, JSX components/types/tests/docs together).
82+
83+
### Generated code and protocol
84+
85+
- `MUST NOT` hand-edit generated drawlist writers.
86+
- `MUST` update source spec + regenerate writers + update protocol docs when command bytes/layout changes.
87+
88+
## 4) Error Handling Standards (Critical)
89+
90+
### Choose the right failure contract
91+
92+
- `MUST` use typed result unions for parse/validation-style flows where callers should recover.
93+
- `MUST` throw for unrecoverable programmer/configuration errors.
94+
- `MUST` keep error contracts consistent within each module.
95+
96+
### Catch blocks and thrown values
97+
98+
- `MUST` treat caught values as `unknown`.
99+
- `MUST` use safe thrown-value formatting in logs/warnings.
100+
- `MUST NOT` call `String(error)` directly in safety-critical catch blocks without a nested guard.
101+
102+
Recommended pattern:
103+
104+
```ts
105+
function describeThrown(value: unknown): string {
106+
if (value instanceof Error) return `${value.name}: ${value.message}`;
107+
try {
108+
return String(value);
109+
} catch {
110+
return "[unstringifiable thrown value]";
111+
}
112+
}
113+
```
114+
115+
### Callback boundaries
116+
117+
- `MUST` isolate user callback failures so they do not destabilize routing/render loops.
118+
- `MUST` keep callback wrappers deterministic and side-effect safe.
119+
- `SHOULD` emit dev warnings (`warnDev`) instead of throwing for user callback exceptions in routing/event handlers.
120+
121+
### Async cancellation and stale results
122+
123+
- `MUST` guard async completion paths against cancellation/stale-token updates.
124+
- `MUST` ensure canceled validations/effects cannot mutate state after cleanup/unmount.
125+
126+
### Error wrapping
127+
128+
- `SHOULD` preserve original errors via `cause` when wrapping.
129+
- `MUST` keep wrapped messages actionable and specific.
130+
131+
## 5) Performance and Hot-Path Standards
132+
133+
- `MUST` avoid unnecessary allocations in per-frame render/layout paths.
134+
- `SHOULD` use simple loops in hot paths instead of allocation-heavy array pipelines.
135+
- `MUST` preserve existing deterministic ordering and stable signatures where applicable.
136+
137+
## 6) Documentation and Parity Standards
138+
139+
- `MUST` update docs in the same PR when changing public behavior.
140+
- `MUST` update examples/templates when recommended patterns change.
141+
- `MUST` keep `CLAUDE.md` and `AGENTS.md` aligned with these standards.
142+
143+
## 7) PR Checklist
144+
145+
Before merging, verify:
146+
147+
- [ ] `lint` and `typecheck` are green.
148+
- [ ] Required tests for touched areas are green.
149+
- [ ] Error paths and cancellation/stale guards are covered where relevant.
150+
- [ ] Module boundaries and JSX parity are preserved.
151+
- [ ] Public API/documentation updates are included.
152+

docs/dev/contributing.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
Rezi welcomes issues and pull requests. This page summarizes the local workflow; see the linked guides for details.
44

5+
Before starting implementation, review the mandatory
6+
[Code Standards](code-standards.md) checklist.
7+
58
## Prerequisites
69

710
- Node.js 18+ (18.18+ recommended)
@@ -62,4 +65,5 @@ If your change touches code-editor syntax behavior (`syntaxLanguage`, tokenizer
6265
- [Build](build.md)
6366
- [Testing](testing.md)
6467
- [Docs](docs.md)
68+
- [Code Standards](code-standards.md)
6569
- [Style guide](style-guide.md)

docs/dev/style-guide.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
This page documents the coding conventions and tooling standards used across the
44
Rezi codebase.
55

6+
For mandatory merge-gate rules, start with
7+
[Code Standards](code-standards.md). This page provides supporting details and
8+
examples.
9+
610
## Formatting and Linting
711

812
Rezi uses [Biome](https://biomejs.dev/) (v1.9.4) for both formatting and

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ nav:
249249
- Repo Layout: dev/repo-layout.md
250250
- Build: dev/build.md
251251
- Testing: dev/testing.md
252+
- Code Standards: dev/code-standards.md
252253
- Perf Regressions: dev/perf-regressions.md
253254
- Repro Replay: dev/repro-replay.md
254255
- Releasing: dev/releasing.md

0 commit comments

Comments
 (0)