diff --git a/Cargo.lock b/Cargo.lock index 07d3f53..f929fd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,27 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + [[package]] name = "arrayref" version = "0.3.9" @@ -66,6 +87,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.2.43" @@ -82,6 +109,58 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "clap" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -98,6 +177,52 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "errno" version = "0.3.14" @@ -138,12 +263,49 @@ dependencies = [ "wasip2", ] +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -203,6 +365,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -299,12 +467,43 @@ dependencies = [ "rand_core", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "rmg-benches" +version = "0.1.0" +dependencies = [ + "criterion", + "rmg-core", +] + [[package]] name = "rmg-cli" version = "0.1.0" @@ -487,6 +686,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "unarray" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index f86bcb1..27073e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,8 @@ members = [ "crates/rmg-ffi", "crates/rmg-wasm", "crates/rmg-cli", - "crates/rmg-geom" + "crates/rmg-geom", + "crates/rmg-benches" ] resolver = "2" @@ -16,3 +17,12 @@ opt-level = "s" lto = true codegen-units = 1 strip = true + +[profile.bench] +# Derive from release but optimize for throughput and faster builds +opt-level = 3 +lto = false +codegen-units = 16 +debug = true +panic = "abort" +strip = false diff --git a/README.md b/README.md index 86043be..8d4616b 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,12 @@ RMG provides atomic, in-place edits of recursive meta-graphs with deterministic It’s the core of the Echo engine: runtime, assets, networking, and tools all operate on the same living graph of graphs. +## Developer: Running Benchmarks + +- Command: `cargo bench -p rmg-benches` +- Purpose: Runs Criterion micro-benchmarks for the benches crate (`crates/rmg-benches`). +- Location: see `crates/rmg-benches/` for sources and configuration. + ### Core Principles | Principle | Description | diff --git a/crates/rmg-benches/Cargo.toml b/crates/rmg-benches/Cargo.toml new file mode 100644 index 0000000..24ee0a4 --- /dev/null +++ b/crates/rmg-benches/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rmg-benches" +version = "0.1.0" +edition = "2021" +publish = false +license = "Apache-2.0" + +[dev-dependencies] +criterion = { version = "0.5", default-features = false, features = ["html_reports"] } +# Pin version alongside path to satisfy cargo-deny wildcard bans +rmg-core = { version = "0.1.0", path = "../rmg-core" } + +[[bench]] +name = "motion_throughput" +harness = false diff --git a/crates/rmg-benches/benches/motion_throughput.rs b/crates/rmg-benches/benches/motion_throughput.rs new file mode 100644 index 0000000..ccbd08a --- /dev/null +++ b/crates/rmg-benches/benches/motion_throughput.rs @@ -0,0 +1,97 @@ +#![allow(missing_docs)] +use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput}; +use rmg_core::{ + decode_motion_payload, encode_motion_payload, make_node_id, make_type_id, ApplyResult, Engine, + NodeId, NodeRecord, MOTION_RULE_NAME, +}; +use std::{hint::black_box, time::Duration}; + +fn build_engine_with_n_entities(n: usize) -> (Engine, Vec) { + // Start from the demo engine (root + motion rule registered). + let mut engine = rmg_core::build_motion_demo_engine(); + let ty = make_type_id("entity"); + let mut ids = Vec::with_capacity(n); + // Insert N entities with a simple payload. + for i in 0..n { + let label = format!("ent-{}", i); + // Precompute NodeId so hashing is not part of the hot loop. + let id = make_node_id(&label); + let pos = [i as f32, 0.0, 0.0]; + let vel = [1.0, 0.0, 0.0]; + let payload = encode_motion_payload(pos, vel); + engine.insert_node( + id, + NodeRecord { + ty, + payload: Some(payload), + }, + ); + ids.push(id); + } + (engine, ids) +} + +fn bench_motion_apply(c: &mut Criterion) { + // Bench 1: Build-only — measures engine construction + inserts. + let mut build_group = c.benchmark_group("motion_build_only"); + build_group.sample_size(50); + build_group.warm_up_time(Duration::from_secs(3)); + build_group.measurement_time(Duration::from_secs(6)); + build_group.noise_threshold(0.02); + for &n in &[1usize, 10, 100, 1_000] { + build_group.throughput(Throughput::Elements(n as u64)); + build_group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| { + // Measure just the build; keep work observable via black_box. + b.iter(|| { + let (engine, ids) = build_engine_with_n_entities(n); + // Optional quick sanity on the first entity to keep side effects visible. + let node = engine.node(&ids[0]).expect("node exists"); + let decoded = + decode_motion_payload(node.payload.as_ref().expect("payload")).expect("decode"); + debug_assert!(decoded.0.iter().all(|v| v.is_finite())); + debug_assert!(decoded.1.iter().all(|v| v.is_finite())); + black_box(engine); + black_box(ids); + black_box(decoded); + }) + }); + } + build_group.finish(); + + // Bench 2: Apply+Commit — measure only the rewrite/commit path. + let mut apply_group = c.benchmark_group("motion_apply_commit"); + apply_group.sample_size(50); + apply_group.warm_up_time(Duration::from_secs(3)); + apply_group.measurement_time(Duration::from_secs(6)); + apply_group.noise_threshold(0.02); + for &n in &[1usize, 10, 100, 1_000] { + apply_group.throughput(Throughput::Elements(n as u64)); + apply_group.bench_with_input(BenchmarkId::from_parameter(n), &n, |b, &n| { + // Build a fresh engine/ids in setup (not timed), measure only the apply/commit work. + b.iter_batched( + || build_engine_with_n_entities(n), + |(mut engine, ids)| { + let tx = engine.begin(); + for id in &ids { + let res = engine.apply(tx, MOTION_RULE_NAME, id).expect("apply"); + debug_assert!(matches!(res, ApplyResult::Applied | ApplyResult::NoMatch)); + } + engine.commit(tx).expect("commit"); + + // Decode and validate the first entity's payload and black_box the result. + let node = engine.node(&ids[0]).expect("node exists"); + let decoded = decode_motion_payload(node.payload.as_ref().expect("payload")) + .expect("decode"); + debug_assert!(decoded.0.iter().all(|v| v.is_finite())); + debug_assert!(decoded.1.iter().all(|v| v.is_finite())); + black_box(decoded); + }, + BatchSize::PerIteration, + ) + }); + } + apply_group.finish(); +} + +criterion_group!(benches, bench_motion_apply); +criterion_main!(benches); diff --git a/deny.toml b/deny.toml index 7099e14..ae8143d 100644 --- a/deny.toml +++ b/deny.toml @@ -16,11 +16,13 @@ allow = [ "Unlicense", ] -# Disallow copyleft by default; we do not expect GPL-family in the runtime. -copyleft = "deny" - -# Treat unknown or missing license as a failure. -unlicensed = "deny" +# Modernized for cargo-deny >=0.14.21 (PR #611): +# - Removed deprecated keys `copyleft` and `unlicensed`. +# Copyleft licenses remain effectively denied by virtue of the explicit +# `allow = [...]` list above. +# Crates missing a license will be flagged by cargo-deny as issues; our +# workspace crates all declare licenses, so no explicit `unlicensed` policy +# is required here. # Confidence threshold for license text detection (default 0.8) confidence-threshold = 0.8 @@ -33,4 +35,3 @@ wildcards = "deny" [sources] unknown-registry = "deny" unknown-git = "deny" - diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index bfea9d7..4eed0d3 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -2,7 +2,7 @@ import { defineConfig } from 'vitepress' export default defineConfig({ title: 'Echo', - description: 'Deterministic, multiverse-aware ECS', + description: 'Real-Time, Deterministic, Recursive Meta-Graph Simulation Engine', cleanUrls: true, ignoreDeadLinks: [ // Collision tour HTML is added in a separate PR @@ -25,7 +25,3 @@ export default defineConfig({ } } }) -<<<<<<< HEAD -======= - ->>>>>>> origin/main diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 3c4ad3a..18d5d41 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -6,32 +6,32 @@ This roadmap reconciles our current plan with GitHub milestones, issues, and the ## Milestones -- M1 – Golden Tests +- M1 – Golden Tests (Target: CI gates operational; bit‑exact vectors validated) - Bit‑exact golden vectors for state_root/commit_id (genesis, merge, empty) - Math kernel goldens (rotation/multiply/sin/cos) - CI matrix: macOS + Ubuntu (glibc) + Alpine (musl) -- M2.0 – Scalar Foundation - - Scalar trait; F32Scalar deterministic wrappers; DFix64 Q32.32 - - Deterministic transcendentals (LUT + refinement); tables checked‑in +- M2.0 – Scalar Foundation (Target: det_fixed & det_float lanes green across OSes) + - Scalar trait; F32Scalar deterministic wrappers; DFix64 Q32.32 (fixed‑point 32.32 format) + - Deterministic transcendentals (LUT = lookup table + refinement); tables checked‑in - Motion rule → Scalar; v2 payload (6×i64 Q32.32), dual decode v1/v2 -- M2.1 – Lattice Joins - - Lattice trait; scheduler fold order - - Exemplar lattices: tags union, cap/max +- M2.1 – Lattice Joins (Target: replay‑invariant merges under ACI properties) + - Lattice trait; scheduler fold order (canonical) + - Exemplar lattices: tags union, cap/max (join keys documented) - ACI property + replay determinism tests -- M2.2 – Playground Slice +- M2.2 – Playground Slice (Target: demo + CLI show identical hashes under permutations) - Minimal WASM demo; CLI run/diff showing replay‑identical hashes -- M2.5 – Accumulator Joins +- M2.5 – Accumulator Joins (Target: delta‑style joins pass ACI/replay tests) - Delta‑style joins; deterministic rounding/saturation; ACI + replay -- M3 – Sweep‑and‑Prune v1 +- M3 – Sweep‑and‑Prune v1 (Target: deterministic broad‑phase replaces O(n²) baseline) - Integerized endpoints; stable tie‑breakers; ordering/stability property tests -- M4 – Determinism Proof & Publish 0.1 +- M4 – Determinism Proof & Publish 0.1 (Target: cross‑OS proof + 0.1 release) - Prove determinism across OSes; finalize docs; publish rmg‑core/geom 0.1 --- ## Issue Table (live snapshot) -Rows are GitHub issues. Priority/Estimate reflect Project 9 fields. Block/parent relationships use native GitHub issue dependencies; no custom text fields are used. +Rows are GitHub issues. Priority/Estimate reflect Project 9 fields. Block/parent relationships use native GitHub issue dependencies; no custom text fields are used. Refresh cadence: update weekly or before each planning cycle. | Issue Name | # | Milestone | Priority | Estimate | Blocked By | Blocking | Parent | Children | Remarks | | --- | ---: | --- | --- | --- | --- | --- | --- | --- | --- | diff --git a/docs/decision-log.md b/docs/decision-log.md index 78c396f..dfc1e39 100644 --- a/docs/decision-log.md +++ b/docs/decision-log.md @@ -147,6 +147,12 @@ The following entries use a heading + bullets format for richer context. | 2025-10-30 | Spec + lint hygiene | Removed duplicate `clippy::module_name_repetitions` allow in `rmg-core/src/lib.rs`. Clarified `docs/spec-merkle-commit.md`: `edge_count` is u64 LE and may be 0; genesis commits have length=0 parents; “empty digest” explicitly defined as `blake3(b"")`; v1 mandates empty `decision_digest` until Aion lands. | Codifies intent; prevents ambiguity for implementers. | No code behavior changes; spec is clearer. | | 2025-10-30 | Templates & Project | Added issue/PR/RFC templates and configured Echo Project (Status: Blocked/Ready/Done); fixed YAML lint nits | Streamlines review process and Kanban tracking | No runtime impact; CI docs guard satisfied | +## 2025-11-02 — M1: benches crate skeleton (PR-11) + +- Decision: Add `crates/rmg-benches` with a minimal Criterion harness and a motion-throughput benchmark using public `rmg-core` APIs. +- Rationale: Establish a place for performance microbenches; keep PR small and focused before adding JSON artifacts/regression gates in follow-ups. +- Consequence: Benches run locally via `cargo bench -p rmg-benches`; no runtime changes. + ## 2025-11-01 — Docs rollup automation (pre-commit + subdirs) - Context: CI rollup check fails if `docs/echo-total.md` drifts; authors asked to trigger the rollup automatically on local commits and include subdirectories. @@ -169,3 +175,18 @@ The following entries use a heading + bullets format for richer context. - Decision: Limit normalization to the header region only and accept case/whitespace/legacy variants (`Generated:`, `generated at:`, `Generated by:`). Emit a GitHub Actions `::error` annotation targeting `docs/echo-total.md` when differences remain to improve diagnostics. - Consequence: Clearer CI failures; minimal, targeted normalization avoids masking content issues. + +## 2025-11-02 — CI hotfix: cargo-deny (benches) + +- Context: CI `cargo-deny` job failed on PR-11 due to `rmg-benches` lacking a license and a prior wildcard dependency reference reported by CI logs. +- Decision: Add `license = "Apache-2.0"` to `crates/rmg-benches/Cargo.toml` and ensure `rmg-core` is referenced via a path dev-dependency (no wildcard). +- Rationale: Keep workspace policy consistent with other crates (Apache-2.0) and satisfy bans (wildcards = deny) and licenses checks. +- Consequence: `cargo-deny` bans/licenses should pass; remaining warnings are deprecations in `deny.toml` to be addressed in a later sweep. + +## 2025-11-02 — cargo-deny modernization + +- Context: CI emitted deprecation warnings for `copyleft` and `unlicensed` keys in `deny.toml` (cargo-deny PR #611). +- Decision: Remove deprecated keys; rely on the explicit permissive `allow = [...]` list to exclude copyleft licenses; ensure all workspace crates declare a license (benches fixed earlier). +- Rationale: Keep CI quiet and align with current cargo-deny schema without weakening enforcement. +- Consequence: Same effective policy, no deprecation warnings; future license exceptions remain possible via standard cargo-deny mechanisms. +- CI Note: Use `cargo-deny >= 0.14.21` in CI (workflow/container) to avoid schema drift and deprecation surprises. Pin the action/image or the downloaded binary version accordingly. diff --git a/docs/echo-total.md b/docs/echo-total.md index 3fbf868..2a2db72 100644 --- a/docs/echo-total.md +++ b/docs/echo-total.md @@ -260,6 +260,14 @@ This is Codex’s working map for building Echo. Update it relentlessly—each s ## Today’s Intent +> 2025-11-02 — PR-11 hotfix-deterministic-rollup-check + +- Switch to `echo/hotfix-deterministic-rollup-check`, fetch and merge `origin/main` (merge commit; no rebase). +- Fix CI cargo-deny failures: + - Add `license = "Apache-2.0"` to `crates/rmg-benches/Cargo.toml`. + - Ensure no wildcard dependency remains in benches (use workspace path dep for `rmg-core`). +- Modernize `deny.toml` (remove deprecated `copyleft` and `unlicensed` keys per cargo-deny PR #611); enforcement still via explicit allowlist. + > 2025-10-30 — PR-01: Golden motion fixtures (tests-only) - Add JSON golden fixtures and a minimal harness for the motion rule under `crates/rmg-core/tests/`. @@ -536,6 +544,10 @@ Remember: every entry here shrinks temporal drift between Codices. Leave breadcr > 2025-11-02 — Hotfix follow-up: tighter normalization + annotation - CI normalization now only removes `Generated` header lines in the top-of-file header block (from start to first blank line) and tolerates whitespace/case variants and legacy forms like `Generated:`, `generated at:`, `Generated by:`. Added a GitHub Actions annotation on failure to point directly at `docs/echo-total.md`. +> 2025-11-02 — PR-11: benches crate skeleton (M1) + +- Add `crates/rmg-benches` with Criterion harness and a minimal motion-throughput benchmark that exercises public `rmg-core` APIs. +- Scope: benches-only; no runtime changes. Document local run (`cargo bench -p rmg-benches`). --- @@ -692,6 +704,12 @@ The following entries use a heading + bullets format for richer context. | 2025-10-30 | Spec + lint hygiene | Removed duplicate `clippy::module_name_repetitions` allow in `rmg-core/src/lib.rs`. Clarified `docs/spec-merkle-commit.md`: `edge_count` is u64 LE and may be 0; genesis commits have length=0 parents; “empty digest” explicitly defined as `blake3(b"")`; v1 mandates empty `decision_digest` until Aion lands. | Codifies intent; prevents ambiguity for implementers. | No code behavior changes; spec is clearer. | | 2025-10-30 | Templates & Project | Added issue/PR/RFC templates and configured Echo Project (Status: Blocked/Ready/Done); fixed YAML lint nits | Streamlines review process and Kanban tracking | No runtime impact; CI docs guard satisfied | +## 2025-11-02 — M1: benches crate skeleton (PR-11) + +- Decision: Add `crates/rmg-benches` with a minimal Criterion harness and a motion-throughput benchmark using public `rmg-core` APIs. +- Rationale: Establish a place for performance microbenches; keep PR small and focused before adding JSON artifacts/regression gates in follow-ups. +- Consequence: Benches run locally via `cargo bench -p rmg-benches`; no runtime changes. + ## 2025-11-01 — Docs rollup automation (pre-commit + subdirs) - Context: CI rollup check fails if `docs/echo-total.md` drifts; authors asked to trigger the rollup automatically on local commits and include subdirectories. @@ -715,6 +733,21 @@ The following entries use a heading + bullets format for richer context. - Decision: Limit normalization to the header region only and accept case/whitespace/legacy variants (`Generated:`, `generated at:`, `Generated by:`). Emit a GitHub Actions `::error` annotation targeting `docs/echo-total.md` when differences remain to improve diagnostics. - Consequence: Clearer CI failures; minimal, targeted normalization avoids masking content issues. +## 2025-11-02 — CI hotfix: cargo-deny (benches) + +- Context: CI `cargo-deny` job failed on PR-11 due to `rmg-benches` lacking a license and a prior wildcard dependency reference reported by CI logs. +- Decision: Add `license = "Apache-2.0"` to `crates/rmg-benches/Cargo.toml` and ensure `rmg-core` is referenced via a path dev-dependency (no wildcard). +- Rationale: Keep workspace policy consistent with other crates (Apache-2.0) and satisfy bans (wildcards = deny) and licenses checks. +- Consequence: `cargo-deny` bans/licenses should pass; remaining warnings are deprecations in `deny.toml` to be addressed in a later sweep. + +## 2025-11-02 — cargo-deny modernization + +- Context: CI emitted deprecation warnings for `copyleft` and `unlicensed` keys in `deny.toml` (cargo-deny PR #611). +- Decision: Remove deprecated keys; rely on the explicit permissive `allow = [...]` list to exclude copyleft licenses; ensure all workspace crates declare a license (benches fixed earlier). +- Rationale: Keep CI quiet and align with current cargo-deny schema without weakening enforcement. +- Consequence: Same effective policy, no deprecation warnings; future license exceptions remain possible via standard cargo-deny mechanisms. +- CI Note: Use `cargo-deny >= 0.14.21` in CI (workflow/container) to avoid schema drift and deprecation surprises. Pin the action/image or the downloaded binary version accordingly. + --- @@ -757,32 +790,32 @@ This roadmap reconciles our current plan with GitHub milestones, issues, and the ## Milestones -- M1 – Golden Tests +- M1 – Golden Tests (Target: CI gates operational; bit‑exact vectors validated) - Bit‑exact golden vectors for state_root/commit_id (genesis, merge, empty) - Math kernel goldens (rotation/multiply/sin/cos) - CI matrix: macOS + Ubuntu (glibc) + Alpine (musl) -- M2.0 – Scalar Foundation - - Scalar trait; F32Scalar deterministic wrappers; DFix64 Q32.32 - - Deterministic transcendentals (LUT + refinement); tables checked‑in +- M2.0 – Scalar Foundation (Target: det_fixed & det_float lanes green across OSes) + - Scalar trait; F32Scalar deterministic wrappers; DFix64 Q32.32 (fixed‑point 32.32 format) + - Deterministic transcendentals (LUT = lookup table + refinement); tables checked‑in - Motion rule → Scalar; v2 payload (6×i64 Q32.32), dual decode v1/v2 -- M2.1 – Lattice Joins - - Lattice trait; scheduler fold order - - Exemplar lattices: tags union, cap/max +- M2.1 – Lattice Joins (Target: replay‑invariant merges under ACI properties) + - Lattice trait; scheduler fold order (canonical) + - Exemplar lattices: tags union, cap/max (join keys documented) - ACI property + replay determinism tests -- M2.2 – Playground Slice +- M2.2 – Playground Slice (Target: demo + CLI show identical hashes under permutations) - Minimal WASM demo; CLI run/diff showing replay‑identical hashes -- M2.5 – Accumulator Joins +- M2.5 – Accumulator Joins (Target: delta‑style joins pass ACI/replay tests) - Delta‑style joins; deterministic rounding/saturation; ACI + replay -- M3 – Sweep‑and‑Prune v1 +- M3 – Sweep‑and‑Prune v1 (Target: deterministic broad‑phase replaces O(n²) baseline) - Integerized endpoints; stable tie‑breakers; ordering/stability property tests -- M4 – Determinism Proof & Publish 0.1 +- M4 – Determinism Proof & Publish 0.1 (Target: cross‑OS proof + 0.1 release) - Prove determinism across OSes; finalize docs; publish rmg‑core/geom 0.1 --- ## Issue Table (live snapshot) -Rows are GitHub issues. Priority/Estimate reflect Project 9 fields. Block/parent relationships use native GitHub issue dependencies; no custom text fields are used. +Rows are GitHub issues. Priority/Estimate reflect Project 9 fields. Block/parent relationships use native GitHub issue dependencies; no custom text fields are used. Refresh cadence: update weekly or before each planning cycle. | Issue Name | # | Milestone | Priority | Estimate | Blocked By | Blocking | Parent | Children | Remarks | | --- | ---: | --- | --- | --- | --- | --- | --- | --- | --- | diff --git a/docs/execution-plan.md b/docs/execution-plan.md index 22b7eaa..93eaf53 100644 --- a/docs/execution-plan.md +++ b/docs/execution-plan.md @@ -33,6 +33,14 @@ This is Codex’s working map for building Echo. Update it relentlessly—each s ## Today’s Intent +> 2025-11-02 — PR-11 hotfix-deterministic-rollup-check + +- Switch to `echo/hotfix-deterministic-rollup-check`, fetch and merge `origin/main` (merge commit; no rebase). +- Fix CI cargo-deny failures: + - Add `license = "Apache-2.0"` to `crates/rmg-benches/Cargo.toml`. + - Ensure no wildcard dependency remains in benches (use workspace path dep for `rmg-core`). +- Modernize `deny.toml` (remove deprecated `copyleft` and `unlicensed` keys per cargo-deny PR #611); enforcement still via explicit allowlist. + > 2025-10-30 — PR-01: Golden motion fixtures (tests-only) - Add JSON golden fixtures and a minimal harness for the motion rule under `crates/rmg-core/tests/`. @@ -309,3 +317,7 @@ Remember: every entry here shrinks temporal drift between Codices. Leave breadcr > 2025-11-02 — Hotfix follow-up: tighter normalization + annotation - CI normalization now only removes `Generated` header lines in the top-of-file header block (from start to first blank line) and tolerates whitespace/case variants and legacy forms like `Generated:`, `generated at:`, `Generated by:`. Added a GitHub Actions annotation on failure to point directly at `docs/echo-total.md`. +> 2025-11-02 — PR-11: benches crate skeleton (M1) + +- Add `crates/rmg-benches` with Criterion harness and a minimal motion-throughput benchmark that exercises public `rmg-core` APIs. +- Scope: benches-only; no runtime changes. Document local run (`cargo bench -p rmg-benches`).