# Private Freeciv source package

This source checkpoint accompanies the original Freeciv-web server/client browser
probe. It is not yet a public release or a completed clean-room rebuild trial.
Original server and web source pins and every downloaded archive hash are in
`scripts/expansion/freeciv-web-upstream.json`. The source manifest contains complete
upstream web/server/Jansson/curl archives, exact ICU/zlib source archives checked
against the pinned SDK's SHA-512 values, Emscripten runtime/port sources, the seven
modified/added native files, and editable Leaf integration/build/test scripts.
Original bundled Lua and other server dependencies are inside the server archive.
The integration archive includes build records and the exact client-tool lockfile;
client npm dependency files and their notices are supplied separately.

Join each archive's numbered parts in order, then verify its whole SHA-256 from
`manifest.json` before extraction. `verify-freeciv-sources.py` checks both fragment
and reconstructed hashes. Each fragment is at most 20 MiB for static-host delivery.
The package currently lives under private `artifacts/expansion/freeciv-web/`.

The existing build sequence is: prepare both pinned archives and all 18 upstream
patches with `prepare-freeciv-web.py`; build Jansson and curl with the respective
`build-freeciv-web-json.py` and `build-freeciv-web-curl.py` scripts; apply the local
socket boundary with `prepare-freeciv-local-network.py`; apply the two dynamic
save-vector accessors with `repair-freeciv-save-bits.py`; configure with
`configure-freeciv-web.py`, then compile with `build-freeciv-web.py` inside the pinned
Emscripten 5.0.7 image. Its ICU 68.2 and zlib 1.3.1 port archives are preserved.
The integration record also preserves the Meson cross/project definitions and
generated native build configuration. Meson 1.10.0 and Ninja 1.13.0 are host tools.

For the client, retain the original templates and protocol/event/sound/atlas
generators. Install the exact client npm lockfile (Handlebars 4.7.8 and
jquery-mousewheel 3.1.13); the atlas generator requires Pillow 11.3.0. Stage the
original worker/rules with `stage-freeciv-worker.py` and original static client
with `stage-freeciv-client.py`. Run the headless native Playwright flows against
`serve-freeciv-probe.py`. A clean end-to-end rebuild/provisioning recipe remains a
release gate; these records do not claim it has been proven.

Source availability alone does not establish redistribution clearance for every
asset. Preserve original copyright/license files. Server GPL, webclient AGPL,
linked-library notices, fonts and individual music/artwork terms require the final
distribution audit. No proprietary game files, credentials or player save files
are included in this package.


The static client stage also builds the original dynamic WebGL helper bundle using
the upstream POM's exclusions, retains its four shader scripts, copies the original
3D models/textures and records their unchanged hashes in `webgl-assets.json`.
Original editable model sources remain in the full web source archive. This does
not require a separate hosted renderer or inference service.


## Isolated rebuild runner

`rebuild-freeciv-clean.py` verifies/reassembles source fragments, extracts the editable
integration into a fresh `clean-rebuild/` tree, and preserves `source-manifest.json`.
It refuses to overwrite an existing attempt. Native dependency compilation, host
tools, original upstream patches, local platform/save-accessor patches, native
configuration/linking, fresh Pillow/npm tooling, original atlas generation and
worker/client staging have separate logs and progress records. The original working
probe is untouched. Configure/native scripts accept `FREECIV_EMSCRIPTEN_CACHE` so
this trial uses a distinct cache volume; normal builds retain the prior default.
The pinned SDK image is the toolchain; no existing project engine/dependency build
outputs are copied into the fresh tree. Downloaded source archives remain hash
checked. A final receipt compares native output hashes, then separate headless
browser verification is required. Do not infer build success from an active stage.

The first isolated trial is currently active: preparation, host-tool provisioning
Jansson/libcurl compilation and both declared patch steps passed; native server configuration is running.
See `clean-rebuild.log` and `clean-rebuild/progress.json`. Its exact initial ten-archive
input snapshot is preserved. The distribution package subsequently adds the verified
original Font Awesome source as an eleventh archive; later runners can also verify
and stage the font notices. The running trial continues from its original snapshot.


## First clean build completed

Every stage of the first source-fragment rebuild passed: fresh Jansson/libcurl,
original upstream preparation, platform/save-accessor patches, configuration,
native compilation/linking, fresh Pillow/npm tools, original atlas generation and
worker/client staging. `clean-rebuild/completed.json` records each successful stage.
The resulting client and engine were served separately for headless verification.

The JavaScript is byte-identical. Wasm remains 21,508,778 bytes, with fresh SHA-256
`90b20b6b2fdadd00733c5354e05da3189a08e12df9f101bb1e9ab6883352e3f5`, rather than the
working build's `0f8aa88d…`. Exactly 78 code bytes differ; data and other sections
match. `compare-freeciv-clean.py` verifies 7,779 prepared/native-added source files,
identical generated configuration/dependency receipts, and all native object files.
Only the two generated tolua objects differ: their type-registration call sets are
identical but differently ordered by the original Lua generator. All other generated
C content matches. Original `tolua_usertype()` creates each named type and its const
metatable independently. No generator, type API, rules or game RNG was changed to
force matching hashes. This is a working clean rebuild with explained original
build variability, not a claim of bit-identical Wasm reproducibility.

Seven fresh-build headless cases passed in `clean-browser.log`; the initial desktop
options case exceeded a five-second cold-start focus wait. That readiness assertion
now permits 15 seconds and the full desktop timed-turn/3D/sound flow passes in
`clean-options-final.log` (42.2 seconds). These results cover all eight existing
cases across the two runs; unchanged passing cases are reused. Fresh desktop/phone
native AI turns, city/movement, save/import recovery, local new-game flow, manual
and phone timed-turn/3D switching passed. Final lint/typecheck and Python/whitespace
checks pass. Performance and final public license/package verification remain.


## Preferred source for the six-track edition

Run `filter-freeciv-music-source.py` and `filter-freeciv-server-source.py`, then `package-freeciv-sources.py --verified-music`
to create private `source-six-track/`. It contains eleven complete archives in 22
verified fragments, replacing the raw web and server archives with verified browser editions.
The server edition omits eight unused SDL desktop font files; 6,813 retained
files have verified original hashes. Browser fonts, native code and rules remain
unchanged. Both receipts are required by source preparation.
Use `rebuild-freeciv-clean.py --source-directory <source-six-track>` to reconstruct
that source edition in a separate `clean-rebuild-six-track/` directory. It preserves
the edition receipt, checks the filtered web hash and original base pin, runs the
same upstream patch/compile sequence, then audits fonts/music and applies the staged
six-track presentation. The prepare script accepts the explicit `--verified-music`
flag, using the exact filtered archive receipt; ordinary raw-source builds retain
their original behavior.

The filtered source preparation has been directly tested: all 946 retained web
files match the originals. The native server code/configuration is unchanged,
so the completed clean native compile/browser evidence is reused. A second full
native compile solely for removing two unused music files has not been claimed.
Public staging and final license/performance checks remain separate gates.
