Skip to content

Take data/visuals.ron out of rules_hash (ADR 0003) - #51

Merged
tonianev merged 3 commits into
mainfrom
claude/confident-hopper-ho6dz1
Oct 27, 2026
Merged

tonianev merged 3 commits into
mainfrom
claude/confident-hopper-ho6dz1

Conversation

@tonianev

Copy link
Copy Markdown
Owner

What and why

This is the first PR of the pre-stream art pass. That pass pulls M7's look items forward: CC0 KayKit models through data/visuals.ron, a minimap, a draw-call counter and the Inter font. The owner approved it on 2026-10-21, and on 2026-10-26 took every default of its plan.

Owner decision 1 settles what M4b decision 5 left open: data/visuals.ron leaves rules_hash, as its own small PR, before any art lands.

Why: the sim never reads visuals, just as UI strings were already outside the hash. While visuals were hashed, every model swap or 40 m readability tweak during the art pass would have cost a rules_version bump and a re-record of all 11 fixtures. After this PR, a look change is a one-line RON edit.

Changes

  • ADR: docs/adr/0003-visuals-outside-rules-hash.md (Accepted, 2026-10-26: Context, Decision, Alternatives, Consequences), with its row in the ADR index.
  • The change: Rules::visuals is now #[serde(skip)], so rules_hash no longer covers data/visuals.ron.
    • Rules::load still parses and validates the file, so data-check still fails on a bad or missing entry.
    • The replay format and SIM_VERSION are unchanged.
  • Tests:
    • The visuals clause of the hash-coverage test is inverted into rules_hash_ignores_visuals_ron, which checks an in-memory change, an emptied Visuals, and an edited file copy.
    • New bad_visual_still_fails_to_load_naming_file_and_field.
    • Four new data-check binary cases: a kind with no visual, an out-of-range look, and a missing visuals.ron each exit 1. A valid look edit prints the same OK line, rules_hash included.
    • Mutation runs confirm the tests catch both ways back.
  • Version bump: rules_version 24 to 25 (reason: "data/visuals.ron leaves rules_hash (ADR 0003); no sim change"), with just rerecord in the same commit.
    • Every .hash file is byte-identical. In each of the 11 .eonreplay files, only header bytes 8 to 17 change: the rules_version byte and the rules_hash varint.
    • A per-tick hash dump (old binary and data against new) has 0 diff lines for move_500, combat_skirmish, capture_seat and m5_first_match.
  • Demonstration: after the bump, the Skirmisher's height_tiles_x100 was edited from 150 to 160 in visuals.ron.
    • sim-cli verify of combat_skirmish and m5_first_match still prints OK, and the rules_hash is unchanged.
    • The control edit, acquire_range_tiles from 6 to 7 in rules.ron, prints RULES CHANGED.
    • Both edits were reverted.
  • Docs:
    • DETERMINISM, DATA_FORMAT, data/README.md, data/rules/README.md (now at 25, worked example 25 to 26), ART_STYLE, ARCHITECTURE, CONTRIBUTING, design/README and ai.md;
    • the visuals.rs and lib.rs docs;
    • a ROADMAP Notes line under M4b decision 5 (no acceptance line touched);
    • HANDOFF and PLAYTEST.

Timing trap for the owner's M5b match

A replay recorded before this bump (rules_version 24, main e84af88) reports RULES CHANGED on this build and every later one. Verify it with the build that recorded it.

No command prints a header's rules_version. Instead, the replay 0x… value in the RULES CHANGED line names the build: 0xb231ab753cb4197e is rules_version 24 (e84af88). docs/PLAYTEST.md says this in the M5b owner checklist.

Review

An adversarial review across determinism, tests and docs confirmed 7 findings, all docs. They are fixed in 11f1bbc and ad41df9. Some lines still said "every RON edit changes rules_hash", one byte count was wrong, and one doc relied on reading a header's rules_version. One finding was refuted: a mechanical guard against the sim reading visuals is not needed, because the sim and ai crates never reference Rules::visuals.

Tier

Data PR (files under data/)

  • cargo run -p sim-cli -- data-check data passes (OK rules_version=25 rules_hash=0xfb0d0b8986fc8865 resources=4 units=8 buildings=8 ages=3 techs=12 side_techs=2 factions=1 personalities=1 build_orders=1 maps=plains_1v1 strings=en)
  • cargo test -p sim passes (6.7 to 7.1 s warm)
  • rules_version is bumped with a one-line reason (24 to 25; every .hash unchanged)

Docs PR (files under docs/, README.md, data/*/README.md)

  • typos passes (inside just ci)
  • Links are relative paths and resolve

Code PR (files under crates/, scripts/, .github/)

  • just ci passes locally (Linux; cargo-machete and cargo-deny are not installed there, but CI runs them)
  • A test or a replay fixture covers the change: rules 128 tests, data_check 13 tests, all 11 goldens verified
  • No f32, f64, HashMap, HashSet or Instant in crates/sim, crates/rules, crates/ai
  • No Bevy, glam, wgpu or winit dependency outside crates/game

Licensing and disclosure

  • I agree that, unless I explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by me, as defined in the Apache-2.0 license, shall be dual licensed as MIT OR Apache-2.0, without any additional terms or conditions (CONTRIBUTING.md).
  • AI assistance: I have disclosed any AI-assisted parts of this change per AI_CONTRIBUTIONS.md, and I have reviewed and tested them myself.

How to verify

$ cargo run -p sim-cli -- data-check data
OK rules_version=25 rules_hash=0xfb0d0b8986fc8865 ...
$ sed -i 's/height_tiles_x100: 150)/height_tiles_x100: 160)/' data/visuals.ron
$ cargo run -p sim-cli --release -- verify crates/sim/tests/fixtures/combat_skirmish.eonreplay
OK final_hash=0x9c42bb7bfd4dcef3 ticks=3000      # a look edit no longer means RULES CHANGED
$ git checkout data/visuals.ron
$ just verify                                     # all 11 goldens, hashes unchanged

Generated by Claude Code

Bump rules_version to 25: data/visuals.ron leaves rules_hash (ADR 0003); no sim change.

Rules::visuals becomes #[serde(skip)], so rules_hash stops covering
data/visuals.ron, while Rules::load still parses and validates it and
sim-cli data-check still fails on a bad, missing or unknown entry. The
sim never reads the file; the UI strings are the precedent. The owner
took this default of the art pass plan on 2026-10-26.

- docs/adr/0003-visuals-outside-rules-hash.md (Accepted) and its index row.
- rules: rules_hash_ignores_visuals_ron replaces the visuals clause of
  rules_hash_is_stable_and_covers_attached_files; a bad visual still
  fails to load. sim-cli data_check: a kind without a visual, an
  out-of-range look and a missing visuals.ron exit 1; a valid look edit
  prints the repository's own OK line, rules_hash included.
- just rerecord: the eleven fixtures change in the header's
  rules_version and rules_hash only (10 bytes); no .hash file moved.
- Docs: DETERMINISM, DATA_FORMAT, data/README, data/rules/README,
  ART_STYLE, ARCHITECTURE, CONTRIBUTING, the fixture README, the
  visuals.rs module doc, the visuals.ron comment and the rules_hash doc;
  a ROADMAP Notes line under M4b decision 5; the timing trap for
  replays recorded before the bump in PLAYTEST and HANDOFF.
Since ADR 0003, data/visuals.ron and the UI strings under
data/rules/strings/ are not in rules_hash, so an edit to either needs no
rules_version bump and no just rerecord. data/README.md ("Checking your
change"), the worked example in data/rules/README.md, the balance-change
note in docs/design/README.md and the versioning row in docs/design/ai.md
still said every RON edit changes the hash. They now name the two
unhashed files.

The rules_version row of the rules.ron table in data/rules/README.md now
shows the current value, 25, instead of the stale 22.

Docs only: no data, code or fixture change, so no rules_version bump.
No command prints a replay header's rules_version: verify's RULES
CHANGED line shows only the replay's and the loaded rules_hash, and
data-check prints the loaded data's version. DETERMINISM, the ROADMAP
M4b note, ADR 0003, HANDOFF and PLAYTEST now say that the "replay 0x..."
hash names the recording build, because data-check at that commit prints
the same hash (0xb231ab753cb4197e is rules_version 24, e84af88).
DETERMINISM's verify-output table and its regeneration policy also give
the pre-bump replay as a second cause of RULES CHANGED.

DETERMINISM's ADR 0003 history called the rules_hash varint 9 bytes long.
It is 10 bytes, at offsets 9 to 18. Its last byte, 0x01, is the same in
both recordings, so 10 bytes change in all: offsets 8 to 17.

HANDOFF now says M5b is merged as PR #47 (e84af88), in its state
paragraph and in the table. It had still described M5b as waiting on the
PR.

Docs only: no data, code or fixture change, so no rules_version bump.
@tonianev
tonianev merged commit 15f1616 into main Oct 27, 2026
5 checks passed
@tonianev
tonianev deleted the claude/confident-hopper-ho6dz1 branch October 27, 2026 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants