Companion to make-manifest.py that signs the output with an Ed25519
private key. Signs the literal manifest bytes — never re-serializes —
because the launcher verifies against exactly what the server delivers.
Warns if the private key file is readable beyond owner. Verified
end-to-end against the launcher's real public key and a tamper test.
Walks a client directory, sha256-hashes every file, emits a canonical
JSON manifest matching docs/update-manifest.md. Excludes runtime
artifacts (.log, .dxvk-cache, .pdb, .old) and the launcher is broken
out as a top-level field rather than an entry in files[]. Does not
sign; pair with a separate signer step.