Archnemix

Technical decisions

The decision atlas

Every choice, on the record.

Twenty-one decisions shaped Archx. Each one below states the problem, what we chose, what we rejected and why, the honest pros and cons, and the measured evidence — with local widgets where a mechanism is easier to feel than to read about. Nothing here is marketing: where a choice costs something, the cost is printed.

↳

One image, start to finish

Follow a private master through the recommended server-delivery ({ id }) path: permission first, pixels second. Choose a viewer mode, renderer/extraction overrides, and server options — the moving picture, packets, and stage notes change with that configuration.

Animated flowchart — master in, protected view out

Illustrated server configuration: the optional server branches start switched on so every path is visible. Each toggle prints the base middleware default; switch a branch off to see what that deployment would skip. The tile animation uses the page’s real plan-v2 builder, but the drawing itself is explanatory — no image, token, or server request leaves this page. Stage timing is budgeted by visible beats and active branches rather than one fixed interval: simple holds are short, while gates, scans and transforms get sequential time; each stage’s viewing budget is printed with its step below. Those budgets are reading time, not server runtimes.

Viewer mode
Renderer flag
onExtract
Server options in this illustrated delivery

One-time tokens are on by default in the middleware; this illustrated token is also sender-constrained to the browser’s proof key.

Stage 1 of 10
SERVER · PRIVATE

1 · The master goes in — and stays there

The original is indexed by image ID in a masters directory outside every public root declared to Archx. Startup refuses overlap with declared roots; undeclared host mounts remain the operator’s responsibility. No Archx route returns this file.

Shield — the default viewer

Shield uses Canvas 2D when the renderer is left on auto. A private working canvas unscrambles the entitled derivative at backing-store size, bakes any configured client watermark and per-session forensic blocks, paints the visible canvas, then zeroes the working canvas. Instance-level readback returns the selected decoy; a prototype-call readback additionally needs an origin-tainted canvas (or promotion to WebGL) to be browser-blocked.

Effective renderer
Canvas 2D (auto from Shield)
What leaves the server
AES-256-GCM-encrypted .archx scrambled derivative · no master
Programmatic readback
Black branded decoy from instance readback APIs

Scope: this chart follows token delivery. Precomputed { assetId } delivery is deliberately different — derivatives are scrambled at build time and selected from a manifest on static/CDN hosting, so there is no per-view authorize, mint, redemption or Sharp stage. Plain URL/Blob sources likewise skip the server boundary and must not be described as if they had one.

Preset names are bundles over this same flow

Presets do not create separate pipelines. They choose a base mode and pre-fill ordinary flags; any flag can still be overridden when the preset object is spread.

PresetBase pathWhat the bundle changes
gallery / catalogLiteCatalog sampling, canonical width buckets, batched token mints, cache/unload budgets for image-heavy pages.
editorialShieldOriginal-quality request profile with the default Canvas path unless a renderer flag says otherwise.
commerce / marketplaceVaultWebGL path and capture shield; marketplace also enables batched mints for grids.
performanceShieldForces Canvas, catalog sampling, batched mints and smaller bitmap-cache budgets.
maxProtectionVaultForces WebGL, requires proof-of-possession, and enables the 60 Hz balanced temporal interlace.
screenshotResistantFortressAdds the pointer Lens to Fortress’s temporal/capture/strike defaults; still not screenshot prevention.
A

Delivery — what leaves the server

D-01

Masters stay outside declared public roots; overlap checks fail closed

SecurityFail-closed

The original file should not be web-addressable; the middleware is the intended reader, and it refuses overlap with public roots declared in its configuration.

D-02

Entitled derivative width is capped; preview-only needs an explicit policy

SecurityQuality

The server resizes to the signed, entitled width before anything is scrambled or sent. That width is not inherently the browser’s physical display size: maxWidthFraction defaults to 1, so an entitled viewer can receive native-width pixels when the other caps permit.

D-03

Scramble is obfuscation; AES-256-GCM is the secrecy — labelled as such

SecurityHonesty

Tile permutation makes captured payloads harder for casual tools to inspect; it is not encryption and can be reconstructed. When wire confidentiality matters, the payload can also be sealed with AES-256-GCM.

D-04

128-bit-seeded scramble plans (v2); the 32-bit v1 kept frozen, not deleted

SecurityCompatibility

Version-1 plans derived from a 32-bit seed — brute-forceable offline. v2 seeds sfc32 from a 128-bit cyrb128 hash. Old payloads still decode because v1 was frozen instead of “fixed”.

D-05

Padding that does not betray the edges (five generations)

SecurityQuality

Images rarely divide by the grid; the padded strip sounded innocent until it kept naming the boundary tiles to solvers. Final design: a keyed, DC-anchored coherent wrap.

B

Tokens & access control

D-06

One-time HMAC tokens with an allowlisted claim set — not a JWT library

Security

A token is base64url(claims).base64url(HMAC-SHA256): eight-ish claims, every one validated (audience, scope, image, width, iat/exp window, nonce), normally spent once while the claim record is retained; the evict-on-saturation policy can reopen a narrow replay window under sustained pressure (D-07), canonical encodings only.

D-07

Replay-store saturation is an operator policy, not a surprise

SecurityPerformance

A one-time-claim store is finite. When it fills, something must give: evict the oldest claims (a replay window re-opens) or refuse new views (strict). We ship both, default by deployment profile, plus the sizing math.

D-08

Sender-constraining: bind tokens to the browser that asked

SecurityCompatibility

A copied token should be worthless elsewhere: optional User-Agent binding for cheap friction, and DPoP-style proof-of-possession (RFC 9449 shape) with an ephemeral in-page key for real binding.

D-09

Deny-by-default authorization; the audit must never bless what startup refuses

Security

On the server, no authorize callback and no explicit allowAnonymous:true mode ⇒ the constructor throws. An explicit denial returns 403; an authorize exception returns a generic 500, and a callback timeout returns 503. Both failures deny delivery and emit a separate archx.authorization_error event. Unknown server-option keys and weak secrets also fail at startup.

C

The viewer — where pixels become visible

D-10

Canvas viewer with poisoned readback — no <img>, no right-click theatre

SecurityHonesty

The picture exists as canvas paint operations, not as an addressable image element. Readback APIs get decoys or black; “disable right-click” is available as a flag but never presented as a control.

D-11

Temporal interlace at 60 Hz: never show the whole picture in one instant

SecurityQuality

Alternating complementary subsets (strips/blocks/checkerboards) at display rate: the eye integrates a complete image; a single-frame capture inherits holes.

D

Watermarking & detection — attribution after the leak

D-12

Classical spread-spectrum watermarking in pure JS (not neural, not LSB)

QualitySecurity

StegoMark signs each grid cell with a keyed ± pattern, amplitude masked by local texture. Robust profile PSNR ≈28–30 dB buys crop/scale/geometry survival that prettier marks don’t have.

D-13

Layout 4 = BCH(188,64) — shipped opt-in, deliberately not the default

QualityCompatibility

Algebraic error correction beats repetition — in quality (+1.4 dB photos) and theory. It lost the pre-registered flip test by one case (84 vs 85 robust), so layout 3 stays default. The bar was set before the experiment; the result stands.

D-14

A keyed MAC decides attribution — never a CRC, never a “confidence %”

SecurityHonesty

False attribution is the catastrophic failure (accusing an innocent buyer). Every candidate decode must pass a keyed 16-bit MAC and strict mismatch caps; the reported confidence: 0.99 is a label, not a measured probability — and the docs say so.

D-15

A decode ladder, not a decoder: BM → ML → OSD → ISD → forensic stash

QualityPerformance

Bounded-distance decoding dies at 37 erasures. Real crops erase 69+ bits and flip a few of the survivors. Each rung exists because a measured case killed the previous one.

D-16

Corroboration stack: pHash + forensic blocks + collusion assay — evidence, not verdicts

HonestySecurity

A 64-bit DCT pHash (soft binding), seeded forensic block signs, and a collusion-ranking assay support the primary mark. Each is labelled with what it can and cannot prove.

E

Platform — running it safely at scale

D-17

Sharp/libvips under hard budgets, one chained pipeline

PerformanceSecurity

Every transform runs as a single libvips pipeline with pixel/channel caps, failOn, sequential reads, and a wall-clock timeout — because the image decoder is the most dangerous code you expose to the internet.

D-18

Bounded everything: no attacker-sized data structures

SecurityPerformance

Rate limiters, replay sets, distinct-image trackers, body readers, batch minters, detect queues — every structure an attacker can grow has a hard capacity and a deadline.

D-19

Zero runtime dependencies; an honest Node floor split

CompatibilitySecurity

The library installs with no runtime dependency tree (Sharp is a peer). engines ≥20.9 covers the library; the dev browser suite needs Node 22 — because the Node-20-compatible Puppeteer line failed our audit gate.

F

Process — how the work itself is governed

D-20

Optimizations must be byte-identical — or be reverted

PerformanceCompatibility

Speed work is gated by output-hash oracles (135 cases at 24 MP last round) and a golden freeze of shipped formats. One “optimization” measured slower and was reverted in the same round; its numbers are published too.

D-21

Honest labelling as an engineering constraint — and 0BSD

Honesty

No “screenshot prevention”, no DRM claims, no C2PA conformance, no independent-audit theatre. The license matches the philosophy: BSD Zero Clause — use it any way you like; attribution appreciated, never required.