29 Commits
Author SHA1 Message Date
[email protected]andClaude Opus 5.5 8421d34846 Merge upstream/main into native/api-mods
Upstream added `pub mod lod_net;` to the old lib.rs module list, which this PR
moved to client_lib.rs: add it there. Upstream's new horizon-optifine
dependency is used by mobs/cem.rs, a reusable-client module, so it goes in
horizon-client-lib's manifest instead of horizon-client's.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 16:03:03 +01:00
[email protected]andCodex 9e18079acc fix(parity): migrate broad saved client target selections too
Co-Authored-By: Codex <[email protected]>
2026-11-01 14:41:20 +01:00
[email protected]andCodex 452910ffce fix(parity): keep saved probe selections compatible with the library split
Co-Authored-By: Codex <[email protected]>
2026-11-01 12:17:53 +01:00
dill-lkandCopilot d34380935d Fix parity remote startup failures
Co-authored-by: Copilot <[email protected]>
2026-11-01 09:05:53 +00:00
Ludovic MarieandClaude Opus 5.5 9c67dd3b76 tests: resolve the temp root in the parity dependency-path test
On macOS the temp folder is under /var, a symlink to /private/var. dependencies()
resolves each path before comparing it with ROOT, so an unresolved temp ROOT
dropped every file and the test failed on macOS (Linux CI didn't see it).
The real ROOT is already resolved.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 14:03:24 +01:00
levzzz 81a0e7e9a5 Merge pull request #3428 from d3grando/win-parity-sighup
parity: catch SIGHUP only where it exists, so parity.py starts on Windows
2026-10-29 17:53:13 +05:00
d3grandoandClaude Opus 5.5 2882f0764d parity: catch SIGHUP only where it exists, so parity.py starts on Windows
Python's signal module has no SIGHUP on Windows, so exit_on_termination
raised AttributeError and every parity.py command (--list, --changed,
--status, and pr_ready's local harness run) stopped before doing anything.
SIGTERM is still caught everywhere, SIGHUP wherever the platform has it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 05:41:08 +07:00
SlaVKsVolksandOpenAI Codex GPT-6.1 Terra 54360a74e3 fix(parity): normalize Windows dependency records for selection
Port the production path portability repair developed in Beyond onto original Horizon. Keep stored records and narrowed-root annotations intact; cover legacy local/shared records, changed probes and oracles, and reachability.

Co-Authored-By: OpenAI Codex GPT-6.1 Terra <[email protected]>

Co-Authored-By: OpenAI Codex GPT-6.1 Sol <[email protected]>
2026-10-28 09:58:22 -03:00
Ludovic MarieandClaude Opus 5.5 0879f3dbd2 parity: a host's exclude list also holds on its own CI runner
playhorizon's runner fails remote_fireball and remote_fireworks even alone and
at bare main (3b19c386c: 2 of 2 runs and the retry), while the Mac mini passes
them; every fork PR whose parity lands there stopped on them. The host's
exclude list only kept harnesses off workers sent there, not off the runner's
own jobs: platform_skips now adds the local host's exclude, skipped with its
reason unless named. The two harnesses join playhorizon's list; the Mac
mini's runner and the nightly audit (macOS) keep running them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 15:37:04 +01:00
Ludovic MarieandClaude Opus 5.5 83ee5c303b parity: game-window harnesses run alone on 4-CPU machines
On playhorizon's runner (CPUs 4-7, 4 harness slots, frames drawn on the CPU)
remote_fireworks still failed in #2215's job after #2589 and #2629: a
screenshot took ~1.5 s (58 ticks for two) beside three other harnesses. The
harnesses in parity_hosts.json's new solo list run alone there, after the
others; bigger machines are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 06:46:49 +01:00
Ludovic MarieandClaude Opus 5.5 1af4d0e432 parity: a workspace crate's features count through the sources they gate
A manifest line defining or turning on a workspace crate's feature no longer
makes the manifests count, if every source naming the feature (or one it turns
on) changed too, as in a split, where the new crate's files are all new.
#2215 (horizon-items with a test-support feature) now selects 209 harnesses
instead of 354.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 01:10:36 +01:00
Ludovic MarieandClaude Opus 5.5 1b1571ed6a parity: a crate split's manifest changes don't select every harness
Cargo.lock is a shared input and every harness depends on its crates'
Cargo.toml, so a crate split (#2160) selected all 352 harnesses although
its moved code reaches 123. With --changed, Cargo.lock and Cargo.toml
changes that only add, remove or move workspace crates (no registry or git
package, version, feature, dependency or build setting changed across them,
compared with the merge base) are left out; the moved code counts through
its own sources. Any other manifest change still counts, as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 23:30:59 +01:00
Ludovic MarieandClaude Opus 5.5 e82fa3d957 parity: retry a known flaky harness once, and say so
tools/parity_hosts.json's new `known_flaky` lists the harnesses that still flake for a cause not fixed yet,
each with its reason: dedicated_server (its Java client's 1.5 s step timer), remote_fireball (wall-clock
sampling) and world_reopen. One of them that fails runs once more from scratch, and a pass then counts.

Every retry prints a RETRIED line at the end of the run and in the CI job's summary, so a harness that
passes only on its retry stays visible on PR parity and parity-main alike. The existing fresh rerun of a
failure that reused oracle results is reported the same way. A known flaky harness skips that rerun and keeps
reusing oracle results, because flaking doesn't mean its cached oracle runs were wrong. Repeated runs
(--repeat, --flake-check) are never retried.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 20:27:34 +01:00
Ludovic MarieandClaude Opus 5.5 d01a621fec tests: two parity-runner tests pass on macOS
OracleReuseTests ran the shim through `#!/usr/bin/env python3` with a PATH
whose Python folder is Homebrew's, which names it only python3.13: the
shim wasn't found (127). The test now gives that PATH a python3 of its own.

test_report_rejects_sources_changed_during_a_run compared a resolved source
path with an unresolved temp root, and macOS's /var is /private/var.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 17:46:06 +01:00
Ludovic MarieandClaude Opus 5.5 e3e08911ba parity: run lan_integration only when named and in the nightly audit
The harness runs the whole lan_e2e suite: ~40 minutes on a loaded runner,
and single checks flake under load (barter, riding, shulker_bullets in one
run; cursor, falling in another, all passing on rerun). Selected by
--changed it would run on most gameplay pull requests and on parity-main.
tools/parity_hosts.json gains a named_only table that every automatic
selection (--changed, --failed, the default, --flake-check) leaves out;
naming the harness or --all (the nightly audit) still runs it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 10:48:58 +01:00
Ludovic MarieandClaude Opus 5.5 5034e4557d parity: clear rust-<name>-parity outputs after a pass, reuse oracles on CI
Disk: clear_large_outputs only looked at .local directories named after the
harness, so the 174 harnesses writing to rust-<name>-parity kept every dump
(86 GB in one runner checkout, 13 GB for state_provider alone). It now
clears those too, keeps vanilla outputs only up to 256 MB (larger ones cost
more disk than rerunning their oracle), and handles shard names.
collision, world and geometry dropped one mkdtemp run directory per run
(11 GB): each run now removes the earlier ones.

Time: harnesses inherited the runner's stdin, a pipe on GitHub's runner, and
parity_shim never reuses an oracle run whose stdin is a pipe, so oracle reuse
never worked on CI. Harnesses now get /dev/null.

CI: parity.yml falls back to the head's own selection when the names main's
`--list` printed don't match its summary count.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 00:44:22 +01:00
Ludovic MarieandClaude Opus 5.5 cb1c9e6935 Parity: a pass trims only its own .local directory
decorated_region compiles its oracle into chunk-generation-parity; when it
passed while chunk_generation was still running, the trim deleted
chunk_generation's dumps mid-run (FileNotFoundError on
*-987654321987-full.txt in CI on #1569, #1571 and #1584).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 23:09:48 +02:00
Ludovic MarieandClaude Opus 5.5 0b581f9ffe Give each crate's probe example its own target name
horizon-client, horizon-world and horizon-protocol each had an example
named `probe`. Cargo copies every crate's examples into one
<profile>/examples/ directory, so parallel parity harnesses sharing a
target dir could run another crate's probe (CI parity run 40055656303:
command_parse ran the horizon-world dispatcher). The examples are now
client_probe, world_probe and protocol_probe ([[example]] in each
Cargo.toml; the files stay where they are), and every harness builds
and runs its own crate's name.

tools/parity.py recognises the new names when it counts the probes a
harness ran, and renames the old `probe` in recorded artifacts to the
crate's target (from the record's -p, else its probe sources), so the
prebuild still builds them instead of dropping them as unknown.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 08:08:18 +02:00
Ludovic MarieandClaude Opus 5.5 ed847d43dc Keep the probe list out of the harnesses' dependencies
main.rs now only lists the probes; dispatch.rs runs them. The runner leaves
main.rs out of a probe-binary harness's dependencies and keeps dispatch.rs,
so adding a probe no longer reruns (or flake-checks) every harness of its
crate. It also follows crate::<probe> references between probes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 16:30:38 +02:00
Ludovic MarieandClaude Opus 5.5 7092f16a06 horizon-world probes: one copy of the helpers they shared
Now that the probes are modules of one binary, the helpers copied between
them live once in examples/probe/support: the collision probes' shape
printer (emit, values, box_values, bounds, 8 copies each), the canonical
NaN bits of f64 and f32 (50 copies), the registry JSON-to-NBT reader (15)
and the JSON block position (4). -1,097 lines of copies.

f64::NAN.to_bits() is 0x7ff8000000000000, the literal some copies used,
so every probe prints the same bytes.

tools/parity.py follows include!: three probes include another probe's
source, and stay dependent on it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 16:30:38 +02:00
Ludovic MarieandClaude Opus 5.5 fdae4b895c horizon-world probes: one binary, probe <name>
The 168 horizon-world examples the parity harnesses run become modules of
one example, examples/probe, that dispatches on its first argument;
crate::args() gives each the command line its example saw. Linking ~170
binaries, each instantiating horizon-world's generics again, was most of
the parity job's probe build (review plan, section 1).

The harnesses build `--example probe` and run `probe <name> ...`.
tools/parity.py counts only the probes a harness ran, and the support
modules they name, as its dependencies, so editing one probe still reruns
only its own harnesses (and PARITY_RUST_SCOPE keeps working).

The six manual tools (benches, loot_fill, structure_blocks, vanilla_diff,
attribute_memory, behaviour_load_profile) stay separate examples.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 16:30:38 +02:00
Ludovic MarieandClaude Opus 5.5 7c42cc63ce parity: leave out of the prebuild probes that no longer exist
A record naming an example since renamed or deleted made the whole Cargo
run fail ("no example target named ..."), so no probe was prebuilt and
every harness built its own: the probe binaries rename ~250 of them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 16:30:27 +02:00
Ludovic MarieandClaude Opus 5.5 ac54227465 parity: prebuild probes with each harness's own package selection
The probe prebuild ran `cargo build --workspace --examples --bins` (or
named targets with --workspace). The harnesses build with `-p <crate>`, and
Cargo unifies features over the selected packages: under --workspace,
flate2, libc, memchr, syn, thiserror, postcard and digest get other
features for horizon-world, and horizon-mods (pack) and horizon-telemetry
(upload) for horizon-client. So every probe the prebuild made was a
variant no harness used, and each harness rebuilt its crate and its probe
again while the others waited on Cargo's lock.

Record each probe with its command's package and feature flags and
whether that command builds examples (which turns dev-dependencies on),
and prebuild one Cargo run per such selection. --bins and --examples are
recorded too, so the fast-profile horizon-client build that
save_roundtrip and world_reopen run is prebuilt as well. A harness that
never ran here takes its probes from the shared dependency lists instead
of a build of all ~275 examples.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 14:11:22 +02:00
LookImEcho-Rick b9d61e5701 Make pr_ready portable to Windows 2026-10-17 15:48:49 -05:00
Ludovic MarieandClaude Opus 5.5 874d111d60 checks: cached verify, and a parity job on the Mac mini for the harnesses a PR can affect
verify keeps its dependencies and workspace build in a cache saved by main's runs (Swatinem/rust-cache).
The new parity job runs on the Mac mini's self-hosted runner (label horizon-game), which holds the
maintainer's own Minecraft files: tools/ci/vanilla-data.sh links .local/ to the runner's copy and prepares
the resources with the pull request's own horizon-prepare, once per preparer version; then
tools/parity.py --changed <base> runs only the harnesses whose traced dependencies changed since the merge
base and that have no pass for their current inputs. A fork's pull request runs it only when a maintainer
adds run-parity, once per label, on the commit it had then.

parity.py: --changed REF, and linux_only in tools/parity_hosts.json for harnesses that differ on other
platforms for a reason that is not a Horizon bug (skipped there with the reason, unless named).

docs/release-flow.md starts with the pull request checks and merging.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 22:17:20 +02:00
Ludovic MarieandClaude Opus 5.5 f5ab40d415 Shard harnesses, narrow their Rust sources, keep the desktop light
parity.py:
- A harness declaring PARITY_SHARDS = N runs as N entries, NAME#1..NAME#N,
  each told its share through PARITY_SHARD; NAME selects them all.
- PARITY_RUST_SCOPE lists the Rust sources a harness's probes can reach.
  It applies only if closed (nothing in it names a module, crate-root
  re-export or macro outside it, and nothing outside implements anything for
  its types); crate roots then count without their other module declarations.
- Bytecode caches no longer count as dependencies.
- With other hosts, this machine runs 3 harnesses at once and only those
  under 800 MB, admitted against the memory free at each start; hosts can
  exclude harnesses and run at a nice level.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 16:41:51 +02:00
Ludovic MarieandClaude Opus 5.5 d061bdf2fb Share harness passes between worktrees and cap harnesses machine-wide
A pass is keyed by the content of the harness's dependencies, so it is
also valid in any worktree with the same files. Passes are published to
parity-shared/ beside the shared vanilla data, and a worktree adopts one
whose key matches its own files instead of running the harness: an
agent's gate only runs what its own changes affect, instead of the whole
suite from scratch. Every runner on the machine also shares
PARITY_MACHINE_JOBS slots, so several agents' gates can't overload it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 16:42:52 +02:00
Ludovic MarieandClaude Opus 5.5 13759ef16b Reuse unchanged vanilla oracle runs, and keep test games silent
tools/parity_shim.py stands in for java and javac in harness runs: it
records each oracle run's outputs and the content of every file under the
paths its arguments name, and replays the run while those are unchanged.
After a Rust-only change a harness only pays for its Rust side
(block_update 53 s -> 5 s). A harness that fails while reusing oracle
results is rerun fresh, and stops reusing them if that passes; --all and
--fresh never reuse them.

Harness probes built in the dev profile are optimised (overflow checks
and debug assertions kept), and the chunk generation harness runs its
vanilla and Horizon sides concurrently.

HORIZON_NO_AUDIO keeps the game off the speakers; tools/parity.py sets it,
since the save round-trip harness launches the game on a virtual screen.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 15:43:26 +02:00
Ludovic MarieandClaude Opus 5.5 6396e8c161 Run the vanilla harnesses in parallel, only when their inputs change
tools/parity.py traces each harness (its Python, Java oracle sources and
the Rust sources of the probes it runs, from Cargo's dep-info) and reruns
it only when one of those, the vanilla artifacts or the toolchains change.
Harnesses run in parallel within the available memory, and their probes
build without LTO and with 16 codegen units into .local/parity-target: a
one-line change rebuilds every horizon-world probe in 3 seconds instead of
122. The full suite takes about 20 minutes instead of an hour.

tools/gate.py is the check a branch passes before integration, and
tools/supervise.py manages the per-area worktrees: status, new worktrees,
saving unfinished work, and integrating a branch only when the gate passes.

Harnesses find probes through lab.cargo_target() instead of a hard-coded
target/, the save round-trip harness builds the binaries it launches, and
the mob AI harness now fails on divergences like every other harness
(--report-only keeps the old behaviour). Debug builds keep line tables
only, so worktrees stay small.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 15:05:36 +02:00