diff --git a/RULES.md b/RULES.md new file mode 100644 index 0000000..6c4e4a8 --- /dev/null +++ b/RULES.md @@ -0,0 +1,116 @@ +# AutistMask Rules Checklist + +This file is derived from README.md and REPO_POLICIES.md for use as an audit +checklist. The authoritative policies are in those two files. If this file +contradicts either, the originals govern. + +--- + +## Cryptography + +- [ ] No raw crypto primitives in application code (`aes`, `sha`, `pbkdf`, + `hmac`, `encrypt`, `decrypt`, `hash`, `cipher`, `digest`, `sign`) +- [ ] All crypto goes through `ethers` or `libsodium-wrappers-sumo` +- [ ] No exceptions without an explicit code comment citing the Crypto Policy +- [ ] Secrets encrypted at rest with Argon2id + XSalsa20-Poly1305 +- [ ] Password never used in address derivation (encryption only) + +## External Communication + +- [ ] Extension contacts exactly two external services: configured RPC endpoint + and CoinDesk price API +- [ ] No analytics, telemetry, or tracking +- [ ] No user-specific data sent except to the configured RPC endpoint +- [ ] No Infura/Alchemy hard dependency +- [ ] No backend servers operated by the developer +- [ ] RPC endpoint is user-configurable (defaults to publicnode.com) + +## Dependencies + +- [ ] Four runtime libraries only: `ethers`, `libsodium-wrappers-sumo`, + `qrcode`, `ethereum-blockies-base64` +- [ ] No JS framework (React, Vue, Svelte, etc.) +- [ ] All external references pinned by cryptographic hash (per REPO_POLICIES) + +## Address Display & Anti-Spoofing + +- [ ] Addresses displayed in full in all critical contexts (tx confirmation, + send confirmation, transaction detail) +- [ ] `truncateMiddle()` removes at most 10 characters — enforced in code +- [ ] Caller floor for address truncation is 32 characters minimum +- [ ] Clicking any address copies the full untruncated value +- [ ] Known token symbol verification: transfers claiming a known symbol from an + unrecognized contract are filtered +- [ ] Tokens with < 1,000 holders hidden from tx history and send selector +- [ ] Dust transactions below configurable threshold hidden +- [ ] Fraud contract blocklist applied to tx history + +## Display Consistency + +- [ ] Token/ETH amounts: exactly 4 decimal places in all summary views +- [ ] Transaction detail view: exact untruncated amount (full precision) +- [ ] Transaction detail view: native quantity shown (wei / base units) +- [ ] Both amount and native quantity are click-copyable +- [ ] Timestamps: ISO datetime + relative age, everywhere they appear +- [ ] Same data formatted identically across all screens + +## No Layout Shift + +- [ ] All async-populated elements have `min-height` or placeholder content +- [ ] `formatUsd(null)` returns `""` — callers must use ` ` fallback +- [ ] `visibility: hidden` preferred over `display: none` when space must be + preserved +- [ ] No UI element moves when async data (prices, balances, tx lists) arrives + +## Clickable Affordance + +- [ ] Every button has visible border, padding, and hover state +- [ ] Every clickable text element has underline or dashed underline +- [ ] No invisible hit targets + +## DEBUG Mode + +- [ ] DEBUG mode only enables: red banner + hardcoded test mnemonic +- [ ] No `if (DEBUG)` branches that skip functionality or bypass security +- [ ] New DEBUG conditionals require explicit project owner approval + +## Transaction Decoding + +- [ ] Decoding is best-effort display convenience only +- [ ] No protocol gets special handling beyond the confirmation screen +- [ ] If decoding fails, raw calldata displayed in full (not truncated) +- [ ] Decoders are self-contained modules in `src/shared/` + +## Approval Flow + +- [ ] Site connection: explicit user approval via popup +- [ ] Transaction signing: password required, decoded details shown +- [ ] Message signing: password required, message content shown +- [ ] Typed data signing: password required, domain/type/message fields shown +- [ ] Rejected approvals return EIP-1193 error code 4001 +- [ ] TX and sign approvals persist across popup close/reopen (toolbar popup) + +## Secrets & Storage + +- [ ] Public data (xpubs, addresses, balances) stored unencrypted +- [ ] Private data (recovery phrases, private keys) encrypted at rest +- [ ] Password only required for signing operations +- [ ] No secrets in `.env`, credentials, or API keys committed to repo +- [ ] `git add -A` / `git add .` never used + +## Build & Workflow + +- [ ] All tool invocations via `make` targets, never directly +- [ ] `make check` = `make test` + `make lint` + `make fmt-check` +- [ ] `main` always passes `make check` +- [ ] Feature branches for all changes, merge to main when done +- [ ] No force-push to `main` +- [ ] Pre-commit hook runs `make check` + +## Language & Labeling + +- [ ] "Recovery phrase" not "seed phrase" or "mnemonic" +- [ ] "Address" not "account" or "derived key" +- [ ] "Password" not "encryption key" or "vault passphrase" +- [ ] Error messages are full sentences +- [ ] No competitor mentioned by name in code or documentation