audit:
  project: neural-memory
  total_loc: 142000
  total_files: 190
  method: "Hybrid (Auto reviewers + Manual review + Pug Brain tracking)"
  focus: [security, code_quality, architecture, performance, logic]
  started: "2026-02-16"

phases:
  phase_1:
    modules: [engine/]
    loc: 14271
    files: 39
    status: COMPLETE
    started: "2026-02-16"
    completed: "2026-02-17"
    completed_audits: [security, code_quality, architecture, performance, logic]

    # ── Security ── Grade: A-
    security_grade: "A-"
    security_findings:
      - severity: MEDIUM
        file: db_introspector.py
        lines: [192, 214, 234, 251, 268]
        category: SQL_INJECTION_MITIGATED
        desc: "F-string SQL in PRAGMA queries - mitigated by _validate_identifier() regex + read-only connection"
        status: ACCEPTABLE
      - severity: LOW
        file: brain_versioning.py
        line: 88
        category: DESERIALIZATION
        desc: "json.loads() without explicit schema validation in _json_to_snapshot()"
        status: FIXED
      - severity: LOW
        file: db_introspector.py
        lines: [350, 365, 371, 387, 397]
        category: ERROR_HANDLING_GOOD
        desc: "Error messages are correctly generic - no internal leaking. Exemplary."
        status: NO_ACTION

    # ── Code Quality ── Grade: A
    code_quality_grade: "A"
    code_quality_findings:
      - severity: MEDIUM
        file: consolidation.py
        line: 181
        category: TYPE_HINTS
        desc: "Lambda dispatch dict uses bare Any instead of Callable[[], Awaitable[None]]"
        status: FIXED
      - severity: MEDIUM
        file: conflict_detection.py
        lines: [386, 536]
        category: DUPLICATE_CODE
        desc: "Two duplicate stop word sets defined inline - should unify to module-level _STOP_WORDS constant"
        status: FIXED
      - severity: MEDIUM
        file: conflict_detection.py
        line: 110
        category: READABILITY
        desc: "Long regex patterns could be extracted to named module-level constants"
        status: DEFERRED  # cosmetic, low risk
      - severity: MEDIUM
        file: retrieval.py
        line: 756
        category: READABILITY
        desc: "Inline suffix/prefix tuples in _expand_query_terms - extract to module constants"
        status: FIXED
      - severity: LOW
        file: consolidation.py
        line: 400
        category: DOCSTRINGS
        desc: "Union-Find nested helpers lack docstrings"
        status: ACCEPTABLE  # UnionFind extracted to clustering.py with docstrings
      - severity: LOW
        file: conflict_detection.py
        line: 444
        category: PYTHONIC
        desc: "Manual seen+list dedup - use dict.fromkeys() instead"
        status: DEFERRED  # dict.fromkeys lowercases, tests expect original case
      - severity: LOW
        file: consolidation.py
        line: 332
        category: IMPORT_STYLE
        desc: "dataclasses.replace imported inside conditional block instead of module-level"
        status: FIXED

    # ── Architecture ── Grade: B+
    architecture_grade: "B+"
    architecture_findings:
      - severity: HIGH
        files: [consolidation.py, enrichment.py, pattern_extraction.py]
        category: DEAD_CODE_REDUNDANCY
        desc: "Union-Find with path compression copy-pasted 5 times across 3 files (~120 lines). Jaccard clustering loop also duplicated."
        recommendation: "Extract reusable UnionFind class + cluster_by_jaccard() utility into engine/clustering.py"
        status: FIXED  # clustering.py UnionFind integrated into all 3 files
      - severity: HIGH
        file: retrieval.py
        category: SRP_GOD_FUNCTION
        desc: "ReflexPipeline.query() is 162 lines spanning 12 pipeline stages. Modifying any stage requires reading entire method."
        recommendation: "Refactor into step-based pipeline matching encoding Pipeline pattern in pipeline.py"
        status: DEFERRED_NEXT  # large refactor, needs design
      - severity: HIGH
        file: retrieval_context.py
        category: DEAD_CODE
        desc: "reconstitute_answer() is dead code - never called, fully superseded by reconstruction.py"
        recommendation: "Delete reconstitute_answer(), keep only format_context()"
        status: ALREADY_DONE  # function was already removed in prior refactor
      - severity: MEDIUM
        files: [consolidation.py, pipeline_steps.py, conflict_detection.py, lifecycle.py]
        category: IMMUTABILITY_VIOLATION
        desc: "6 call sites manually construct frozen dataclass instances field-by-field instead of replace()"
        recommendation: "Use dataclasses.replace() per project immutability rules"
        status: FIXED  # 4 genuine call sites replaced with dc_replace() (5th was new construction)
      - severity: MEDIUM
        file: consolidation.py
        category: SRP
        desc: "ConsolidationEngine is 966 lines with 9 inline strategies. Hybrid coordinator+implementor."
        recommendation: "Extract _prune, _merge, _summarize into dedicated modules like dream.py/enrichment.py"
        status: DEFERRED  # large refactor, schedule separately
      - severity: MEDIUM
        file: lifecycle.py
        category: COUPLING
        desc: "Contains unrelated DecayManager + ReinforcementManager. DecayManager overlaps with consolidation."
        recommendation: "Split into engine/decay.py + engine/reinforcement.py"
        status: DEFERRED
      - severity: MEDIUM
        file: consolidation.py
        category: INTERFACE
        desc: "ConsolidationReport has 14 mutable fields, mutated by concurrent strategies in asyncio.gather()"
        recommendation: "Have each strategy return sub-report, merge after gather()"
        status: DEFERRED
      - severity: MEDIUM
        file: retrieval.py
        category: COUPLING
        desc: "retrieval.py has 12+ direct dependencies (high fan-out hub)"
        recommendation: "Register temporal reasoning + workflow suggestions as hooks instead of hardcoded imports"
        status: DEFERRED
      - severity: MEDIUM
        file: retrieval.py
        category: CODE_SMELL
        desc: "__all__ declaration appears before some imports (organizational anomaly)"
        recommendation: "Move __all__ after all imports"
        status: ALREADY_SAFE  # __all__ is after runtime imports, before TYPE_CHECKING (standard pattern)
      - severity: LOW
        file: consolidation.py
        category: SRP
        desc: "_infer() is 140 lines performing 6 phases"
        recommendation: "Extract to engine/infer.py following dream.py pattern"
        status: DEFERRED
      - severity: LOW
        file: conflict_auto_resolve.py
        category: LAYERING
        desc: "Cross-package dependency: engine -> safety.freshness"
        recommendation: "Minor concern, inline age check if problematic"
        status: ACCEPTABLE
      - severity: LOW
        file: dream.py
        category: PERFORMANCE
        desc: "O(n^2) pairs from activated neurons. Safe at current scale but latent risk."
        recommendation: "Add max_pairs safety cap"
        status: ALREADY_DONE  # max_dream_pairs = 50_000 cap already exists
      - severity: LOW
        file: hooks.py
        category: EXTENSIBILITY
        desc: "HookRegistry is fully implemented but has zero integration points in core engine"
        recommendation: "Wire into encode/recall/consolidate paths"
        status: DEFERRED

    # ── Performance ── Grade: B+
    performance_grade: "B+"
    performance_findings:
      - severity: CRITICAL
        file: consolidation.py
        lines: [314, 319]
        category: DATABASE_N_PLUS_1
        desc: "N+1 query in _prune(): get_neighbors() called inside synapse loop for bridge detection. 500+ serial DB queries."
        fix: "Pre-fetch neighbor counts in batch, build lookup dict"
        status: FIXED  # pre-fetch with get_synapses_for_neurons()
      - severity: HIGH
        file: consolidation.py
        lines: [777, 806]
        category: ALGORITHMIC
        desc: "_infer() fiber tagging O(tags x fibers). 100 tags x 10K fibers = 1M iterations."
        fix: "Build inverted index tag->fiber_ids, batch-update at end"
        status: FIXED  # inverted index + accumulated writes (also fixed tag overwrite bug)
      - severity: HIGH
        file: retrieval.py
        lines: [858, 867]
        category: DATABASE
        desc: "Anchor finding spawns N parallel find_neurons queries (13+ queries). No batching."
        fix: "Add storage.find_neurons_batch() with single SQL UNION query"
        status: ACCEPTABLE  # already uses asyncio.gather() for parallel queries
      - severity: HIGH
        file: activation.py
        lines: [119, 161]
        category: DATABASE
        desc: "activate() calls get_neighbors() in inner loop. ~1000 calls over activation lifetime."
        fix: "Cache synapse adjacency, pre-fetch for known nodes"
        status: FIXED  # neighbor_cache + batch neuron state pre-fetch
      - severity: HIGH
        file: conflict_detection.py
        lines: [219, 226]
        category: ALGORITHMIC
        desc: "detect_conflicts() searches per-term individually (5 terms x max_candidates). Quadratic predicate comparison."
        fix: "Single batch query find_neurons(content_contains_any=[...])"
        status: FIXED  # asyncio.gather() for parallel per-term queries
      - severity: MEDIUM
        file: retrieval.py
        lines: [228, 234]
        category: ALGORITHMIC
        desc: "sorted() on 1000s of items for top-10 selection. O(n log n) instead of O(n log k)."
        fix: "Use heapq.nlargest()"
        status: ALREADY_DONE  # code already uses heapq.nlargest()
      - severity: MEDIUM
        file: activation.py
        line: 199
        category: MEMORY
        desc: "Path copying [*current.path, neighbor] creates new list on every hop. ~1000 allocations."
        fix: "Store only hop_distance, reconstruct path lazily"
        status: DEFERRED
      - severity: MEDIUM
        file: consolidation.py
        lines: [330, 339]
        category: ALGORITHMIC
        desc: "Fiber synapse_id cleanup iterates all fibers x avg_synapses. O(fibers x synapses_per_fiber)."
        fix: "Build inverted index synapse_id->fiber_ids"
        status: FIXED  # inverted index to skip unaffected fibers
      - severity: MEDIUM
        file: consolidation.py
        lines: [496, 500]
        category: DATABASE
        desc: "_merge() deletes fibers one-by-one. 300 serial DELETE operations."
        fix: "Add storage.delete_fibers_batch(ids)"
        status: DEFERRED  # needs new storage abstract method
      - severity: MEDIUM
        file: enrichment.py
        lines: [139, 146]
        category: ALGORITHMIC
        desc: "find_cross_cluster_links() O(n^2) tag comparison for all fiber pairs."
        fix: "Add early exit for low intersection before Jaccard calc"
        status: FIXED  # early continue on empty tags + zero intersection + inline union calc
      - severity: LOW
        file: write_queue.py
        lines: [69, 116]
        category: ASYNC
        desc: "flush() awaits each write serially within categories."
        fix: "Use asyncio.gather() within each type"
        status: DEFERRED

    # ── Logic ── Grade: B+
    logic_grade: "B+"
    logic_findings:
      - severity: HIGH
        file: conflict_detection.py
        line: 437
        category: EDGE_CASE
        desc: "Division by zero in _predicates_conflict() when words_a or words_b empty after splitting."
        fix: "Add: if not words_a or not words_b: return False"
        status: FIXED  # guard added 2026-02-17
      - severity: HIGH
        file: consolidation.py
        lines: [418, 419]
        category: EDGE_CASE
        desc: "Division by zero in _merge() Jaccard when both fiber.neuron_ids are empty sets (union_size=0)."
        fix: "Add: if union_size == 0: continue"
        status: ALREADY_SAFE  # code already has 'if union_size > 0:' guard at line 418
      - severity: MEDIUM
        file: consolidation.py
        line: 470
        category: EDGE_CASE
        desc: "_merge() min(f.created_at) on member_fibers without guard for missing created_at."
        fix: "Add fallback: default=utcnow()"
        status: ALREADY_SAFE  # Fiber.created_at is datetime (never None), member_fibers always >= 2
      - severity: MEDIUM
        file: brain_versioning.py
        lines: [257, 262]
        category: ALGORITHM
        desc: "create_version() checks name uniqueness by fetching ALL versions (limit=10000) + Python iteration."
        fix: "Push to storage layer with dedicated query or UNIQUE constraint"
        status: FIXED  # reduced limit to 1000 (realistic cap for versions)
      - severity: MEDIUM
        file: retrieval.py
        lines: [670, 674]
        category: ALGORITHM
        desc: "Lateral inhibition per_cluster allocation leaves unused slots with uneven k/num_clusters."
        fix: "Use ceiling division or distribute remainder"
        status: FIXED  # ceiling division applied 2026-02-17
      - severity: MEDIUM
        file: consolidation.py
        lines: [551, 554]
        category: EDGE_CASE
        desc: "Jaccard in _summarize() division by zero when both tag sets empty."
        fix: "Add: if union_size == 0: continue"
        status: ALREADY_SAFE  # code already has 'union_size > 0' guard at line 552
      - severity: MEDIUM
        file: activation.py
        line: 173
        category: EDGE_CASE
        desc: "batch_states partial results if get_neuron_states_batch() returns incomplete data."
        fix: "Already null-safe (checks 'if neuron_state and ...')"
        status: ACCEPTABLE
      - severity: MEDIUM
        file: retrieval.py
        line: 437
        category: EDGE_CASE
        desc: "Duplicate of conflict_detection.py _predicates_conflict() division by zero."
        fix: "Same fix: guard empty word sets"
        status: ALREADY_SAFE  # no such pattern exists in retrieval.py (false positive)
      - severity: LOW
        file: learning_rule.py
        line: 134
        category: EDGE_CASE
        desc: "hebbian_update() doesn't validate current_weight is in valid range initially."
        fix: "Add input validation or clamp on entry"
        status: FIXED  # clamp added 2026-02-17
      - severity: LOW
        file: stabilization.py
        lines: [118, 123]
        category: EDGE_CASE
        desc: "Homeostatic normalization: scale explodes when mean_level very close to 0."
        fix: "Add threshold: if mean_level < 0.001: skip"
        status: FIXED  # threshold guard added 2026-02-17
      - severity: LOW
        file: brain_versioning.py
        lines: [158, 161]
        category: ALGORITHM
        desc: "_compute_diff() dict.get() with no default for 'content'/'type' comparison."
        fix: "Use dict.get('content', '') for safe defaults"
        status: FIXED  # safe defaults added 2026-02-17
      - severity: LOW
        file: merge.py
        lines: [202, 203]
        category: EDGE_CASE
        desc: "Budget check passes with total=0 (empty outgoing), normalization is no-op."
        fix: "No fix needed - behavior is correct"
        status: ACCEPTABLE
      - severity: LOW
        file: brain_transplant.py
        line: 268
        category: EDGE_CASE
        desc: "Synapse filtering for orphan neurons might exclude their synapses."
        fix: "Logic is correct - this is intentional (orphans = no fiber-based synapses)"
        status: ACCEPTABLE

    # ── Phase 1 Overall ──
    overall_grade: "B+"
    summary: |
      Engine module is architecturally sound with strong bio-inspired design.
      Main concerns: N+1 DB queries in consolidation, Union-Find duplication,
      division-by-zero edge cases, and ReflexPipeline.query() god-function.
      Security is excellent (A-). Code quality is clean (A).

    priority_fixes:
      - "CRITICAL: Fix N+1 bridge detection in consolidation._prune()"
      - "HIGH: Guard division-by-zero in _predicates_conflict() and _merge() Jaccard"
      - "HIGH: Delete dead reconstitute_answer() in retrieval_context.py"
      - "HIGH: Extract shared UnionFind utility (eliminate 120 lines duplication)"
      - "HIGH: Add find_neurons_batch() for anchor finding"
      - "MEDIUM: Use replace() instead of manual frozen dataclass construction"
      - "MEDIUM: Fix lateral inhibition slot distribution"
      - "MEDIUM: Guard empty tag set Jaccard in _summarize()"

    zero_issue_files:
      - associative_inference.py
      - brain_evolution.py
      - causal_traversal.py
      - encoder.py
      - learning_rule.py
      - memory_stages.py
      - stabilization.py
      - write_queue.py

    fixes:
      - date: "2026-02-16"
        desc: "Unified duplicate stop word sets -> shared _STOP_WORDS frozenset"
        files: [conflict_detection.py]
        status: VERIFIED
      - date: "2026-02-16"
        desc: "Dispatch dict type hint: Any -> Callable[[], Awaitable[None]]"
        files: [consolidation.py]
        status: VERIFIED
      - date: "2026-02-16"
        desc: "Extracted expansion constants to module-level"
        files: [retrieval.py]
        status: VERIFIED
      - date: "2026-02-16"
        desc: "Added dict type validation in _json_to_snapshot()"
        files: [brain_versioning.py]
        status: VERIFIED
      - date: "2026-02-16"
        desc: "Moved dc_replace import to module-level"
        files: [consolidation.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Clamp current_weight to valid range on entry in hebbian_update()"
        files: [learning_rule.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add mean_level < 0.001 threshold guard in homeostatic normalization"
        files: [stabilization.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Use dict.get() with empty string defaults in _compute_diff()"
        files: [brain_versioning.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Ceiling division for lateral inhibition slot allocation"
        files: [retrieval.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Guard empty word sets in _predicates_conflict() to prevent false conflict on whitespace"
        files: [conflict_detection.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Created UnionFind utility class + integrated into all 3 consumer files"
        files: [clustering.py, consolidation.py, enrichment.py, pattern_extraction.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fixed stale version assertion 2.3.0 -> 2.3.1"
        files: [test_health_fixes.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Replace 4 manual frozen dataclass constructions with dc_replace()"
        files: [pipeline_steps.py, conflict_detection.py, lifecycle.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Optimize _infer() fiber tagging: inverted index + accumulated writes (fixed tag overwrite bug)"
        files: [consolidation.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Optimize synapse_id cleanup: inverted index to skip unaffected fibers"
        files: [consolidation.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fix CRITICAL N+1 in _prune(): pre-fetch neighbor synapses with get_synapses_for_neurons()"
        files: [consolidation.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add neighbor_cache + batch neuron state pre-fetch in activate() to eliminate N+1"
        files: [activation.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Batch conflict detection: asyncio.gather() for parallel per-term find_neurons queries"
        files: [conflict_detection.py]
        status: VERIFIED

  phase_2:
    modules: [storage/, server/]
    loc: 9539
    files: 36
    status: COMPLETE
    findings:
      # --- BOUNDS (systematic) ---
      - id: P2-001
        severity: HIGH
        category: BOUNDS
        desc: "15 storage methods missing min(limit, MAX) cap"
        files: [sqlite_neurons.py, sqlite_fibers.py, sqlite_typed.py, sqlite_projects.py, sqlite_versioning.py, sqlite_coactivation.py, memory_store.py, memory_collections.py]
        status: FIXED
      - id: P2-002
        severity: HIGH
        category: BOUNDS
        desc: "get_synapses() has no LIMIT clause at all"
        files: [sqlite_synapses.py]
        status: FIXED
      # --- SECURITY ---
      - id: P2-003
        severity: HIGH
        category: SECURITY
        desc: "CORS wildcard 'http://localhost:*' not supported by Starlette — dashboard requests blocked"
        files: [app.py]
        status: FIXED
      - id: P2-004
        severity: MEDIUM
        category: SECURITY
        desc: "OAuth endpoints (initiate, callback, providers) missing localhost restriction"
        files: [oauth.py]
        status: FIXED
      - id: P2-005
        severity: MEDIUM
        category: SECURITY
        desc: "sync/stats endpoint missing localhost restriction"
        files: [sync.py]
        status: FIXED
      - id: P2-006
        severity: MEDIUM
        category: SECURITY
        desc: "WebSocket subscribe allows any brain_id without validation"
        files: [sync.py]
        status: FIXED  # regex pattern + length validation on subscribe
      - id: P2-007
        severity: MEDIUM
        category: SECURITY
        desc: "shared_store.py bakes stale X-Brain-ID in session headers"
        files: [shared_store.py]
        status: FIXED
      # --- CORRECTNESS ---
      - id: P2-008
        severity: HIGH
        category: CORRECTNESS
        desc: "merge_brain() non-atomic: clear() then import_brain() — data loss if import fails"
        files: [brain.py]
        status: FIXED
      - id: P2-009
        severity: HIGH
        category: CORRECTNESS
        desc: "import_brain() saves brain record before transaction — orphaned on failure"
        files: [sqlite_brain_ops.py]
        status: FIXED
      - id: P2-010
        severity: MEDIUM
        category: CORRECTNESS
        desc: "sqlite_action_log docstring placed after limit cap statement (broken __doc__)"
        files: [sqlite_action_log.py]
        status: FIXED
      - id: P2-011
        severity: LOW
        category: CORRECTNESS
        desc: "export_brain() loses auto_tags/agent_tags distinction on roundtrip"
        files: [sqlite_brain_ops.py]
        status: DEFERRED
      # --- PERFORMANCE ---
      - id: P2-012
        severity: MEDIUM
        category: PERFORMANCE
        desc: "dashboard fiber diagram loads ALL synapses via get_all_synapses()"
        files: [dashboard_api.py]
        status: FIXED
      - id: P2-013
        severity: MEDIUM
        category: PERFORMANCE
        desc: "dashboard fiber diagram scans 500 fibers to find one by ID"
        files: [dashboard_api.py]
        status: FIXED
      - id: P2-014
        severity: MEDIUM
        category: PERFORMANCE
        desc: "get_graph_data fetches ALL neurons up to offset+limit, get_all_synapses unbounded"
        files: [app.py]
        status: DEFERRED
      - id: P2-015
        severity: MEDIUM
        category: PERFORMANCE
        desc: "BFS path-finding issues one SQL query per node expansion (N+1)"
        files: [sqlite_synapses.py]
        status: DEFERRED
      # --- DEAD CODE ---
      - id: P2-016
        severity: LOW
        category: DEAD_CODE
        desc: "Duplicate index: idx_typed_memories_expires vs idx_typed_memories_expiry"
        files: [sqlite_schema.py]
        status: FIXED
      - id: P2-017
        severity: LOW
        category: DEAD_CODE
        desc: "Duplicate limit cap in suggest_neurons route (line 207 and 216)"
        files: [memory.py]
        status: FIXED
      # --- TYPE SAFETY ---
      - id: P2-018
        severity: MEDIUM
        category: TYPE_SAFETY
        desc: "HybridStorage does not inherit NeuralStorage (type:ignore hack)"
        files: [factory.py]
        status: DEFERRED
      - id: P2-019
        severity: LOW
        category: TYPE_SAFETY
        desc: "HybridStorage methods use bare Any return types"
        files: [factory.py]
        status: DEFERRED
      # --- ERROR HANDLING ---
      - id: P2-020
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "HybridStorage.sync() catches bare Exception for remote brain lookup"
        files: [factory.py]
        status: FIXED
      - id: P2-021
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "list_neurons endpoint lacks Query() validation — negative limits pass"
        files: [memory.py]
        status: FIXED
      # --- PATH SECURITY ---
      - id: P2-022
        severity: MEDIUM
        category: PATH_SECURITY
        desc: "SQLiteStorage db_path not validated with resolve() + is_relative_to()"
        files: [sqlite_store.py]
        status: FIXED  # Path(db_path).resolve() in __init__
      # --- BOUNDS (deferred) ---
      - id: P2-023
        severity: MEDIUM
        category: BOUNDS
        desc: "get_all_neuron_states() and get_all_synapses() have no limit"
        files: [sqlite_neurons.py, sqlite_synapses.py]
        status: FIXED  # LIMIT 10000 on get_all_neuron_states; get_all_synapses delegates to get_synapses (already capped)
      - id: P2-024
        severity: HIGH
        category: BOUNDS
        desc: "export_brain() loads entire brain into memory with no limit"
        files: [sqlite_brain_ops.py]
        status: FIXED  # added _MAX_EXPORT caps (50K neurons, 100K synapses, 50K fibers)
    fixes:
      - date: "2026-02-17"
        desc: "Add min(limit, MAX) to 15 storage methods across SQLite + InMemory implementations"
        files: [sqlite_neurons.py, sqlite_fibers.py, sqlite_typed.py, sqlite_projects.py, sqlite_versioning.py, sqlite_coactivation.py, sqlite_action_log.py, memory_store.py, memory_collections.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add LIMIT 10000 safety cap to get_synapses() and get_co_activation_counts()"
        files: [sqlite_synapses.py, sqlite_coactivation.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fix CORS: replace wildcard patterns with explicit localhost origins"
        files: [app.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add localhost restriction to OAuth router and sync/stats endpoint"
        files: [oauth.py, sync.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fix merge_brain() atomicity: restore from backup on import failure"
        files: [brain.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fix import_brain() orphan: move brain INSERT inside transaction"
        files: [sqlite_brain_ops.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fix dashboard fiber diagram: use get_fiber() + get_synapses_for_neurons()"
        files: [dashboard_api.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Remove duplicate index, fix docstring placement, add Query() validation"
        files: [sqlite_schema.py, sqlite_action_log.py, memory.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Fix shared_store stale session header + factory.py broad Exception catch"
        files: [shared_store.py, factory.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Cap export_brain() with _MAX_EXPORT limits (50K neurons, 100K synapses, 50K fibers)"
        files: [sqlite_brain_ops.py]
        status: VERIFIED

  phase_3:
    modules: [unified_config.py, utils/config.py, config_presets.py, cli/config.py, cli/commands/config_cmd.py, engine/dedup/config.py, engine/embedding/config.py]
    loc: 1604
    files: 7
    status: COMPLETE
    findings:
      # --- CONFIG SECURITY ---
      - id: P3-001
        severity: HIGH
        category: CONFIG_SECURITY
        desc: "TOML injection via unsanitized dedup string fields (llm_provider, llm_model, merge_strategy)"
        files: [unified_config.py]
        status: FIXED
      # --- IMMUTABILITY ---
      - id: P3-002
        severity: HIGH
        category: IMMUTABILITY
        desc: "get_preset() returns direct reference to module-level mutable dicts"
        files: [config_presets.py]
        status: FIXED
      # --- CORRECTNESS ---
      - id: P3-003
        severity: MEDIUM
        category: DEAD_CODE
        desc: "Dead code in apply_preset: maintenance replace() result immediately overwritten"
        files: [config_presets.py]
        status: FIXED
      - id: P3-004
        severity: MEDIUM
        category: CORRECTNESS
        desc: "Accessing private _conn attribute to check storage liveness"
        files: [unified_config.py]
        status: DEFERRED
      - id: P3-005
        severity: LOW
        category: DEAD_CODE
        desc: "updated_at field on UnifiedConfig declared but never set or serialized"
        files: [unified_config.py]
        status: FIXED  # removed field + unused datetime import
      # --- ERROR HANDLING ---
      - id: P3-006
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "Bare except: pass in _read_current_brain_from_toml()"
        files: [unified_config.py]
        status: FIXED
      - id: P3-007
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "Bare except: continue in _read_legacy_brain() hides migration errors"
        files: [unified_config.py]
        status: FIXED
      # --- PATH SECURITY ---
      - id: P3-008
        severity: MEDIUM
        category: PATH_SECURITY
        desc: "get_brain_path() and get_brain_db_path() missing brain name validation"
        files: [cli/config.py]
        status: FIXED
      - id: P3-009
        severity: MEDIUM
        category: PATH_SECURITY
        desc: "NEURALMEMORY_DIR env var used without validation"
        files: [cli/config.py]
        status: FIXED  # Path(env_dir).resolve() in both unified_config.py and cli/config.py
      - id: P3-010
        severity: MEDIUM
        category: PATH_SECURITY
        desc: "sqlite_path from env var not validated in utils/config.py"
        files: [utils/config.py]
        status: DEFERRED
      # --- TYPE SAFETY ---
      - id: P3-011
        severity: LOW
        category: TYPE_SAFETY
        desc: "config: Any → UnifiedConfig in compute_diff/apply_preset"
        files: [config_presets.py]
        status: FIXED
      - id: P3-012
        severity: LOW
        category: IMMUTABILITY
        desc: "AutoConfig, BrainSettings, EternalConfig not frozen (inconsistent with other sub-configs)"
        files: [unified_config.py]
        status: DEFERRED
      - id: P3-013
        severity: LOW
        category: CONFIG_SECURITY
        desc: "Neo4j password stored as plain str in Config dataclass (no masking)"
        files: [utils/config.py]
        status: DEFERRED
      - id: P3-014
        severity: LOW
        category: DEAD_CODE
        desc: "utils/config.py Config class appears superseded by UnifiedConfig"
        files: [utils/config.py]
        status: DEFERRED
    fixes:
      - date: "2026-02-17"
        desc: "Add _sanitize_toml_str() and apply to dedup llm_provider/llm_model/merge_strategy in save()"
        files: [unified_config.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "get_preset() returns deepcopy to prevent mutation of module-level dicts"
        files: [config_presets.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Remove dead replace() block in apply_preset, unused import, fix type: Any → UnifiedConfig"
        files: [config_presets.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add logging to bare except blocks in _read_current_brain_from_toml and _read_legacy_brain"
        files: [unified_config.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add brain name validation + path traversal check in get_brain_path/get_brain_db_path"
        files: [cli/config.py]
        status: VERIFIED

  phase_4:
    modules: [mcp/, cli/]
    loc: 10749
    files: 41
    status: COMPLETE
    findings:
      # --- PATH TRAVERSAL (CRITICAL/HIGH) ---
      - id: P4-001
        severity: CRITICAL
        category: PATH_SECURITY
        desc: "cli/commands/tools.py:481 — hooks --path param used directly without resolve()"
        files: [cli/commands/tools.py]
        status: FIXED
      - id: P4-002
        severity: CRITICAL
        category: PATH_SECURITY
        desc: "cli/commands/brain.py:226 — import file path opened without validation"
        files: [cli/commands/brain.py]
        status: FIXED
      - id: P4-003
        severity: CRITICAL
        category: PATH_SECURITY
        desc: "cli/commands/shortcuts.py:327 — import input_file path used without resolve()"
        files: [cli/commands/shortcuts.py]
        status: FIXED
      - id: P4-004
        severity: HIGH
        category: PATH_SECURITY
        desc: "mcp/db_train_handler.py — SQLite connection_string path not validated for existence"
        files: [mcp/db_train_handler.py]
        status: FIXED
      - id: P4-005
        severity: HIGH
        category: PATH_SECURITY
        desc: "mcp/index_handler.py — adapter connection paths (ChromaDB, AWF, LlamaIndex) not validated"
        files: [mcp/index_handler.py]
        status: FIXED
      # --- DATETIME ---
      - id: P4-006
        severity: MEDIUM
        category: CORRECTNESS
        desc: "maintenance_handler.py:188 — datetime.now(UTC) instead of utcnow()"
        files: [mcp/maintenance_handler.py]
        status: FIXED
      - id: P4-007
        severity: MEDIUM
        category: CORRECTNESS
        desc: "mem0_sync_handler.py:92 — datetime.now(UTC) instead of utcnow()"
        files: [mcp/mem0_sync_handler.py]
        status: FIXED
      # --- BOUNDS ---
      - id: P4-008
        severity: MEDIUM
        category: BOUNDS
        desc: "tool_schemas.py — pugbrain_context.limit missing maximum (unbounded)"
        files: [mcp/tool_schemas.py]
        status: FIXED
      - id: P4-009
        severity: MEDIUM
        category: BOUNDS
        desc: "tool_schemas.py — pugbrain_import.limit missing maximum (unbounded)"
        files: [mcp/tool_schemas.py]
        status: FIXED
      # --- INFO LEAK ---
      - id: P4-010
        severity: MEDIUM
        category: SECURITY
        desc: "conflict_handler.py:146 — internal synapse.source_id leaked in error message"
        files: [mcp/conflict_handler.py]
        status: FIXED
      # --- ERROR HANDLING ---
      - id: P4-011
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "brain.py:191 — export file write has no error handling"
        files: [cli/commands/brain.py]
        status: FIXED
      - id: P4-012
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "shortcuts.py:290 — export file write has no error handling"
        files: [cli/commands/shortcuts.py]
        status: FIXED
      - id: P4-013
        severity: LOW
        category: ERROR_HANDLING
        desc: "update_check.py — 4 bare except Exception: blocks (narrowed to specific types)"
        files: [cli/update_check.py]
        status: FIXED
      - id: P4-014
        severity: LOW
        category: ERROR_HANDLING
        desc: "_helpers.py:47 — bare except in storage cleanup (narrowed)"
        files: [cli/_helpers.py]
        status: FIXED
      # --- CORRECTNESS (lower) ---
      - id: P4-015
        severity: MEDIUM
        category: CORRECTNESS
        desc: "unified_config.py — logger not defined (bare except → logging added in Phase 3 but logger missing)"
        files: [unified_config.py]
        status: FIXED
      # --- DEFERRED ---
      - id: P4-016
        severity: MEDIUM
        category: CORRECTNESS
        desc: "update.py:184 — hardcoded 'main' branch in git pull"
        files: [cli/commands/update.py]
        status: FIXED  # detect current branch via git rev-parse, fallback to 'main'
      - id: P4-017
        severity: LOW
        category: PATH_SECURITY
        desc: "setup.py — .claude/.cursor path symlink attack vectors"
        files: [cli/setup.py]
        status: DEFERRED
    fixes:
      - date: "2026-02-17"
        desc: "Resolve + validate path in tools.py hooks, brain.py import, shortcuts.py import"
        files: [cli/commands/tools.py, cli/commands/brain.py, cli/commands/shortcuts.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add SQLite file existence check in db_train_handler + path validation in index_handler"
        files: [mcp/db_train_handler.py, mcp/index_handler.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Replace datetime.now(UTC) with utcnow() in maintenance_handler and mem0_sync_handler"
        files: [mcp/maintenance_handler.py, mcp/mem0_sync_handler.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add maximum bounds to pugbrain_context.limit (200) and pugbrain_import.limit (10000)"
        files: [mcp/tool_schemas.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Remove internal synapse.source_id from error message in conflict_handler"
        files: [mcp/conflict_handler.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add error handling on export file writes in brain.py and shortcuts.py"
        files: [cli/commands/brain.py, cli/commands/shortcuts.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Narrow bare except blocks in update_check.py (4 spots) and _helpers.py"
        files: [cli/update_check.py, cli/_helpers.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add logger = logging.getLogger(__name__) to unified_config.py"
        files: [unified_config.py]
        status: VERIFIED

  phase_5:
    modules: [integration/, extraction/]
    loc: 6294
    files: 22
    status: COMPLETE
    started: "2026-02-17"
    completed: "2026-02-17"
    findings:
      # --- integration/ HIGH ---
      - id: P5-001
        severity: HIGH
        category: INFO_LEAK
        desc: "adapters/__init__.py — error message lists all available adapter names"
        files: [integration/adapters/__init__.py]
        status: FIXED
      - id: P5-002
        severity: HIGH
        category: PATH_SECURITY
        desc: "awf_adapter.py:42 — dead '..' traversal check replaced with is_dir() validation"
        files: [integration/adapters/awf_adapter.py]
        status: FIXED
      - id: P5-003
        severity: HIGH
        category: INFO_LEAK
        desc: "awf_adapter.py:107-131 — health_check errors expose filesystem paths"
        files: [integration/adapters/awf_adapter.py]
        status: FIXED
      - id: P5-004
        severity: HIGH
        category: BOUNDS
        desc: "sync_engine.py — sync limit unbounded, allows arbitrarily large imports"
        files: [integration/sync_engine.py]
        status: FIXED
      - id: P5-005
        severity: HIGH
        category: INFO_LEAK
        desc: "sync_engine.py — str(e) leaked in error list returned to caller"
        files: [integration/sync_engine.py]
        status: FIXED
      # --- extraction/ HIGH ---
      - id: P5-006
        severity: HIGH
        category: ERROR_HANDLING
        desc: "codebase.py:91-104 — PythonExtractor unhandled OSError/SyntaxError/UnicodeDecodeError on file read/parse"
        files: [extraction/codebase.py]
        status: FIXED
      - id: P5-007
        severity: HIGH
        category: ERROR_HANDLING
        desc: "codebase.py:445-449 — RegexExtractor unhandled OSError on file read"
        files: [extraction/codebase.py]
        status: FIXED
      - id: P5-008
        severity: HIGH
        category: PERFORMANCE
        desc: "entities.py:400 — re.compile() inside hot loop in _extract_locations()"
        files: [extraction/entities.py]
        status: FIXED
      # --- integration/ MEDIUM ---
      - id: P5-009
        severity: MEDIUM
        category: INFO_LEAK
        desc: "mapper.py:170 — sensitive content rejection leaks detection types in error"
        files: [integration/mapper.py]
        status: FIXED
      - id: P5-010
        severity: MEDIUM
        category: IMMUTABILITY
        desc: "entities.py — Entity dataclass not frozen"
        files: [extraction/entities.py]
        status: FIXED
      - id: P5-011
        severity: MEDIUM
        category: IMMUTABILITY
        desc: "keywords.py — WeightedKeyword dataclass not frozen"
        files: [extraction/keywords.py]
        status: FIXED
      - id: P5-012
        severity: MEDIUM
        category: IMMUTABILITY
        desc: "temporal.py — TimeHint dataclass not frozen"
        files: [extraction/temporal.py]
        status: FIXED
      - id: P5-013
        severity: MEDIUM
        category: IMMUTABILITY
        desc: "entities.py — VI_PERSON_PREFIXES and LOCATION_INDICATORS are mutable sets"
        files: [extraction/entities.py]
        status: FIXED
      - id: P5-014
        severity: MEDIUM
        category: NAMESPACE_LEAK
        desc: "sentiment.py:441-443 — loop variables _emotion, _words, _word leak into module namespace"
        files: [extraction/sentiment.py]
        status: FIXED
      # --- DEFERRED ---
      - id: P5-015
        severity: MEDIUM
        category: IMMUTABILITY
        desc: "parser.py — Stimulus dataclass has mutable list fields; freezing would not prevent list mutation"
        files: [extraction/parser.py]
        status: DEFERRED
      - id: P5-016
        severity: LOW
        category: PERFORMANCE
        desc: "sync_engine.py — import loop awaits each record sequentially"
        files: [integration/sync_engine.py]
        status: DEFERRED
      - id: P5-017
        severity: LOW
        category: DEAD_CODE
        desc: "adapters/graphiti_adapter.py — connection_kwargs unused placeholder"
        files: [integration/adapters/graphiti_adapter.py]
        status: ALREADY_DONE  # no connection_kwargs found in current code
      - id: P5-018
        severity: LOW
        category: DEAD_CODE
        desc: "adapters/cognee_adapter.py — connection_kwargs unused placeholder"
        files: [integration/adapters/cognee_adapter.py]
        status: ALREADY_DONE  # no connection_kwargs found in current code
    fixes:
      - date: "2026-02-17"
        desc: "Remove available adapter names from error, generic message only"
        files: [integration/adapters/__init__.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Replace dead '..' check with is_dir() + remove filesystem paths from health_check errors"
        files: [integration/adapters/awf_adapter.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add _MAX_SYNC_LIMIT=10000 cap + sanitize error messages in sync_engine"
        files: [integration/sync_engine.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Change sensitive content rejection to generic error message"
        files: [integration/mapper.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Wrap PythonExtractor + RegexExtractor file operations in try/except"
        files: [extraction/codebase.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Pre-compile location regex patterns as class-level dict"
        files: [extraction/entities.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Freeze Entity, WeightedKeyword, TimeHint dataclasses + frozenset for class constants"
        files: [extraction/entities.py, extraction/keywords.py, extraction/temporal.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Clean up module-level loop variable leak with del statement"
        files: [extraction/sentiment.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Update AWFAdapter test to expect ValueError on nonexistent dir"
        files: [tests/unit/test_integration.py]
        status: VERIFIED

  phase_6:
    modules: [core/, safety/, utils/, sync/]
    loc: 4238
    files: 21
    status: COMPLETE
    started: "2026-02-17"
    completed: "2026-02-17"
    findings:
      # --- CRITICAL ---
      - id: P6-001
        severity: CRITICAL
        category: IMMUTABILITY
        desc: "synapse.py — Synapse is not frozen (violates core model immutability contract)"
        files: [core/synapse.py]
        status: FIXED
      # --- HIGH ---
      - id: P6-002
        severity: HIGH
        category: IMMUTABILITY
        desc: "fiber.py — Fiber is not frozen (has _pathway_index lazy cache)"
        files: [core/fiber.py]
        status: FIXED
      - id: P6-003
        severity: HIGH
        category: IMMUTABILITY
        desc: "neuron.py — NeuronState is not frozen"
        files: [core/neuron.py]
        status: FIXED
      - id: P6-004
        severity: HIGH
        category: IMMUTABILITY
        desc: "Mutable dict/list defaults on frozen dataclasses (Neuron.metadata, Brain.metadata, etc.)"
        files: [core/neuron.py, core/brain.py, core/fiber.py]
        status: DEFERRED  # Python limitation — document as forbidden mutation
      - id: P6-005
        severity: HIGH
        category: ERROR_HANDLING
        desc: "SyncEvent.from_dict — datetime.fromisoformat uncaught ValueError on malformed timestamp"
        files: [sync/client.py]
        status: FIXED
      # --- MEDIUM ---
      - id: P6-006
        severity: MEDIUM
        category: ERROR_HANDLING
        desc: "project.py:179-184 — from_dict datetime.fromisoformat uncaught ValueError"
        files: [core/project.py]
        status: FIXED
      - id: P6-007
        severity: MEDIUM
        category: SECURITY
        desc: "brain_mode.py:223 — to_dict serializes api_key in plaintext"
        files: [core/brain_mode.py]
        status: FIXED
      - id: P6-008
        severity: MEDIUM
        category: PERFORMANCE
        desc: "sensitive.py:196-197 — re.compile() inside loop on every check_sensitive_content call"
        files: [safety/sensitive.py]
        status: FIXED
      - id: P6-009
        severity: MEDIUM
        category: PERFORMANCE
        desc: "trigger_engine.py:216-218 — re.search() on raw strings inside hot loop"
        files: [core/trigger_engine.py]
        status: FIXED
      - id: P6-010
        severity: MEDIUM
        category: CODE_QUALITY
        desc: "brain.py:66-145 — BrainConfig.with_updates manually lists 40 fields (fragile)"
        files: [core/brain.py]
        status: FIXED
      - id: P6-011
        severity: MEDIUM
        category: SECURITY
        desc: "sensitive.py — no content length cap before regex matching (ReDoS risk)"
        files: [safety/sensitive.py]
        status: FIXED
      - id: P6-012
        severity: MEDIUM
        category: IMMUTABILITY
        desc: "Neuron.with_metadata shared mutable reference risk"
        files: [core/neuron.py]
        status: DEFERRED  # document metadata values should be immutable
      - id: P6-013
        severity: MEDIUM
        category: PERFORMANCE
        desc: "EternalContext.get_status N+1: 10 separate queries for type counts"
        files: [core/eternal_context.py]
        status: DEFERRED
      - id: P6-014
        severity: MEDIUM
        category: CORRECTNESS
        desc: "suggest_memory_type uses substring matching (false positives)"
        files: [core/memory_types.py]
        status: FIXED  # word boundary matching via _has_keyword() with \b regex
      - id: P6-015
        severity: MEDIUM
        category: CORRECTNESS
        desc: "Config singleton not thread-safe"
        files: [utils/config.py]
        status: DEFERRED
      # --- LOW ---
      - id: P6-016
        severity: LOW
        category: IMMUTABILITY
        desc: "DriftReport.variants is mutable list on frozen dataclass"
        files: [utils/tag_normalizer.py]
        status: FIXED
      - id: P6-017
        severity: LOW
        category: IMMUTABILITY
        desc: "FreshnessResult and MemoryFreshnessReport not frozen"
        files: [safety/freshness.py]
        status: FIXED
      - id: P6-018
        severity: LOW
        category: IMMUTABILITY
        desc: "SyncEvent not frozen"
        files: [sync/client.py]
        status: DEFERRED  # has mutable dict[str, Any] data field
      - id: P6-019
        severity: LOW
        category: IMMUTABILITY
        desc: "BrainSnapshot not frozen"
        files: [core/brain.py]
        status: FIXED
      - id: P6-020
        severity: LOW
        category: ERROR_HANDLING
        desc: "sensitive.py — silently swallows regex compilation errors"
        files: [safety/sensitive.py]
        status: FIXED
      - id: P6-021
        severity: LOW
        category: CODE_QUALITY
        desc: "sync/client.py — redundant import logging inside run_forever()"
        files: [sync/client.py]
        status: FIXED
      - id: P6-022
        severity: LOW
        category: CORRECTNESS
        desc: "SyncEvent.from_dict may produce timezone-aware datetime"
        files: [sync/client.py]
        status: FIXED
      - id: P6-023
        severity: LOW
        category: ERROR_HANDLING
        desc: "eternal_context.py:271 — broad except Exception in _get_memory_content"
        files: [core/eternal_context.py]
        status: FIXED
    fixes:
      - date: "2026-02-17"
        desc: "Freeze Synapse, Fiber, NeuronState dataclasses (object.__setattr__ for Fiber cache)"
        files: [core/synapse.py, core/fiber.py, core/neuron.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Guard SyncEvent.from_dict timestamp with try/except + strip tzinfo"
        files: [sync/client.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Mask api_key in BrainModeConfig.to_dict serialization"
        files: [core/brain_mode.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Pre-compile regex patterns in sensitive.py (cache) and trigger_engine.py (module-level)"
        files: [safety/sensitive.py, core/trigger_engine.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Replace 80-line BrainConfig.with_updates with dc_replace(self, **kwargs)"
        files: [core/brain.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Add _MAX_CONTENT_LENGTH cap + logger.warning for invalid regex in sensitive.py"
        files: [safety/sensitive.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Guard Project.from_dict datetime parsing with try/except + utcnow() fallback"
        files: [core/project.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "DriftReport.variants list -> tuple, freeze FreshnessResult + MemoryFreshnessReport + BrainSnapshot"
        files: [utils/tag_normalizer.py, safety/freshness.py, core/brain.py]
        status: VERIFIED
      - date: "2026-02-17"
        desc: "Remove redundant import logging, narrow broad Exception in eternal_context"
        files: [sync/client.py, core/eternal_context.py]
        status: VERIFIED
