52 lines
3.6 KiB
Markdown
52 lines
3.6 KiB
Markdown
# Project Conventions — reikhelm
|
||
|
||
Ground truth every dispatched agent reads. Plan lives at `.dev/2026-05-28-procgen-map-core/`.
|
||
|
||
## Toolchain & environment (CRITICAL)
|
||
|
||
- Rust **1.96.0** stable, `aarch64-apple-darwin`, via rustup.
|
||
- **`~/.cargo/bin` is NOT on the non-interactive shell PATH.** Every shell command that runs `cargo`, `rustc`, or `rustup` MUST first export it:
|
||
```sh
|
||
export PATH="$HOME/.cargo/bin:$PATH"
|
||
```
|
||
Put this at the front of the same Bash invocation as your cargo command. If you forget it you'll get `command not found: cargo`.
|
||
- Run all cargo commands from the workspace root `/Users/caspar/Projects/reikhelm`.
|
||
|
||
## Dependency versions (RESOLVED by Task 1)
|
||
|
||
- `rand` **0.10.1**, `rand_chacha` **0.10.0**, `rand_core` **0.10.1**, `serde` **1.0.228** (derive), `macroquad` **0.4.15**.
|
||
- This is the **rand 0.10** line — newer than 0.8/0.9. Verify exact API paths against the compiler: `ChaCha8Rng` implements `SeedableRng` (`seed_from_u64(u64)` / `from_seed([u8;32])`); `rand_core::RngCore` gives `next_u32`/`next_u64`. To minimize exposure to rand's churning trait paths (`SliceRandom`→`IndexedRandom`/`IndexedMutRandom` across 0.8→0.9), prefer building `range`/`chance`/`choose`/`shuffle` directly on `RngCore::next_u64` (e.g. Fisher–Yates shuffle from our own `range`) — also more transparent for determinism. `cargo build` is the arbiter.
|
||
|
||
## Git
|
||
|
||
- Repo is initialized in Task 1; work happens on the **default branch** (no feature branch — greenfield bring-up, explicitly authorized by the session goal).
|
||
- Each task commits with the exact message given in its task file's `## Commit` section.
|
||
- End every commit message body with this trailer (on its own line, preceded by a blank line):
|
||
```
|
||
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
```
|
||
- Commit only the files your task created/modified. Do not commit `/target` (gitignored).
|
||
|
||
## Module wiring ownership
|
||
|
||
- A task that CREATES a module file also appends its own `pub mod <name>;` to the parent (`lib.rs` or `passes/mod.rs` or `recipes/mod.rs`) — EXCEPT the parallel pass batch (Tasks 7–11): for those, the orchestrator pre-wires `passes/mod.rs` and pre-creates empty stub files, so pass implementers ONLY edit their own pass file and never touch `mod.rs`.
|
||
|
||
## Determinism rules (load-bearing — spec §7)
|
||
|
||
- All generation randomness flows through `reikhelm_core::rng::Rng` (ChaCha8). Never `thread_rng`/`rand::random()`.
|
||
- **Never `std::collections::hash_map::DefaultHasher`** for anything that affects generation — it's version-unstable. RNG `fork` uses an explicit integer mix (splitmix64 / FNV-style).
|
||
- No `HashMap`/`HashSet` *iteration order* may influence generated output (use sorted/`BTreeMap` or index order where order matters).
|
||
- Same seed → byte-identical `Map`, every run, every machine.
|
||
|
||
## Rust style
|
||
|
||
- Derive traits rather than hand-impl where possible (`Clone, Copy, Debug, PartialEq, Eq`, serde).
|
||
- Public items get a `///` doc comment. Keep functions small and total — no panics on valid input.
|
||
- Grid writes go through bounds-safe accessors; OOB is a no-op, never a panic (spec §8).
|
||
- Prefer iterators/combinators over index loops where it reads cleanly. This is a learning-Rust project: favor clear, idiomatic code over clever code.
|
||
- Tests live in an inline `#[cfg(test)] mod tests { use super::*; ... }` at the bottom of the module file.
|
||
|
||
## Reporting (for dispatched implementers)
|
||
|
||
End your report with a STATUS line: `DONE`, `DONE_WITH_CORRECTIONS`, `NEEDS_CONTEXT`, or `BLOCKED`.
|
||
Paste the **actual** `cargo test` output (not "tests pass"). List every file you created/modified. If you deviated from the task spec, say why.
|