Skip to content

Commit d649e9f

Browse files
committed
merge(train-geom-1): resolve docs + hook conflicts with origin/main
2 parents 87d9f53 + 3d8da97 commit d649e9f

File tree

120 files changed

+5431
-170
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+5431
-170
lines changed

.devcontainer/devcontainer.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "echo-dev",
3+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
4+
"features": {
5+
"ghcr.io/devcontainers/features/common-utils:2": {
6+
"username": "vscode",
7+
"installZsh": false
8+
},
9+
"ghcr.io/devcontainers/features/rust:1": {
10+
"profile": "minimal",
11+
"components": ["rustfmt", "clippy"]
12+
},
13+
"ghcr.io/devcontainers/features/node:1": {
14+
"version": "20"
15+
},
16+
"ghcr.io/devcontainers/features/github-cli:1": {}
17+
},
18+
"customizations": {
19+
"vscode": {
20+
"extensions": [
21+
"rust-lang.rust-analyzer",
22+
"serayuzgur.crates",
23+
"tamasfe.even-better-toml",
24+
"vadimcn.vscode-lldb"
25+
]
26+
}
27+
},
28+
"mounts": [
29+
"source=devcontainer-cargo-cache,target=/usr/local/cargo,type=volume",
30+
"source=devcontainer-rustup-cache,target=/usr/local/rustup,type=volume"
31+
],
32+
"containerEnv": {
33+
"CARGO_TERM_COLOR": "always"
34+
},
35+
"overrideCommand": false,
36+
"postCreateCommand": "/bin/bash .devcontainer/post-create.sh"
37+
}

.devcontainer/post-create.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
echo "[devcontainer] Installing default toolchain (1.71.1 via rust-toolchain.toml)..."
5+
if ! command -v rustup >/dev/null 2>&1; then
6+
curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused --location --silent --show-error --fail https://sh.rustup.rs | sh -s -- --default-toolchain none -y
7+
export PATH="$HOME/.cargo/bin:$PATH"
8+
fi
9+
10+
rustup toolchain install 1.71.1 --profile minimal
11+
# Do not override default; let rust-toolchain.toml control selection for this repo.
12+
# Ensure components/targets are available for the default toolchain (1.71.1).
13+
rustup component add --toolchain 1.71.1 rustfmt clippy || true
14+
rustup target add --toolchain 1.71.1 wasm32-unknown-unknown || true
15+
16+
echo "[devcontainer] Priming cargo registry cache (optional)..."
17+
cargo fetch || true
18+
19+
echo "[devcontainer] Done. Run 'cargo test -p rmg-core' or 'make ci-local' to validate."

.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = space
9+
indent_size = 4
10+
11+
[*.{md,mdx}]
12+
trim_trailing_whitespace = false
13+
14+
[*.{ts,tsx,js,json}]
15+
indent_size = 2
16+

.githooks/commit-msg

100644100755
File mode changed.

.githooks/pre-commit

100644100755
Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4+
45
if [[ "${SKIP_HOOKS:-}" == 1 ]]; then
56
exit 0
67
fi
@@ -49,8 +50,27 @@ if command -v rustup >/dev/null 2>&1; then
4950
fi
5051
fi
5152

52-
# 3) Format check (fast)
53-
cargo fmt --all -- --check
53+
# 3) Format (auto-fix if opted in)
54+
_auto_fmt="${ECHO_AUTO_FMT:-1}"
55+
case "${_auto_fmt}" in
56+
1|true|TRUE|yes|YES|on|ON)
57+
echo "pre-commit: ECHO_AUTO_FMT=${_auto_fmt} → running cargo fmt (auto-fix)"
58+
cargo fmt --all || { echo "pre-commit: cargo fmt failed" >&2; exit 1; }
59+
# Re-stage only staged files that were reformatted
60+
if STAGED=$(git diff --cached --name-only); then
61+
if [[ -n "$STAGED" ]]; then
62+
echo "$STAGED" | xargs -r git add --
63+
fi
64+
fi
65+
;;
66+
0|false|FALSE|no|NO|off|OFF)
67+
cargo fmt --all -- --check || { echo "pre-commit: cargo fmt check failed" >&2; exit 1; }
68+
;;
69+
*)
70+
# Unknown value → safest is check-only
71+
cargo fmt --all -- --check || { echo "pre-commit: cargo fmt check failed" >&2; exit 1; }
72+
;;
73+
esac
5474

5575
# 4) Docs guard (scaled): only require docs when core public API changed
5676
STAGED=$(git diff --cached --name-only)
@@ -60,12 +80,19 @@ if [[ -n "$CORE_API_CHANGED" ]]; then
6080
echo "$STAGED" | grep -Fx 'docs/decision-log.md' >/dev/null || { echo 'pre-commit: docs/decision-log.md must be updated when core API changes.' >&2; exit 1; }
6181
fi
6282

63-
# 5) Lockfile guard: ensure lockfile version is v3 (compatible with MSRV cargo)
83+
# 5) Lockfile guard: ensure lockfile version is v3 (current cargo format)
6484
if [[ -f Cargo.lock ]]; then
65-
VER_LINE=$(grep -n '^version = ' Cargo.lock | head -n1 | awk -F'= ' '{print $2}')
66-
if [[ "$VER_LINE" != "3" && "$VER_LINE" != "3\r" ]]; then
67-
echo "pre-commit: Cargo.lock must be generated with Cargo 1.68 (lockfile v3)." >&2
68-
echo "Run: cargo +1.68.0 generate-lockfile" >&2
85+
# Normalize detected lockfile version (strip quotes/CR/whitespace)
86+
VER_LINE=$(grep -n '^version = ' Cargo.lock | head -n1 | awk -F'= ' '{print $2}' | tr -d '\r' | tr -d '"' | xargs)
87+
if [[ "$VER_LINE" != "3" ]]; then
88+
# Determine pinned toolchain (normalize), fallback to rust-toolchain.toml if unset
89+
_PINNED_RAW="${PINNED:-}"
90+
if [[ -z "$_PINNED_RAW" ]]; then
91+
_PINNED_RAW=$(awk -F '"' '/^channel/ {print $2}' rust-toolchain.toml 2>/dev/null || echo "")
92+
fi
93+
PINNED_NORM=$(printf "%s" "$_PINNED_RAW" | tr -d '\r' | xargs)
94+
echo "pre-commit: Cargo.lock must be lockfile format v3 (found '$VER_LINE')." >&2
95+
echo "Run: cargo +${PINNED_NORM} generate-lockfile" >&2
6996
exit 1
7097
fi
7198
fi

.githooks/pre-push

100644100755
Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
3-
PINNED="${PINNED:-1.68.0}"
3+
PINNED="${PINNED:-1.71.1}"
4+
# MSRV floor for library checks (override with MSRV env)
5+
MSRV="${MSRV:-1.71.1}"
46

57
for cmd in cargo rustup rg; do
68
if ! command -v "$cmd" >/dev/null 2>&1; then
@@ -15,34 +17,76 @@ if [[ "${SKIP_HOOKS:-}" == 1 ]]; then
1517
exit 0
1618
fi
1719

18-
echo "[pre-push] fmt"
19-
cargo +"$PINNED" fmt --all -- --check
20+
echo "[pre-push] fmt (default toolchain)"
21+
cargo fmt --all -- --check
2022

21-
echo "[pre-push] clippy (workspace)"
22-
cargo +"$PINNED" clippy --all-targets -- -D warnings -D missing_docs
23+
echo "[pre-push] clippy (workspace, default toolchain)"
24+
cargo clippy --all-targets -- -D warnings -D missing_docs
2325

24-
echo "[pre-push] tests (workspace)"
25-
cargo +"$PINNED" test --workspace
26+
echo "[pre-push] tests (workspace, default toolchain)"
27+
cargo test --workspace
2628

27-
# MSRV check for rmg-core
28-
echo "[pre-push] MSRV check (rmg-core @ $PINNED)"
29-
if rustup run "$PINNED" cargo -V >/dev/null 2>&1; then
30-
cargo +"$PINNED" check -p rmg-core --all-targets
29+
echo "[pre-push] Testing against MSRV ${MSRV} (core libraries)"
30+
# If any participating crate declares a rust-version greater than MSRV, skip MSRV checks entirely.
31+
CORE_RV=$(awk -F '"' '/^rust-version/ {print $2}' crates/rmg-core/Cargo.toml 2>/dev/null || echo "")
32+
GEOM_RV=$(awk -F '"' '/^rust-version/ {print $2}' crates/rmg-geom/Cargo.toml 2>/dev/null || echo "")
33+
if { [[ -n "$CORE_RV" ]] && printf '%s\n%s\n' "$MSRV" "$CORE_RV" | sort -V | tail -n1 | grep -qx "$CORE_RV" && [[ "$CORE_RV" != "$MSRV" ]]; } \
34+
|| { [[ -n "$GEOM_RV" ]] && printf '%s\n%s\n' "$MSRV" "$GEOM_RV" | sort -V | tail -n1 | grep -qx "$GEOM_RV" && [[ "$GEOM_RV" != "$MSRV" ]]; }; then
35+
echo "[pre-push] Skipping MSRV block: one or more crates declare rust-version > ${MSRV} (core=${CORE_RV:-unset}, geom=${GEOM_RV:-unset})"
3136
else
32-
echo "[pre-push] MSRV toolchain $PINNED not installed. Install via: rustup toolchain install $PINNED" >&2
33-
exit 1
37+
if ! rustup run "$MSRV" cargo -V >/dev/null 2>&1; then
38+
echo "[pre-push] MSRV toolchain ${MSRV} not installed. Install via: rustup toolchain install ${MSRV}" >&2
39+
exit 1
40+
fi
41+
# Only run MSRV tests for crates that declare rust-version <= MSRV; skip otherwise.
42+
msrv_ok() {
43+
local crate="$1"
44+
local rv
45+
rv=$(awk -F '"' '/^rust-version/ {print $2}' "crates/${crate}/Cargo.toml" 2>/dev/null || echo "")
46+
if [[ -z "$rv" ]]; then
47+
return 0
48+
fi
49+
# If declared rust-version is greater than MSRV, skip.
50+
if printf '%s\n%s\n' "$MSRV" "$rv" | sort -V | tail -n1 | grep -qx "$rv" && [[ "$rv" != "$MSRV" ]]; then
51+
echo "[pre-push] Skipping MSRV test for ${crate} (rust-version ${rv} > MSRV ${MSRV})"
52+
return 1
53+
fi
54+
# If crate depends on workspace rmg-core whose rust-version exceeds MSRV, skip as well
55+
if grep -qE '^rmg-core\s*=\s*\{[^}]*path\s*=\s*"\.\./rmg-core"' "crates/${crate}/Cargo.toml" 2>/dev/null; then
56+
local core_rv
57+
core_rv=$(awk -F '"' '/^rust-version/ {print $2}' "crates/rmg-core/Cargo.toml" 2>/dev/null || echo "")
58+
if [[ -n "$core_rv" ]] && printf '%s\n%s\n' "$MSRV" "$core_rv" | sort -V | tail -n1 | grep -qx "$core_rv" && [[ "$core_rv" != "$MSRV" ]]; then
59+
echo "[pre-push] Skipping MSRV test for ${crate} (depends on rmg-core ${core_rv} > MSRV ${MSRV})"
60+
return 1
61+
fi
62+
fi
63+
return 0
64+
}
65+
if msrv_ok rmg-core; then cargo +"$MSRV" test -p rmg-core --all-targets; fi
66+
if msrv_ok rmg-geom; then cargo +"$MSRV" test -p rmg-geom --all-targets; fi
3467
fi
3568

36-
# Rustdoc warnings guard (core API)
37-
echo "[pre-push] rustdoc warnings gate (rmg-core)"
69+
# Rustdoc warnings guard (public crates)
70+
echo "[pre-push] rustdoc warnings gate (rmg-core @ $PINNED)"
3871
RUSTDOCFLAGS="-D warnings" cargo +"$PINNED" doc -p rmg-core --no-deps
72+
echo "[pre-push] rustdoc warnings gate (rmg-geom @ $PINNED)"
73+
RUSTDOCFLAGS="-D warnings" cargo +"$PINNED" doc -p rmg-geom --no-deps
3974

4075
# Banned patterns
4176
echo "[pre-push] scanning banned patterns"
42-
# Match any crate-level allow(...) that includes missing_docs; exclude telemetry.rs explicitly
43-
if rg -n '#!\[allow\([^]]*missing_docs[^]]*\)\]' --glob '!crates/rmg-core/src/telemetry.rs' crates >/dev/null; then
77+
# Forbid crate-level allow(missing_docs) in library source files, but allow in tests and build scripts
78+
if rg -n '#!\[allow\([^]]*missing_docs[^]]*\)\]' \
79+
crates \
80+
--glob 'crates/**/src/**/*.rs' \
81+
--glob '!**/telemetry.rs' \
82+
--glob '!**/tests/**' \
83+
--glob '!**/build.rs' >/dev/null; then
4484
echo "pre-push: crate-level allow(missing_docs) is forbidden (except telemetry.rs)." >&2
45-
rg -n '#!\[allow\([^]]*missing_docs[^]]*\)\]' --glob '!crates/rmg-core/src/telemetry.rs' crates | cat >&2 || true
85+
rg -n '#!\[allow\([^]]*missing_docs[^]]*\)\]' crates \
86+
--glob 'crates/**/src/**/*.rs' \
87+
--glob '!**/telemetry.rs' \
88+
--glob '!**/tests/**' \
89+
--glob '!**/build.rs' | cat >&2 || true
4690
exit 1
4791
fi
4892
if rg -n "\#\[unsafe\(no_mangle\)\]" crates >/dev/null; then

.githooks/pre-rebase

100644100755
File mode changed.

.github/workflows/ci.yml

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ jobs:
1515
- uses: actions/checkout@v4
1616
with:
1717
submodules: false
18-
- uses: dtolnay/rust-toolchain@stable
19-
- uses: dtolnay/rust-toolchain@stable
18+
- uses: dtolnay/rust-toolchain@1.71.1
2019
- uses: Swatinem/rust-cache@v2
2120
with:
2221
workspaces: |
@@ -31,19 +30,14 @@ jobs:
3130
- uses: actions/checkout@v4
3231
with:
3332
submodules: false
34-
- uses: dtolnay/rust-toolchain@stable
33+
- uses: dtolnay/rust-toolchain@1.71.1
3534
with:
36-
toolchain: stable
3735
components: clippy
38-
- name: rustup override stable
39-
run: rustup toolchain install stable && rustup override set stable
4036
- uses: Swatinem/rust-cache@v2
4137
with:
4238
workspaces: |
4339
.
4440
- name: cargo clippy
45-
env:
46-
RUSTUP_TOOLCHAIN: stable
4741
run: cargo clippy --all-targets -- -D warnings -D missing_docs
4842

4943
test:
@@ -53,19 +47,13 @@ jobs:
5347
- uses: actions/checkout@v4
5448
with:
5549
submodules: false
56-
- uses: dtolnay/rust-toolchain@stable
57-
with:
58-
toolchain: stable
59-
- name: rustup override stable
60-
run: rustup toolchain install stable && rustup override set stable
50+
- uses: dtolnay/rust-toolchain@1.71.1
6151
- uses: Swatinem/rust-cache@v2
6252
with:
6353
workspaces: |
6454
.
65-
- name: cargo test
66-
env:
67-
RUSTUP_TOOLCHAIN: stable
68-
run: cargo test
55+
- name: cargo test (workspace)
56+
run: cargo test --workspace
6957
- name: PRNG golden regression (rmg-core)
7058
run: cargo test -p rmg-core --features golden_prng -- tests::next_int_golden_regression
7159

@@ -101,20 +89,6 @@ jobs:
10189
exit 1;
10290
}
10391
104-
msrv:
105-
name: MSRV (rmg-core @ 1.68)
106-
runs-on: ubuntu-latest
107-
steps:
108-
- uses: actions/checkout@v4
109-
with:
110-
submodules: false
111-
- uses: dtolnay/rust-toolchain@1.68.0
112-
- uses: Swatinem/rust-cache@v2
113-
with:
114-
workspaces: |
115-
.
116-
- name: cargo check (rmg-core)
117-
run: cargo check -p rmg-core --all-targets
11892
11993
rustdoc:
12094
name: Rustdoc (rmg-core warnings gate)
@@ -123,13 +97,7 @@ jobs:
12397
- uses: actions/checkout@v4
12498
with:
12599
submodules: false
126-
- uses: dtolnay/rust-toolchain@stable
127-
with:
128-
toolchain: stable
129-
- name: rustup override stable
130-
run: rustup toolchain install stable && rustup override set stable
100+
- uses: dtolnay/rust-toolchain@1.71.1
131101
- uses: Swatinem/rust-cache@v2
132102
- name: rustdoc warnings gate
133-
env:
134-
RUSTUP_TOOLCHAIN: stable
135103
run: RUSTDOCFLAGS="-D warnings" cargo doc -p rmg-core --no-deps

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ Welcome to the **Echo** project. This file captures expectations for any LLM age
2626
- Respect determinism: preferably no random seeds without going through the Echo PRNG.
2727
- Run `cargo clippy --all-targets -- -D missing_docs` and `cargo test` before every PR; CI will expect a zero-warning, fully documented surface.
2828

29+
### Git Hooks & Local CI
30+
- Install repo hooks once with `make hooks` (configures `core.hooksPath`).
31+
- Formatting: pre-commit auto-fixes with `cargo fmt` by default. Set `ECHO_AUTO_FMT=0` to run check-only instead.
32+
- Toolchain: pre-commit verifies your active toolchain matches `rust-toolchain.toml`.
33+
- Docs Guard: when core API files change, the hook requires updating `docs/execution-plan.md` and `docs/decision-log.md` (mirrors the CI check).
34+
2935
## Git Real
3036
1. **NEVER** use `--force` with any git command. If you think you need it, stop and ask the human for help.
3137
2. **NEVER** use rebase. Embrace messy distributed history; plain merges capture the truth, rebases rewrite it.

CONTRIBUTING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Echo is a deterministic, renderer-agnostic engine. We prioritize:
2222
1. Clone the repo and run `cargo check` to ensure the Rust workspace builds.
2323
2. Read `docs/architecture-outline.md` and `docs/execution-plan.md`.
2424
3. Review `AGENTS.md` for collaboration norms before touching runtime code.
25+
4. Optional: develop inside the devcontainer for toolchain parity with CI.
26+
- Open in VS Code → "Reopen in Container" (requires the Dev Containers extension).
27+
- The container includes Rust 1.71.1 (via rust-toolchain.toml), clippy/rustfmt, Node, and gh.
28+
- Post-create installs toolchain 1.71.1 (no override); wasm32 target and components are added to 1.71.1.
2529

2630
## Branching & Workflow
2731
- Keep `main` pristine. Create feature branches like `echo/<feature>` or `timeline/<experiment>`.
@@ -53,6 +57,14 @@ Echo is a deterministic, renderer-agnostic engine. We prioritize:
5357
- TypeScript tooling (when active) lives in `reference/typescript/`; follow local lint configs when reactivated.
5458
- Avoid non-deterministic APIs (no wall-clock, no uncontrolled randomness). Use Echo’s deterministic services.
5559

60+
### Git Hooks (recommended)
61+
- Install repo hooks once: `make hooks` (configures `core.hooksPath` to `.githooks`).
62+
- Pre-commit runs:
63+
- cargo fmt (auto-fix by default; set `ECHO_AUTO_FMT=0` for check-only)
64+
- Toolchain pin verification (matches `rust-toolchain.toml`)
65+
- A minimal docs-guard: when core API files change, it requires updating `docs/execution-plan.md` and `docs/decision-log.md` (mirrors CI)
66+
- To auto-fix formatting on commit: `ECHO_AUTO_FMT=1 git commit -m "message"`
67+
5668
## Communication
5769
- Major updates should land in `docs/execution-plan.md` and `docs/decision-log.md`; rely on GitHub discussions or issues for longer-form proposals.
5870
- Respect the temporal theme—leave the codebase cleaner for the next timeline traveler.

0 commit comments

Comments
 (0)