Adds the load-bearing primitives for obfuscated browser-fingerprinting
canaries. Step 3 (HTML/SVG generators) and step 4 (worker-side
fingerprint ingestion) build on top of these.
* decnet/canary/obfuscator.py - javascript-obfuscator wrapper. Seed
and polymorphic config bits both derive from the callback token, so
output is byte-identical for the same mint (preserving the generator
determinism contract from base.py) and structurally distinct across
mints.
* decnet/canary/fingerprint_payload.js - port of canary-self-test.html
with the rendering UI stripped. Two placeholders (BEACON_URL,
MINT_UUID) substituted before obfuscation. MVP beacon strategy:
bare-open GET pixel first, then base64url-encoded fingerprint as
query params on subsequent GETs (chunked above ~6KB) so the existing
worker records hits before step-4 lands.
* decnet/canary/_obfuscate_helper.js - Node subprocess helper that
reads code+options JSON from stdin and writes obfuscated JS to
stdout. Vendored javascript-obfuscator under decnet/canary/.
* tests/canary/test_obfuscator.py - determinism, per-mint divergence,
template substitution, Node syntax check, error path.
- Fixed CLI tests by patching local imports at source (psutil, os, Path).
- Fixed Collector tests by globalizing docker.from_env mock.
- Stabilized SSE stream tests via AsyncMock and immediate generator termination to prevent hangs.
- Achieved >80% coverage on CLI (84%), Collector (97%), and DB Repository (100%).
- Implemented SMTP Relay service tests (100%).