diff --git a/.agents/skills/4d-geometry/SKILL.md b/.agents/skills/4d-geometry/SKILL.md new file mode 100644 index 0000000..7b37927 --- /dev/null +++ b/.agents/skills/4d-geometry/SKILL.md @@ -0,0 +1,52 @@ +--- +name: 4d-geometry +description: Build or modify Rust4D primitives and tetrahedral meshes. Use when touching rust4d_math::Mesh4D, primitives, Tesseract4D, ShapeTemplate geometry variants, or any code that creates 4D tetrahedra for slicing. +--- + +# 4D Geometry Workflow + +Rust4D renders **3D slices of 4D boundary meshes**. The renderer wants a closed +3-manifold embedded in 4D, decomposed into tetrahedra. If a primitive is not +structurally watertight, the GPU will show cracks, T-junctions, missing faces, +or interior membranes when sliced. + +## Mandatory checks for every primitive + +1. Construct as `Mesh4D` where possible. +2. Run `mesh.validate()` — catches out-of-bounds and repeated cell indices. +3. Run `mesh.is_watertight()` — every triangular face must be shared by exactly + two tetrahedra. +4. Pin expected cell counts in tests. +5. Pin total boundary 3-volume using `mesh.surface_volume()`: + - exact for regular polytopes, + - convergent-from-below for curved approximations. +6. Render with `cargo run --example shape_showcase .scratchpad/captures-gallery` + and inspect captures. + +## Seam rule + +For composite curved shapes, shared vertices must share **global indices before +splitting prisms**. Use the `VertexPool` pattern from `primitives/curved.rs`. +Do not rely on post-hoc welding to fix seams: welding after splitting does not +fix mismatched quad diagonals. + +Use `primitives::extrude::split_prism`, which applies the Dompierre +lowest-global-index rule so neighboring prisms choose the same diagonals on +shared quad faces. + +## Tesseract warning + +The tesseract must emit only its 48 boundary tetrahedra. The old 84-tet Kuhn +surface included 36 internal membranes, wasting slice work and rendering +spurious interior walls. Any future tesseract edit must keep: + +```rust +assert_eq!(Tesseract4D::new(2.0).tetrahedra().len(), 48); +assert!(Mesh4D::from(&tess as &dyn ConvexShape4D).is_watertight()); +``` + +## Related docs + +- `docs/4d-math.md` — slicing and matrix conventions +- `docs/shapes.md` — shape catalog (when updated) +- `.agents/skills/headless-visual-verification` — GPU capture workflow diff --git a/.agents/skills/headless-visual-verification/SKILL.md b/.agents/skills/headless-visual-verification/SKILL.md new file mode 100644 index 0000000..2637fc0 --- /dev/null +++ b/.agents/skills/headless-visual-verification/SKILL.md @@ -0,0 +1,57 @@ +--- +name: headless-visual-verification +description: Run autonomous visual checks for Rust4D rendering changes. Use after touching WGSL shaders, RenderUniforms, camera projection, slice pipeline, primitives, or examples that affect rendering. +--- + +# Headless Visual Verification + +Willow does not do manual rendering checks for this project. If a change affects +visual output, verify it yourself with offscreen GPU captures. + +## Slice invariant protocol + +Use for camera/movement/physics/slice correctness: + +```bash +nix develop --command cargo run --example headless_protocol .scratchpad/captures +``` + +Read the `[STATE] slice_w(...)` logs. During WASD phases, slice W must remain +constant. Convert frames with ImageMagick if needed. + +## Primitive showcase protocol + +Use for geometry, shader, material, and lighting work: + +```bash +nix develop --command cargo run --example shape_showcase .scratchpad/captures-gallery +``` + +Expected: +- 81 captures (9 primitives × 3 slice offsets × 3 orientations) +- zero zero-triangle captures +- no cracks/T-junctions/hairline seams +- central slices of every primitive visibly distinct + +Make a quick contact sheet: + +```bash +mkdir -p .scratchpad/captures-gallery/png +for f in .scratchpad/captures-gallery/*_mid_identity.ppm; do + magick "$f" ".scratchpad/captures-gallery/png/$(basename "${f%.ppm}").png" +done +magick .scratchpad/captures-gallery/png/tesseract_mid_identity.png \ + .scratchpad/captures-gallery/png/hypersphere_mid_identity.png \ + .scratchpad/captures-gallery/png/pentachoron_mid_identity.png +append row1.png +# Repeat rows, then `magick row1.png row2.png row3.png -append contact-sheet.png` +``` + +Use `+append`/`-append`; ImageMagick `montage` may need fonts unavailable in +the nix shell. + +## GPU warning + +The current wgpu/naga stack may emit Vulkan validation warning +`VUID-StandaloneSpirv-MemorySemantics-10871` for `OpAtomicIAdd` relaxed +semantics. This is harmless for now and tracked as a wgpu upgrade backlog item. +Do not confuse it with a rendering failure. diff --git a/.agents/skills/production-readiness/SKILL.md b/.agents/skills/production-readiness/SKILL.md new file mode 100644 index 0000000..97002df --- /dev/null +++ b/.agents/skills/production-readiness/SKILL.md @@ -0,0 +1,59 @@ +--- +name: production-readiness +description: Final quality gate for Rust4D feature branches. Use before PRs, releases, or after broad engine changes. Covers formatting, tests, clippy, rustdoc, visual captures, docs, and scratchpad handoff. +--- + +# Production Readiness Gate + +Run this before opening a PR or calling a feature branch done. + +## Code gate + +```bash +nix develop --command cargo fmt --all -- --check +nix develop --command cargo clippy --workspace --all-targets -- -D warnings +nix develop --command bash -c 'RUSTDOCFLAGS=-Dwarnings cargo doc --workspace --no-deps' +nix develop --command cargo test --workspace +nix develop --command cargo test --test slice_invariant +``` + +No warnings. No ignored failures unless already documented. + +## Visual gate + +For rendering-affecting work: + +```bash +nix develop --command cargo run --example shape_showcase .scratchpad/captures-gallery +nix develop --command cargo run --example headless_protocol .scratchpad/captures +``` + +Inspect at least one contact sheet or representative PNGs. Do not ask Willow to +verify visually. + +## Docs gate + +- README feature list updated +- `docs/README.md` links any new doc +- `docs/developer-guide.md` updated for workflows/architecture changes +- `docs/4d-math.md` updated for math/convention changes +- `docs/shapes.md` updated for primitive changes +- `.agents/skills/*` updated if a workflow changed +- Rustdoc has no broken intra-doc links (`RUSTDOCFLAGS=-Dwarnings` catches this) + +## Scratchpad gate + +- Update the active plan with completed waves and next steps +- Update `scratchpad/board.md` with correct `# ` column names +- Write a short report if ending a substantial session +- Commit and push scratchpad separately from repo code + +## PR gate + +PR body should include: +- Summary +- Why it matters / root cause if a fix +- Verification commands and visual evidence +- Known follow-ups + +Mention exact test counts and capture counts where relevant. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ccd08dd --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,54 @@ +name: CI + +on: + push: + branches: [main, feature/**] + pull_request: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + RUSTFLAGS: -Dwarnings + RUSTDOCFLAGS: -Dwarnings + +jobs: + test: + name: clippy, docs, tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + libasound2-dev \ + libudev-dev \ + pkg-config \ + libwayland-dev \ + libxkbcommon-dev + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + + - name: Cache cargo registry and target + uses: Swatinem/rust-cache@v2 + + - name: Check formatting + run: cargo fmt --all -- --check + + - name: Clippy + run: cargo clippy --workspace --all-targets -- -D warnings + + - name: Documentation + run: cargo doc --workspace --no-deps + + - name: Tests + run: cargo test --workspace