personal memory agent

feat(link): derive journal id + mark from CA public key master

Add solstone/think/link/mark.py — a pure, no-write derivation core that turns a journal CA's P-256 public-key SPKI into a stable journal id (jid, a 128-bit UUIDv8 via HKDF-SHA256) and a journal mark (two distinct icons with color + 45-degree rotation, two words) via argon2id over the jid bytes. Both are deterministic functions of the canonicalized key, so any peer that sees the public key re-derives the identical jid and mark. The recipe is a frozen cross-surface/cross-language contract; the suite pins four independently-computed reference vectors (covering all four rotation states and both pick_distinct branches) and asserts the jid, argon2 digest, and icon/color/word/rotation selections byte-for-byte, plus the pick_distinct off-by-one boundary, canonicalization + loud ValueError on wrong-curve/non-key/PEM/compressed input, asset length-guards, and the locked argon2 parameters. Adds argon2-cffi to the thin base dependencies (the think/link/ access surface) in lockstep with scripts/check_extras_consistency.py THIN_BASE. Derivation core only — no init/LinkState wiring, no UI, no persisted format change (later lodes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>


+679
5 changed files