Skip to content

Commit 6121ed6

Browse files
committed
Close the cross-platform comparison and make it a standing gate
A Windows capture and a Linux capture of the same pinned world canonicalized to identical bytes. The fingerprints agree on all 157 chunks both observed, with no chunk seen by only one side and nothing either could not account for, and the two files are byte-identical at 24,677 bytes. The game test pins the seed, generator and view distance, so a difference could only have come from the encoder. This was the last open item in the capture milestone and the reason builds went out as pre-releases. The canonical encoding is now platform independent by measurement rather than by construction. The Linux fingerprint is committed as the reference. The gate that has been sitting inert since it was written now has something to compare against, and was checked in both directions: identical input passes, a single altered state digest fails with exit 1 and names the chunk. CHANGELOG carries a v0.1.0 entry. It leads with the verification rather than the features, records the client-thread cost including the 15.2 ms worst tick that can drop a frame, and keeps saying what has not been verified. Tagging is a separate decision.
1 parent 3e95401 commit 6121ed6

5 files changed

Lines changed: 264 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,50 @@
11
# Changelog
22

3+
## v0.1.0
4+
5+
The verification the earlier builds were waiting on has been done. Both
6+
pre-releases said so plainly; this one says it is finished.
7+
8+
### The thing that was outstanding
9+
10+
The same observed world state, captured by a Windows client and by a Linux
11+
client in CI, canonicalizes to identical bytes. The two fingerprints agree on
12+
all 157 chunks both captures observed, and the two files are byte-identical.
13+
The game test pins the world seed, generator and view distance, so a difference
14+
between the two could only have come from the encoder.
15+
16+
That reference is now committed. CI compares every Linux capture against it and
17+
fails on a disagreement rather than reporting one after the fact.
18+
19+
### Also in this release
20+
21+
- **A whole spool imports in one command.** `ingest-spool` takes in every ready
22+
bundle and clears them once the archive has them, because a spool nothing
23+
empties grows until the disk does.
24+
- **The spool stops growing without a limit.** It refuses to write past its
25+
budget and never deletes what it already holds to make room, and identical
26+
component bytes are stored once instead of once per bundle.
27+
- **`status` says what an archive holds and what to do next**, including which
28+
servers still have no publication decision.
29+
- **Errors say what to do.** An empty selection used to give one timestamp
30+
whether the archive was empty, the server name wrong, the dimension wrong, or
31+
the moment too early. Those read differently now.
32+
- **The adapter reports itself in game.** Whether capture is on, under whose
33+
name, and what the previous session captured including anything dropped.
34+
35+
### Measured, and not comfortable
36+
37+
Capture costs the client thread a mean of 1.08 ms on the ticks that do work,
38+
and 15.2 ms on the worst one. A frame at 60 fps has 16.7 ms. The worst case is
39+
one full-height chunk and it is bounded, but it can cost a frame, and
40+
`docs/status.md` says so rather than reporting the mean and stopping.
41+
42+
### Still not verified
43+
44+
No converted world has been opened in an older release, and there is no
45+
committed profile for any release other than 26.2, because building one
46+
requires that release's own artifact.
47+
348
## v0.1.0-alpha.2
449

550
Fixes what the first build got wrong about presenting itself. No change to how

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The repository contains two deliberately separate systems:
1515

1616
The Fabric process never opens or mutates an archive. The Go importer is the only boundary that turns a capture bundle into archive objects, observation records, and chunk indexes.
1717

18-
> **Development status.** The archive core, canonical encoders and decoders, epoch selection, Anvil export, release profiles, and publication policy are implemented and automatically tested. Reconstruction has been verified end to end against an unmodified Minecraft 26.2 client: an exported chunk loads and renders correctly, including negative sections and block state properties. Capture has been exercised against a real 26.2 client as well, and the client game test runs headless in Linux CI on every push. What has not been done is a digest comparison between captures taken on different platforms, which is why builds are published as pre-releases. See [`docs/status.md`](docs/status.md) for every claim and the evidence behind it, and [`CHANGELOG.md`](CHANGELOG.md) for what a given build contains.
18+
> **Development status.** The archive core, canonical encoders and decoders, epoch selection, Anvil export, release profiles, and publication policy are implemented and automatically tested. Reconstruction has been verified end to end against an unmodified Minecraft 26.2 client: an exported chunk loads and renders correctly, including negative sections and block state properties. Capture has been exercised against a real 26.2 client as well, and the client game test runs headless in Linux CI on every push. A Windows capture and a Linux capture of the same pinned world have been compared and canonicalized to byte-identical results, so the encoding is platform independent by measurement rather than by construction; that reference is committed and CI fails on a future divergence. See [`docs/status.md`](docs/status.md) for every claim and the evidence behind it, and [`CHANGELOG.md`](CHANGELOG.md) for what a given build contains.
1919
2020
## What makes this different from a world downloader
2121

docs/roadmap.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ Exit criterion: the same fixture ingested on different machines produces identic
3636
- [x] crash-safe spool using capture-bundle v1
3737
- [x] controlled vanilla integration fixture
3838
- [x] Linux client record
39-
- [ ] cross-platform digest comparison
39+
- [x] cross-platform digest comparison
4040

41-
The integration fixture is now an automated client game test rather than only a written procedure. It passed against a real 26.2 client on Windows: 158 ready bundles, none dropped, all imported, idempotent on repeat, `fsck` clean. The same test runs headless in Linux CI on every push. What remains is comparing the two: CI does not publish the bundles it produces, so no run has yet shown that the same world state yields identical digests on both platforms.
41+
The integration fixture is now an automated client game test rather than only a written procedure. It passed against a real 26.2 client on Windows: 158 ready bundles, none dropped, all imported, idempotent on repeat, `fsck` clean. The same test runs headless in Linux CI on every push.
4242

43-
Exit criterion: **met on Windows.** A live multiplayer session produced a deterministic local archive that then exported to a playable world. See [`status.md`](status.md).
43+
The two have now been compared. A Windows capture and a Linux capture of the same pinned world produced byte-identical fingerprints across all 157 chunks both observed. The reference is committed, so a future divergence fails the build instead of waiting to be noticed.
44+
45+
Exit criterion: **met.** A live multiplayer session produced a deterministic local archive that then exported to a playable world, and two platforms canonicalized the same observed state identically. See [`status.md`](status.md).
4446

4547
## Phase 2 — playable reconstruction
4648

docs/status.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ The capture game test is the standing form of this check. It passes from a clean
3232
- **Attestation.** An ed25519 signature over an observation id verifies, and fails when moved to another observation, when the signature is altered, when the key is swapped, or when it was made without the domain separator. The archive refuses to store an attestation that does not verify. A valid signature from an unregistered key is reported as valid and unrecognised rather than as an endorsement, and a second key cannot register a label another key already holds.
3333
- **Object existence negotiation.** Two mirrors work out what to transfer from their fingerprints alone, in both directions, without either opening the other's archive.
3434
- **Archive exchange.** Two archives that never shared a database converge to the same manifest root by exchanging transfer bundles in both directions, exercised on the two real capture sessions on disk. A bundle whose object bytes were substituted is refused, and so is one whose observation was reattributed to another contributor, because the identity no longer matches the record. A repeated import changes nothing.
35+
- **Cross-platform digest agreement.** The same observed world state, captured by a Windows client here and by a Linux client in CI, canonicalized to identical bytes. The two fingerprints agree on all 157 chunks both observed, with no chunk seen by only one side and no state either could not account for, and the two files are byte-identical at 24,677 bytes. The game test pins the world seed, generator and view distance so that a difference between the two could only have come from the encoder. That reference is committed, so every CI run now compares against it and fails on a disagreement rather than reporting one.
3536
- **Spool storage.** Identical component bytes are stored once. Twenty bundles declaring 199,671 bytes occupied 36,879 on disk, identical components resolved to a single file, and deleting one bundle after import left a bundle sharing its bytes readable. A 40 KB budget stopped capture after 32 bundles and left all 32 in place; the same writer with a large budget kept going.
3637
- **Player-facing notices.** The text shown in game is built with no Minecraft type in it and is asserted directly: the disabled notice names the file and the setting, a clean session does not mention drops, a lossy one names them separately from the total, and a session that captured nothing does not read like capture being switched off. The class that draws them holds no logic.
3738
- **Redaction.** Contributor and region scopes withhold matching observations from everything the archive builds for sharing. Purging removes observation records, removes objects nothing else references, and reports every object it kept along with the surviving contributor that still needs it. An interrupted purge is journalled and finished when the archive is next opened, because either half-done order leaves a state the integrity check rejects.
@@ -56,12 +57,6 @@ The same game test runs in Linux CI on every push, headless under a software ren
5657

5758
## Not verified
5859

59-
**Cross-platform digest agreement.** The game test passes on both Windows and Linux, and the comparison between them is now mechanised: `worldledger fingerprint` reduces a capture to state and component digests alone, and Linux CI publishes its fingerprint as a build artifact. What has not happened is the comparison itself, against a Windows capture of the same fixture. Until it does, the canonical encoding is platform independent by construction and not by measurement.
60-
61-
One thing already measured is worth separating from that claim. Two capture sessions on one machine, under different contributors and session identifiers, agreed byte for byte on every one of the 40 chunks they both observed, and on 50 of the 52 distinct components between them. The one chunk whose states differed differed by absence: the shorter session left before the fixture was applied, so it holds the earlier state and not the later one. That is a difference in what was caught rather than in how it was encoded, and the comparison reports the two separately.
62-
63-
Those sessions shared a world, so they say nothing about worlds generated independently. The game test's server sets no seed by default, which means two fresh worlds need not contain the same terrain at all. It now pins the seed, the generator, and the view distance, because otherwise a difference between two platforms could not be attributed to the encoder rather than to the world each one happened to generate.
64-
6560
**Cross-release conversion.** Translation has unit tests and an end-to-end run against a synthetic target profile, but no converted world has been opened in an older release. There is no committed profile for any release other than 26.2, because building one requires that release's own artifact.
6661

6762
**Performance on the client, in a real session.** The cost is now measured rather than assumed, and the first figure is not comfortable. A game test run on a Windows client reported:

0 commit comments

Comments
 (0)