Skip to content

Commit c83cae3

Browse files
aram-devdocsclaude
andauthored
docs: ENG2 v2 rebuild runbook + perf/test agent rules (#811)
* docs: add ENG2 v2 rebuild runbook, perf/test rules, archive alpha roadmap Adds the authoritative v2 rebuild runbook under docs/src/runbook/ (wired into the mdBook): overview, phase index, per-phase specs (0-9), perf definition of done with named scenes S1-S5/H1, testing strategy (unit/isolation/integration/ E2E/spec + story gallery + determinism/fuzz), Throne sync points, and the roadmap issue template. Grounded in a full-engine audit; tracked by the pinned ENG2 master issue (#810) and 102 phase issues. Archives ALPHA_ROADMAP.md with a header correcting the false "v2 Core Performance COMPLETE" claim (#677/#678/#679 were open at the time). Adds agent rules perf-work.md, render-v2.md, testing-v2.md encoding the v2 perf definition of done, O(visible) render invariants, and spec-first/story testing discipline for future /gh-issue agents; points AGENTS.md at the runbook. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: fix runbook markdown lint + regenerate AI config mirrors Add blank lines around tables (MD058) and backtick-wrap _TYPE_ALIASES (MD037); regenerate .cursor/rules/*.mdc mirrors for the three new .agents/rules files (sync-agent-configs). Fixes the Lint Markdown and Validate AI Config Sync checks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 409a549 commit c83cae3

27 files changed

Lines changed: 1805 additions & 5 deletions

.agents/rules/perf-work.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Performance Work Rules (ENG2)
2+
3+
Applies to any change under `**/rendering/**`, `**/graphics/**`, `**/benches/**`, `scripts/bench-gate.py`, or any issue labeled `area:performance`.
4+
5+
## Definition of done (non-negotiable)
6+
7+
A performance change is done only when BOTH hold:
8+
9+
1. **A named scripted scene hits its numeric target** — S1–S5/H1/cull_scaling from `docs/src/runbook/perf-dod.md`, captured via `scripts/perf-capture` (3-run median on Apple M-series/Metal) or the CI `scripts/bench-gate.py` ratio-gate for CI-runnable benches.
10+
2. **A phase counter attributes the cost.** The relevant GPU/CPU phase timing is non-zero and accounts for the frame.
11+
12+
**A counter that reads zero means the instrumentation is broken, never that the work is free.** GPU cost surfaces at surface-acquire/present, not in a CPU command-record timer — measure it with a real GPU timestamp (QuerySet), do not infer it.
13+
14+
## Rules
15+
16+
- No optimization without a measurement first. Post the before-number, then the after-number, on the issue.
17+
- Never silently cap coverage (top-N, sampling, windowing) to hit a number — `log`/document what was dropped. A scene-windowing workaround is a consumer band-aid, not an engine fix.
18+
- The target is **O(visible), not O(total)**: per-frame CPU cost must not scale with total scene/entity count. If it does, that is the bug, regardless of FPS.
19+
- Steady-state render frame (no scene mutation) must perform **0 heap allocations** in the render path — assert it with the alloc-budget harness (ENG2-P0-15), do not eyeball it.
20+
- Aim for headroom, not the 60 FPS floor: the v2 targets are 120+ FPS for tens of thousands of visible entities.
21+
22+
## Before closing
23+
24+
Run the relevant bench-gate scene, attach the capture (scene, numbers, phase breakdown, delta vs baseline). See `docs/src/runbook/perf-dod.md` for scenes and targets and `[perf-work]``[render-v2]``[testing-v2]` for the companion rules.

.agents/rules/render-v2.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Render Core v2 Rules (ENG2 Phases 2 & 6)
2+
3+
Applies to `**/graphics/**` and the renderer paths. These invariants supersede the performance/submission guidance in `graphics-patterns.md` (the backend-isolation and Renderer-trait rules there still hold). Full design: `docs/src/runbook/phases/phase-2.md` and RFC-0005.
4+
5+
## Submission model
6+
7+
- **O(visible), never O(total).** No per-frame iteration over the entire scene-object set. Cull against a spatial index (grid/BVH) *before* any transform/uniform/encode work. A culled object must pay zero per-frame cost.
8+
- **Dense storage, not hash-map iteration.** Scene objects live in slot arrays with generational handles, iterated contiguously — not a per-frame walk of a `FxHashMap`.
9+
- **Instancing by identity.** Draws are grouped by `(mesh id, material id)` and submitted instanced by default — including `CreatePlane`/`CreateCube`/`CreateSphere`/`CreateCylinder` primitives, not only `InstantiateModel`. A config flag that claims to enable instancing must actually drive the instanced path or not exist.
10+
11+
## Uniforms & buffers
12+
13+
- **Per-frame constants uploaded once** (camera, lights, fog) into one bind group. **Per-object data goes in dynamic-offset slots** — never copy a full multi-KB uniform block per draw, never issue one `write_buffer` per draw. Coalesce writes into one upload per frame.
14+
- **Persistent, dirty-tracked instance/transform buffers.** Upload only changed ranges. Never rebuild the whole buffer, and never CPU-pre-transform vertices into a static VBO that must be re-baked on any change.
15+
- Do not clone per-instance CPU vertex data for instances that share a mesh.
16+
17+
## Data seam
18+
19+
- Transforms are a **structure-of-arrays column shared between ECS and the renderer** (ENG2-P2-13). The renderer consumes dirty ranges from that column; it does not receive per-entity transforms across FFI one at a time.
20+
21+
## Every render/UI/particle change
22+
23+
- Add or update a **story** in the scene gallery (ENG2-P0-14) with a golden image and metric budget — see `[testing-v2]`.
24+
- Meet the perf definition of done — see `[perf-work]` and `docs/src/runbook/perf-dod.md`.
25+
- Raw GPU calls stay in `libs/graphics/backend/` (unchanged boundary).

.agents/rules/testing-v2.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Testing v2 Rules (ENG2)
2+
3+
Applies to all ENG2 work. Full strategy: `docs/src/runbook/testing-strategy.md`. Extends `testing.md` (GL-context and unit conventions there still hold).
4+
5+
## Spec-first (TDD)
6+
7+
- Every behavioral issue gets a spec test at `goud_engine/tests/spec/eng2_p<N>_<nn>_<slug>.rs` encoding its Acceptance Criteria as executable assertions. The spec **is** the gate evidence.
8+
- Write the spec RED before the implementation; make it GREEN; then REFACTOR. A reviewer confirms it was red-before-green.
9+
- The issue's Verification section names the spec path. Do not close an issue whose spec test does not exist or does not assert its acceptance criteria.
10+
11+
## Tiers — put each test at the right level
12+
13+
- **Unit** — pure logic, no GPU. Design v2 render/ECS logic (culling, instancing-grouping, sort-key, propagation) to be unit-testable without a GPU context.
14+
- **Isolation** — one subsystem behind its null/provider boundary (`NullBackend`, null net/audio, in-memory VFS). If the seam to mock a dependency is missing, add the null/mock provider.
15+
- **Integration** — cross-layer in-process; assert exact draw/culled/visible counts (generalize `tests/renderer3d_frame_counts.rs`).
16+
- **E2E** — SDK-driven headless engine (ENG2-P0-17); C#/TS/Python boot a real engine, run a scripted game, assert counts/world-hash/flat-RSS.
17+
18+
## Story gallery
19+
20+
- Every render/UI/particle/animation change adds or updates a **story** (ENG2-P0-14): scene + camera + knobs + expected invariants + golden image. CI renders it headless, diffs the golden, checks metric budgets, and publishes the HTML gallery.
21+
- Changing a golden requires the documented golden-update approval — do not silently overwrite baselines.
22+
23+
## Determinism, property, fuzz
24+
25+
- Sim/scheduling changes run the determinism fixture (3 seeds × 10k ticks, hash-compare). Do not introduce nondeterminism (unordered iteration, wall-clock reads, FP drift).
26+
- Component-store and command-decoder changes add/extend `proptest` + `cargo-fuzz` targets (ENG2-P0-18, P3-09).
27+
28+
## Don't game the gate
29+
30+
Never weaken an assertion, widen a tolerance, or skip a scene to make a gate pass. If a gate is wrong, fix the gate in the same PR with justification.

.cursor/rules/perf-work.mdc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
description: Performance Work Rules (ENG2)
3+
globs:
4+
alwaysApply: true
5+
---
6+
7+
<!-- AUTO-GENERATED by scripts/sync-agent-configs.py. Edit .agents/rules/perf-work.md, then rerun the generator. -->
8+
# Performance Work Rules (ENG2)
9+
10+
Applies to any change under `**/rendering/**`, `**/graphics/**`, `**/benches/**`, `scripts/bench-gate.py`, or any issue labeled `area:performance`.
11+
12+
## Definition of done (non-negotiable)
13+
14+
A performance change is done only when BOTH hold:
15+
16+
1. **A named scripted scene hits its numeric target** — S1–S5/H1/cull_scaling from `docs/src/runbook/perf-dod.md`, captured via `scripts/perf-capture` (3-run median on Apple M-series/Metal) or the CI `scripts/bench-gate.py` ratio-gate for CI-runnable benches.
17+
2. **A phase counter attributes the cost.** The relevant GPU/CPU phase timing is non-zero and accounts for the frame.
18+
19+
**A counter that reads zero means the instrumentation is broken, never that the work is free.** GPU cost surfaces at surface-acquire/present, not in a CPU command-record timer — measure it with a real GPU timestamp (QuerySet), do not infer it.
20+
21+
## Rules
22+
23+
- No optimization without a measurement first. Post the before-number, then the after-number, on the issue.
24+
- Never silently cap coverage (top-N, sampling, windowing) to hit a number — `log`/document what was dropped. A scene-windowing workaround is a consumer band-aid, not an engine fix.
25+
- The target is **O(visible), not O(total)**: per-frame CPU cost must not scale with total scene/entity count. If it does, that is the bug, regardless of FPS.
26+
- Steady-state render frame (no scene mutation) must perform **0 heap allocations** in the render path — assert it with the alloc-budget harness (ENG2-P0-15), do not eyeball it.
27+
- Aim for headroom, not the 60 FPS floor: the v2 targets are 120+ FPS for tens of thousands of visible entities.
28+
29+
## Before closing
30+
31+
Run the relevant bench-gate scene, attach the capture (scene, numbers, phase breakdown, delta vs baseline). See `docs/src/runbook/perf-dod.md` for scenes and targets and `[perf-work]`↔`[render-v2]`↔`[testing-v2]` for the companion rules.

.cursor/rules/render-v2.mdc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
description: Render Core v2 Rules (ENG2 Phases 2 & 6)
3+
globs:
4+
alwaysApply: true
5+
---
6+
7+
<!-- AUTO-GENERATED by scripts/sync-agent-configs.py. Edit .agents/rules/render-v2.md, then rerun the generator. -->
8+
# Render Core v2 Rules (ENG2 Phases 2 & 6)
9+
10+
Applies to `**/graphics/**` and the renderer paths. These invariants supersede the performance/submission guidance in `graphics-patterns.md` (the backend-isolation and Renderer-trait rules there still hold). Full design: `docs/src/runbook/phases/phase-2.md` and RFC-0005.
11+
12+
## Submission model
13+
14+
- **O(visible), never O(total).** No per-frame iteration over the entire scene-object set. Cull against a spatial index (grid/BVH) *before* any transform/uniform/encode work. A culled object must pay zero per-frame cost.
15+
- **Dense storage, not hash-map iteration.** Scene objects live in slot arrays with generational handles, iterated contiguously — not a per-frame walk of a `FxHashMap`.
16+
- **Instancing by identity.** Draws are grouped by `(mesh id, material id)` and submitted instanced by default — including `CreatePlane`/`CreateCube`/`CreateSphere`/`CreateCylinder` primitives, not only `InstantiateModel`. A config flag that claims to enable instancing must actually drive the instanced path or not exist.
17+
18+
## Uniforms & buffers
19+
20+
- **Per-frame constants uploaded once** (camera, lights, fog) into one bind group. **Per-object data goes in dynamic-offset slots** — never copy a full multi-KB uniform block per draw, never issue one `write_buffer` per draw. Coalesce writes into one upload per frame.
21+
- **Persistent, dirty-tracked instance/transform buffers.** Upload only changed ranges. Never rebuild the whole buffer, and never CPU-pre-transform vertices into a static VBO that must be re-baked on any change.
22+
- Do not clone per-instance CPU vertex data for instances that share a mesh.
23+
24+
## Data seam
25+
26+
- Transforms are a **structure-of-arrays column shared between ECS and the renderer** (ENG2-P2-13). The renderer consumes dirty ranges from that column; it does not receive per-entity transforms across FFI one at a time.
27+
28+
## Every render/UI/particle change
29+
30+
- Add or update a **story** in the scene gallery (ENG2-P0-14) with a golden image and metric budget — see `[testing-v2]`.
31+
- Meet the perf definition of done — see `[perf-work]` and `docs/src/runbook/perf-dod.md`.
32+
- Raw GPU calls stay in `libs/graphics/backend/` (unchanged boundary).

.cursor/rules/testing-v2.mdc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
description: Testing v2 Rules (ENG2)
3+
globs:
4+
alwaysApply: true
5+
---
6+
7+
<!-- AUTO-GENERATED by scripts/sync-agent-configs.py. Edit .agents/rules/testing-v2.md, then rerun the generator. -->
8+
# Testing v2 Rules (ENG2)
9+
10+
Applies to all ENG2 work. Full strategy: `docs/src/runbook/testing-strategy.md`. Extends `testing.md` (GL-context and unit conventions there still hold).
11+
12+
## Spec-first (TDD)
13+
14+
- Every behavioral issue gets a spec test at `goud_engine/tests/spec/eng2_p<N>_<nn>_<slug>.rs` encoding its Acceptance Criteria as executable assertions. The spec **is** the gate evidence.
15+
- Write the spec RED before the implementation; make it GREEN; then REFACTOR. A reviewer confirms it was red-before-green.
16+
- The issue's Verification section names the spec path. Do not close an issue whose spec test does not exist or does not assert its acceptance criteria.
17+
18+
## Tiers — put each test at the right level
19+
20+
- **Unit** — pure logic, no GPU. Design v2 render/ECS logic (culling, instancing-grouping, sort-key, propagation) to be unit-testable without a GPU context.
21+
- **Isolation** — one subsystem behind its null/provider boundary (`NullBackend`, null net/audio, in-memory VFS). If the seam to mock a dependency is missing, add the null/mock provider.
22+
- **Integration** — cross-layer in-process; assert exact draw/culled/visible counts (generalize `tests/renderer3d_frame_counts.rs`).
23+
- **E2E** — SDK-driven headless engine (ENG2-P0-17); C#/TS/Python boot a real engine, run a scripted game, assert counts/world-hash/flat-RSS.
24+
25+
## Story gallery
26+
27+
- Every render/UI/particle/animation change adds or updates a **story** (ENG2-P0-14): scene + camera + knobs + expected invariants + golden image. CI renders it headless, diffs the golden, checks metric budgets, and publishes the HTML gallery.
28+
- Changing a golden requires the documented golden-update approval — do not silently overwrite baselines.
29+
30+
## Determinism, property, fuzz
31+
32+
- Sim/scheduling changes run the determinism fixture (3 seeds × 10k ticks, hash-compare). Do not introduce nondeterminism (unordered iteration, wall-clock reads, FP drift).
33+
- Component-store and command-decoder changes add/extend `proptest` + `cargo-fuzz` targets (ENG2-P0-18, P3-09).
34+
35+
## Don't game the gate
36+
37+
Never weaken an assertion, widen a tolerance, or skip a scene to make a gate pass. If a gate is wrong, fix the gate in the same PR with justification.

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Source of truth: `.agents/agent-catalog.toml` and `.agents/role-specs/*.md`.
4747

4848
## Rules
4949

50-
Read only rules matching your change area: `.agents/rules/*.md`.
50+
Read only rules matching your change area: `.agents/rules/*.md`. Active roadmap: v2 rebuild ("ENG2") — `docs/src/runbook/` + pinned master issue #810 (perf/render/test rules: `perf-work.md`, `render-v2.md`, `testing-v2.md`).
5151

5252
## Local AGENTS Files
5353

ALPHA_ROADMAP.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
# GoudEngine Alpha Roadmap
2-
3-
## Completion Status
1+
# GoudEngine Alpha Roadmap (ARCHIVED)
2+
3+
> **ARCHIVED — DO NOT USE FOR PLANNING.** This is the historical alpha (v1) roadmap.
4+
> Its status claims are unreliable: the "Phase 0 (v2): Core Performance — COMPLETE"
5+
> line below was false when written — #677, #678, and #679 were open priority:high
6+
> perf bugs at the time, and the v2 perf gate (60 fps @ 10k entities) was never
7+
> validated against a consumer-scale scene.
8+
>
9+
> **The current roadmap is the v2 Rebuild Runbook: `docs/src/runbook/phase-index.md`
10+
> and the pinned master tracking issue (ENG2 #810).** Historical body preserved below.
11+
12+
## Completion Status (v1 — historical)
413
- [x] Phase 0 (v1): Foundation -- COMPLETE
514
- [x] Phase 1 (v1): Core Stabilization -- COMPLETE
615
- [x] Phase 2 (v1): Core Systems -- COMPLETE
716
- [x] Phase 2.5 (v1): AI Debugger & Runtime Observability -- COMPLETE
817
- [x] Phase 3 (v1): Rendering Pipeline + SDK Expansion -- COMPLETE
9-
- [x] Phase 0 (v2): Core Performance (GoudEngine side) -- COMPLETE
18+
- [ ] Phase 0 (v2): Core Performance -- SUPERSEDED by ENG2 (was falsely marked COMPLETE)
1019

1120
## Vision
1221

docs/src/SUMMARY.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@
2626
- [Governance and Enforcement](development/governance.md)
2727
- [Performance Roadmap](development/performance-roadmap.md)
2828

29+
# v2 Rebuild Runbook (ENG2)
30+
31+
- [Runbook Overview](runbook/index.md)
32+
- [Phase Index](runbook/phase-index.md)
33+
- [Perf Definition of Done](runbook/perf-dod.md)
34+
- [Testing Strategy](runbook/testing-strategy.md)
35+
- [Throne Sync](runbook/throne-sync.md)
36+
- [Roadmap Issue Template](runbook/issue-template.md)
37+
- [Phase Specs (full)](runbook/phase-specs.md)
38+
- [Phase Specs — Perf/Test Expansion](runbook/phase-specs-expansion.md)
39+
- [Phase 0: Instrumentation, Truth & Test Foundation](runbook/phases/phase-0.md)
40+
- [Phase 1: SDK Single Source of Truth](runbook/phases/phase-1.md)
41+
- [Phase 2: Render Core v2](runbook/phases/phase-2.md)
42+
- [Phase 3: Data Core v2](runbook/phases/phase-3.md)
43+
- [Phase 4: FFI v2 Convergence](runbook/phases/phase-4.md)
44+
- [Phase 5: Parallelism & Determinism](runbook/phases/phase-5.md)
45+
- [Phase 6: 2D Render v2](runbook/phases/phase-6.md)
46+
- [Phase 7: Runtime Services](runbook/phases/phase-7.md)
47+
- [Phase 8: Capability Gaps](runbook/phases/phase-8.md)
48+
- [Phase 9: Authoring & Release](runbook/phases/phase-9.md)
49+
2950
# Architecture
3051

3152
- [SDK-First Architecture](architecture/sdk-first.md)

0 commit comments

Comments
 (0)