diff --git a/CLAUDE.md b/CLAUDE.md index 3cb8245..dee3ed0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,9 +10,16 @@ Context for AI agents (Claude Code) working in this repo. Read this first, then - **English for ALL code**: identifiers, class/field/column names, comments, commit messages, branch names, and technical specs. No exceptions. - **User-facing strings are NEVER hardcoded** — always via i18n. The app is multilingual by design. +- **International by design, not Spain-first.** Tane targets the whole world, not one country or region. This is not just UI strings: it constrains **bundled data and assets** too. + - **Locale-keyed data, never mono-locale**: any catalog/reference data with human-readable names (species common names, vernacular names, units, categories) MUST be a locale-keyed map (`{ "es": [...], "en": [...], "ar": [...] }`), extensible to any language — never a single hardcoded language. Starter datasets may ship a small locale set, but the *schema*, code paths, and copy must never assume es/en only, and comments/notes must not brand the data as "Iberian/Spanish". + - **RTL is a first-class requirement**: layouts, widgets, and tests must work under RTL (Arabic, Hebrew, Persian). Use directional (`start`/`end`) not physical (`left`/`right`) insets/alignment; verify with `Directionality`. + - **Scripts & fonts**: bundled fonts must cover the scripts we claim to support (Latin + at least RTL/Arabic and CJK as they land); don't hardcode a Latin-only font stack. + - **OCR / language models**: bundled OCR traineddata and any language resource are pluggable per locale, not fixed to `eng`/`spa`. Match the data pack to the user's locale(s); the current es/en starter set is a seed, not the ceiling. + - **No locale-specific assumptions** in formatting, sorting, dates, numbers, name order — go through `intl`/ICU, never ad-hoc. - **No plaintext at rest, ever** — the inventory DB is encrypted (SQLCipher). No plaintext logs/temp/caches. See [`docs/design/security-privacy.md`](docs/design/security-privacy.md). - **Local-first**: everything works offline, no account, no central server. Online only enriches (degrades gracefully). - **Progressive disclosure**: only `Variety.label` is mandatory; every other field optional. Audience is everyone 10–80; simple by default, depth on demand. Never build "two modes". +- **Human words in the UI, never tech jargon.** User-facing copy speaks by *intent* (what it does for the person), not by *mechanism*. File formats and internals (CSV, JSON, HLC, CRDT, LWW, UUID…) are implementation details and MUST NOT appear in labels, subtitles, dialogs or messages. E.g. "Save a backup" / "Restore a backup" (not "Export JSON"); "Export to a spreadsheet" (a spreadsheet is a human concept; "CSV" is not). Format-named i18n *keys* (`exportJson`) are fine — they're code; only their *values* must be human. When a feature is genuinely for power users, reframe it or bury it under progressive disclosure — don't leak the jargon. - **License: AGPL-3.0.** Keep new deps compatible. - **Tests, near-TDD.** Every behavior is covered by automated tests (unit / widget / integration); **do NOT rely on manual testing.** Write tests first for domain logic (`commons_core` is pure Dart — ideal for TDD). Nothing merges without tests covering the new behavior; CI gates it. See [`docs/design/testing.md`](docs/design/testing.md). - Discussion/design docs may be in Spanish; code and specs in English.