# Publishing the Earthsiege investigation

This builds the full research archive for `https://lostengines.com/earthsiege/`.
It uses the same Markdown renderer, report styling and rsync arrangement as the
Darker and TFX investigation sites. Earthsiege Exhumed remains the shorter
introduction; the archive landing page links to it.

## Commands

From the project root:

```sh
./publish.sh --build-only   # Build and verify web-stage; no server connection
./publish.sh --dry-run      # Build, verify, then preview the remote rsync changes
./publish.sh                # Build, verify, then upload
```

The upload destination is:

```text
root@lostengines.com:/var/www/lostengines.com/public/earthsiege/
```

Rsync uses the contents of `web-stage/`, including its manifests, and removes
stale remote files with `--delete-delay`. SSH uses your existing configuration.
The script runs from its own project root, regardless of the caller's directory.
A failed build or verification stops the upload.

Node.js 22 or newer and npm are needed for staging. The script installs the
locked dependencies with `npm ci --prefix tools/publish`. Uploading also needs
rsync and SSH access to the server.

To inspect the result locally:

```sh
python3 -m http.server 8767 --bind 127.0.0.1 --directory web-stage
```

Open `http://127.0.0.1:8767/`. The generated site uses relative links and also
works under the production `/earthsiege/` prefix.

## What gets staged

- The exact files in `analysis/publication-manifest.json`, with their hashes
  checked against the curated copy.
- The reports, manuals, small linked tools and site assets named in `files.json`.
- HTML versions of the Markdown files, a searchable report directory, a landing
  page and the staging manifests.

The source Markdown remains available through a download link on each report.
Rendered reports have heading anchors, a table of contents and scrollable data
tables. Markdown links are rewritten to their HTML equivalents. Viewer scripts
and embedded data are kept intact. Dynamic download links follow the same file
selection as static report links.

The builder never traverses `work/`, `installs/`, `install media/` or `extracted/`.
A reference to an unpublished local artifact opens an explanation page. Links to
the C++ repository open on GitHub. A missing displayed image or script fails the
build rather than producing a broken page or automatically widening the upload.

To publish newly completed findings, update the curated analysis first:

```sh
python3 tools/publish_analysis.py
./publish.sh --build-only
```

The staging build itself does not need `work/research/`. To add a report, update
`files.json`; to add a viewer asset, use the curated analysis allowlist described
in [the research layout guide](../../docs/RESEARCH_LAYOUT.md).

## Rebuilding and verification

The builder assembles a temporary sibling directory and checks local links and
heading targets before replacing `web-stage/`. A failed build leaves the previous
stage in place. It refuses to replace source directories, symlinks or nonempty
output directories without its ownership marker. Staged files are separate
copies, so HTML rewriting cannot modify the analysis sources.

`build-manifest.json` records SHA-256 hashes for every staged file. Verification
also rejects unlisted files and a total size above the 2 GiB limit (including lossless expansion music auditions):

```sh
node tools/publish/verify.mjs
```

An alternative empty or previously managed output directory can be used for
local checks:

```sh
node tools/publish/build.mjs --output /tmp/earthsiege-web-preview
node tools/publish/verify.mjs /tmp/earthsiege-web-preview
```

The rsync wrapper always uploads the standard `web-stage/` directory. Generated
staging directories and `node_modules` are ignored; the publisher source and npm
lockfile are retained with the investigation.

The optional Chromium smoke check exercises the generated site under its
`/earthsiege/` prefix, including model textures, mission scenery, cockpit startup
frames, fonts and rewritten links:

```sh
.venv/bin/python tools/publish/check-browser.py
```

It uses the existing research browser helper and writes screenshots and results
to `work/publication-check/`. It needs Chromium and the Python `websockets`
package; these are not required to build or upload the site.

## Social preview

The archive home page includes static Open Graph and large-image card metadata
for `https://lostengines.com/earthsiege/`. Its 1200 × 630 JPEG is published at
`https://lostengines.com/earthsiege/site-assets/earthsiege-social.jpg`.

The finished `earthsiege-social.jpg` is a normal publisher input; building and
uploading the archive need no browser or image tools. The editable layout is
`social-card.html`. Its source image, `social-herc.png`, is the Samson capture
from Earthsiege Exhumed’s model viewer, using original geometry, textures and
equipment. It is retained here so regeneration does not depend on that checkout.

To regenerate the JPEG, run from the repository root:

```sh
.venv/bin/python tools/publish/render-social.py
```

This uses the existing local Chromium browser helper and Python `websockets`.
It renders at 1200 × 630 with device scale 1 and saves a JPEG below GitHub’s
1 MB image limit. The same file can be uploaded in the repository’s **Settings >
Social preview > Edit > Upload an image**. GitHub’s repository preview is set
separately from the website’s Open Graph tags.

Publish the image and updated index together before checking a shared website
link. Services can retain a cached preview after the site changes.
