docs: design the update manager + manifest generator #3

Merged
jakub merged 7 commits from jann/m2dev-client:claude/update-manager into main 2026-04-14 11:54:43 +02:00

7 Commits

Author SHA1 Message Date
Jan Nedbal
fdb9e98075 docs: add caddy updates vhost bring-up runbook
Step-by-step operator runbook for turning on updates.jakubkadlec.dev:
create the webroot, append the site block, validate the Caddyfile
before reload, watch for Let's Encrypt cert issuance, verify from an
external client, plus explicit rollback for every mutating step and a
catastrophic-recovery section in case Caddy drops all sites. Targeted
at Jakub (VPS operator) so Claude does not touch the running service.
2026-04-14 11:35:39 +02:00
Jan Nedbal
02061f6e07 docs: add caddy snippet for updates.jakubkadlec.dev
Caddy site block for the update CDN. Serves the signed manifest with
short TTL, content-addressed blobs as immutable, historical manifests
as immutable, and the Velopack launcher feed alongside. Caching rules
are calibrated so a new release is visible within a minute without
hammering the origin on thundering herds.
2026-04-14 11:22:32 +02:00
Jan Nedbal
b7e4514677 scripts: add manifest signer
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.
2026-04-14 11:22:32 +02:00
Jan Nedbal
759b31d390 docs: record prior art survey and switch to velopack for self-update
After a survey of existing Metin2 launchers, general-purpose
auto-updaters, and adjacent open-source game launchers, update the
design to:

- drop the hand-rolled rename-before-replace self-update path
- use Velopack for launcher self-update (MIT, modern successor to
  Squirrel.Windows, handles atomic replace, delta, Authenticode, AV
  friendliness out of the box)
- keep the custom asset patcher for the 4 GB game payload, which
  Velopack is not designed for
- reference runelite/launcher as the architectural template
- name Sparkle 2 and wowemulation-dev/wow-patcher as Ed25519 prior art

No Metin2 community launcher is worth forking; the ceiling of
published prior art is 'file list + sha256 + HTTP GET' and this design
is already above it. Greenfield confirmed.
2026-04-14 10:44:44 +02:00
Jan Nedbal
605f8765d5 scripts: add make-manifest.py manifest generator
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.
2026-04-14 10:36:24 +02:00
Jan Nedbal
6f70ef201a docs: add update manifest schema
Formal JSON schema for the release manifest, with canonical ordering
rules so signatures stay stable. Includes a small synthetic example
under docs/examples/.
2026-04-14 10:36:24 +02:00
Jan Nedbal
05af7e55b3 docs: add update manager design
Design for a content-addressed, signed manifest-based update system for
the Metin2 client. Launcher is a single entry point; server is static
files behind Caddy at updates.jakubkadlec.dev; manifests are signed with
Ed25519. Publishing starts manual in v1 and moves to Gitea Actions in v2.
2026-04-14 10:36:23 +02:00