diff --git a/AGENTS.md b/AGENTS.md index 3ce69e8cf..510d42011 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,7 +30,7 @@ Use the v2 ubiquitous language defined in `CONTEXT.md` — every domain term (sc 1. **Never** store `privateKey` or any seed in localStorage/sessionStorage 2. **Never** log sensitive keys or seeds 3. **Never** send unencrypted keys to the server — the server is zero-knowledge and NEVER sees plaintext or unencrypted keys -4. **All crypto lives in `crates/core`** — TypeScript has no codec or crypto of its own; never implement crypto in TS +4. **All crypto lives in `crates/core`** — TypeScript has no codec or crypto of its own; never implement crypto in TS. **One exception: browser-held key custody via WebCrypto**, for a key that must be non-extractable, or must exist before the engine has a session. The engine cannot serve either case — a WASM implementation necessarily materializes key bytes in linear memory, which is the property non-extractability exists to deny, and before `start(secret)` there is no session to derive from. Conditions, all of them: the key protects local state only, it derives nothing in the KDF catalog, it touches no wire format and no KAT, and it never leaves WebCrypto. Two live instances — the Core Kit store's wrapping key (`apps/web/src/auth/sealedStore.ts`), and the device identity key that signs a device-approval exchange before reconstruction ([ADR 0009](https://github.com/FSM1/cipher-box-next/blob/main/decisions/0009-device-approval-is-a-bound-rendezvous.md)). Anything protocol-shaped is still Rust, without exception. 5. Primitives are fixed by `blueprint/core.md`: XChaCha20-Poly1305 sealing, BLAKE3 tree KDF, X25519 + HPKE key wrapping, Ed25519/secp256k1 signing — no key derives outside the frozen KDF edge catalog 6. Every resolved record passes the adoption gate; a failure is a fail-closed trust violation, never mere staleness 7. Clear sensitive material from memory after use (zeroize at the terminal owner only — a callee must not zero caller-owned buffers)