# aphoria-error-mapping ## AUDIT (2026-02-06) **Pattern:** Inconsistent `.map_err()` patterns across Aphoria codebase **Analysis:** Found 152 `.map_err()` calls across 4 patterns: | Pattern | Count | Action | |---------|-------|--------| | A - Context-aware `format!()` | 55 | ✅ Keep as standard | | B - Direct `.to_string()` | 35 | ❌ Replace with A | | C - Bare `format!()` (returns String) | 11 | ❌ Replace with A | | D - Custom closure logic | 43 | ⚠️ Keep for structured errors | **Standard Pattern (A):** ```rust some_op().map_err(|e| AphoriaError::Variant(format!( "Failed to do X at Y: {}", e )))?; ``` **Anti-Pattern (B):** ```rust some_op().map_err(|e| AphoriaError::Variant(e.to_string()))?; // Loses context: what operation? what was the file/path? ``` **Files to fix (by priority):** 1. `episteme/local/store.rs` - 13 Pattern B instances 2. `episteme/local/mod.rs` - 4 Pattern B instances 3. `walker/mod.rs`, `walker/git.rs` - 4 Pattern B instances 4. `policy.rs`, `policy_ops.rs` - 6 Pattern B instances 5. `corpus/rfc/mod.rs`, `owasp/mod.rs` - 3 Pattern B instances 6. `episteme/aliases.rs`, `drift.rs` - 5 Pattern B instances 7. `hosted.rs` - 11 Pattern C instances **Total changes needed:** 46 instances ## FIX (2026-02-06) - [x] `episteme/local/store.rs` - Fixed 13 Pattern B instances: - serialize_assertion → "Failed to serialize claim/observation/authoritative assertion" - journal.append → "Failed to append to WAL" - journal.force_sync → "Failed to sync WAL" - ingestor.process_pending → "Failed to process ingestion" - get_by_predicate → "Failed to fetch predicate index" - [x] `episteme/local/mod.rs` - Fixed 4 Pattern B instances: - Journal::open → "Failed to open WAL at {path}" - HybridStore::open → "Failed to open store at {path}" - Ingestor::new → "Failed to create ingestor" - load_or_generate_key → "Failed to load/generate signing key at {path}" - [x] `walker/mod.rs` + `git.rs` - Fixed 2 Pattern B instances: - directory entry → "Failed to read directory entry" - git diff → "Failed to execute git diff command" - [x] `policy.rs` + `policy_ops.rs` - Fixed 7 Pattern B instances: - write/read policy file with path context - cache file creation with path context - assertion serialization with subject context - alias import with alias names - [x] `episteme/aliases.rs` + `drift.rs` - Fixed 4 Pattern B instances: - get_canonical → with code_path context - set_alias → with both paths context - list_all_aliases → with operation description - get_by_predicate → with operation description - [x] `hosted.rs` - Fixed Pattern C (11 instances → AphoriaError::Hosted): - Changed return types from `Result` to `Result` - All HTTP errors now use `AphoriaError::Hosted(format!(...))` - [x] `corpus/rfc/mod.rs` + `owasp/mod.rs` - Already using context-aware patterns: - Uses structured error variants with rfc/sheet context **Remaining:** 1 instance in policy.rs:206 - intentionally ignores error (signature validation) ## ENFORCE (2026-02-06) Added to `.claude/skills/aphoria-dev/skill.md`: - **Do Not #12:** "Use generic `.map_err(|e| AphoriaError::X(e.to_string()))`. Always include operation context in error messages." - **ALWAYS:** "Use context-aware error mapping: `.map_err(|e| AphoriaError::X(format!("Failed to Y: {e}")))`" ## COMPLETE (2026-02-06) **Before:** 46 Pattern B/C instances **After:** 1 intentional exception (signature validation) **Fixed:** 45 instances across 10 files