reikhelm/.dev/2026-05-28-procgen-map-core/state/progress.md
Parley Hatch 068df27c7d chore: orchestration bookkeeping through Task 6 (progress, ledger, conventions)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-28 21:22:42 -06:00

49 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Progress Ledger — reikhelm procgen core
Orchestrator's external memory. One entry per task as it completes.
## Environment notes
- Rust 1.96.0 stable. `~/.cargo/bin` NOT on PATH — prepend `export PATH="$HOME/.cargo/bin:$PATH"` in every cargo shell call.
- Resolved dep versions: rand 0.10.1, rand_chacha 0.10.0, rand_core 0.10.1, serde 1.0.228 (derive), macroquad 0.4.15. **rand 0.10 line** — RNG task must target 0.10 API (prefer building helpers on RngCore::next_u64).
## Execution schedule
- Phase 0: Task 1 (scaffold) — direct dispatch, de-risk toolchain/version resolution.
- Phase 1: Tasks 2→3→5 chain + Task 4 (RNG) — core library layer.
- Phase 2: Task 6 (engine) — keystone Pass/Pipeline contract + validator.
- Phase 2.5: orchestrator pre-stubs 5 pass files + wires passes/mod.rs.
- Phase 3: Tasks 711 (passes) — parallel, worktree-isolated; then adversarial verify.
- Phase 4: Task 12 (recipe + integration) — heavy determinism/connectivity verification.
- Phase 5: Task 13 (viz) — build + boundary check.
## Task log
### Task 1 — Workspace scaffold ✅ (commit 08e99e3)
- Two-crate workspace, resolver "2", edition 2021. core deps: rand/rand_chacha/serde(derive); viz deps: macroquad + reikhelm-core (path). `cargo build`+`cargo test` green (0 tests). lib.rs has only crate doc; main.rs plain `fn main()` stub. `.dev/` plan committed into repo root (fine for greenfield). No rendering dep in core ✓.
### Tasks 25 — core library layer ✅ (commits f707bd1, dbfd44a, 6ffe0cc, 659ef00)
Ran as Phase 1 workflow (sequential 2→3→4→5). All 41 tests green, no warnings. Reviewed all source directly.
- **T2 geometry**: Point/Rect/Line + extras (OFFSETS4/8, offset, right/bottom/is_empty, sign). Fixed iteration orders for determinism. Point derives Hash. Line::cells handles diagonal as connected staircase (documented).
- **T3 grid**: bounds-safe Grid<T>, row-major, OOB read=None/write=no-op. iter_rect avoids Rect::iter borrow lifetime. Now also derives PartialEq/Eq (see fix below).
- **T4 rng**: ChaCha8 wrapper. `fork` mix = splitmix64(basis) → FNV-1a over label bytes → splitmix64 finalizer. NO DefaultHasher. fork(&self) order-independent, doesn't mutate parent. range=half-open w/ rejection sampling; shuffle=hand-rolled FisherYates on next_u64; chance clamps + 53-bit. **Adversarial RNG verify never ran (worktree error) — I reviewed it manually: contract holds.**
- **T5 data model**: Tile{Wall(default),Floor,Door}; RegionId(pub usize) id==index invariant; RegionKind{Room,Corridor}; Region/Edge fields pub; Edge.at=Option<Point>; ConnGraph new/add_edge/edges/edges_mut/neighbors; Map all-pub; to_ascii `#`/`.`/`+`.
### Orchestrator fix — derive PartialEq/Eq on Grid<T> + Map ✅ (commit 8c4ef2e)
T5 deliberately skipped Eq on Map (Grid wasn't Eq) and used a serde-string compare workaround. Added the derives at the data-model layer so Tasks 6 & 12 determinism tests can use `assert_eq!(map_a, map_b)` directly. Purely additive, 41 tests still green.
### ⚠️ Environment constraint discovered
**Worktree isolation is UNAVAILABLE** (`WorktreeIsolationError: not in a git repository and no WorktreeCreate hooks configured`) — even though `git rev-parse` confirms a valid repo. Do NOT use `isolation: 'worktree'` in workflows or Agent calls. Phase 3 (parallel passes 711) must use a different anti-race strategy: orchestrator pre-stubs all 5 pass files + pre-wires passes/mod.rs, commits, then passes are implemented — likely SEQUENTIALLY in the shared tree (or with each agent told to only Write its file + not run concurrent cargo) to avoid build races. Re-decide at Phase 3.
### Task 6 — generation engine ✅ (commit e0a20f7)
Direct dispatch + my full code review (skipped separate validator — keystone read line-by-line; Task 12 integration tests are the end-to-end backstop). 53 tests green, clippy-clean.
- `Pass::apply(&self, ctx, rng)` exact. `GenContext{tiles,regions,graph,blackboard}` + `add_region`→`RegionId(len())`. `Snapshot{label,tiles,regions,edges}`. `Pipeline::new(w,h)/then/run/run_with_snapshots`.
- **RNG isolation correct**: per-NAME occurrence counter (`HashMap<&str,u32>`), key `"name#occ"`, `root.fork(key)` per pass. Isolation test inserts draw-then-discard X between A,B and proves their streams unchanged. ✓
- `run`/`run_with_snapshots` share private `run_inner(seed, collect)` → cannot diverge. Snapshots clone-after-apply, RNG-untouched. ✓
- `Blackboard` HashMap<String,Box<dyn Any>>; wrong-type get→None, take non-destructive. ✓
- `passes/mod.rs` created with contract doc comment, NO pub mod lines (711 append).
## Phase 3 plan (REVISED — no worktrees)
Run passes 7→8→9→10→11 SEQUENTIALLY in shared tree (forced by no worktree isolation). Each implementer creates its file + appends its own `pub mod`/`pub use` to passes/mod.rs (sequential = no race, like Tasks 2-5 did with lib.rs). No pre-stubbing needed. Sequential also lets later passes (e.g. DoorPlacer) read earlier passes' real cell-population conventions. Then a PARALLEL adversarial verify fan-out (read-only, no isolation) over the 5 passes for algorithm/determinism/bounds bugs. Heavy integration verification deferred to Task 12.
## Open concerns
- Determinism is the highest-risk surface: RNG fork stability (T4) + pipeline per-pass forking (T6). Both get adversarial verification.
- Parallel batch (711) shares passes/mod.rs — handled by orchestrator-owned pre-wiring + worktree isolation.