{
  "assessments": {
    "error_consistency": 50.0
  },
  "dimension_notes": {
    "error_consistency": {
      "evidence": [
        "cmd/scrape.go uses `wrapErr` for YAML fallback parsing but returns `%w` with outer `err` (`return fmt.Errorf(\"parse sources file: %w\", err)`), which can misreport or drop the actual parse failure.",
        "cmd/ask.go drops `localErr` (`localRanked = nil`) and later reports only live fetch errors, so a failed local retrieval path is silently omitted from the returned error contract.",
        "internal/search/engine.go frequently returns raw errors from filesystem/JSON boundaries (`return nil, err`) while nearby modules like internal/indexer/indexer.go and cmd/serve.go consistently wrap with operation context.",
        "internal/quality/plugins/go/analyzers/test_coverage.go returns `nil, nil` for missing `go` tool and missing `coverage.out`, but returns hard errors for other failures, creating mixed silent-skip vs fail-fast behavior in one detector family.",
        "internal/quality/plugins/go/plugin.go panics in package init on registration failure, while command entrypoints use returned errors + controlled process exit (cmd/root.go), producing inconsistent failure modes across startup paths."
      ],
      "impact_scope": "subsystem",
      "fix_scope": "multi_file_refactor",
      "confidence": "high",
      "unreported_risk": ""
    }
  },
  "findings": [
    {
      "dimension": "error_consistency",
      "identifier": "wrong_error_wrapped_in_sources_fallback_parse",
      "summary": "Fallback YAML parse wraps the wrong error variable, losing true parse context.",
      "related_files": [
        "cmd/scrape.go",
        "internal/config/config.go"
      ],
      "evidence": [
        "cmd/scrape.go:153-155 checks `wrapErr` but returns `%w` with `err` from a different scope.",
        "internal/config/config.go consistently wraps the current failing error with `%w` at parse/read boundaries, showing intended local convention."
      ],
      "suggestion": "In cmd/scrape.go, change the return to `fmt.Errorf(\"parse sources file: %w\", wrapErr)` so the emitted error always preserves the actual fallback parse failure.",
      "confidence": "high",
      "impact_scope": "module",
      "fix_scope": "single_edit"
    },
    {
      "dimension": "error_consistency",
      "identifier": "local_ask_retrieval_error_is_silently_dropped",
      "summary": "Local retrieval failures are discarded, so final errors hide one failing path.",
      "related_files": [
        "cmd/ask.go",
        "cmd/serve.go"
      ],
      "evidence": [
        "cmd/ask.go:122-125 sets `localRanked = nil` on `localErr` and does not append/report that error.",
        "cmd/ask.go:145-147 returns only `fetchErrors` for failure messaging, excluding local retrieval failure cause.",
        "cmd/serve.go wraps and propagates lower-level errors with operation context (`run devour_ask search: %w`), showing a stricter error propagation pattern at adjacent boundary code."
      ],
      "suggestion": "Capture `localErr` into the same error aggregation path (or return immediately with context) so both local and live retrieval failures are visible to callers.",
      "confidence": "high",
      "impact_scope": "subsystem",
      "fix_scope": "multi_file_refactor"
    },
    {
      "dimension": "error_consistency",
      "identifier": "search_engine_drops_operation_context_on_io_errors",
      "summary": "Search engine returns raw IO/JSON errors without operation context at key boundaries.",
      "related_files": [
        "internal/search/engine.go",
        "internal/indexer/indexer.go"
      ],
      "evidence": [
        "internal/search/engine.go returns bare errors at several boundaries (e.g., MkdirAll/listDocFiles/os.ReadFile/json.Unmarshal paths).",
        "internal/indexer/indexer.go wraps errors with explicit operation strings (`failed to generate embeddings`, `failed to add to vector store`), improving traceability."
      ],
      "suggestion": "Wrap engine boundary errors with operation-specific context (`fmt.Errorf(\"ensure index metadata: %w\", err)`, etc.) consistently across Rebuild/EnsureIndexed/Search.",
      "confidence": "medium",
      "impact_scope": "subsystem",
      "fix_scope": "multi_file_refactor"
    },
    {
      "dimension": "error_consistency",
      "identifier": "test_coverage_detector_mixes_silent_skip_and_hard_failure",
      "summary": "Coverage detector silently skips some environment failures but fails hard on others.",
      "related_files": [
        "internal/quality/plugins/go/analyzers/test_coverage.go",
        "internal/quality/scanner.go"
      ],
      "evidence": [
        "internal/quality/plugins/go/analyzers/test_coverage.go:39-41 returns `nil, nil` if `go` is unavailable; lines 50-51 also return `nil, nil` when profile is missing.",
        "The same detector returns hard errors for command execution failures (`failed to run test coverage`) and parse failures, yielding mixed failure contracts.",
        "internal/quality/scanner.go aggregates detector errors, so silent `nil,nil` prevents scanner-level visibility for some failure modes."
      ],
      "suggestion": "Standardize detector contract: either return explicit typed 'skipped' metadata/finding for non-actionable environment gaps, or return wrapped errors consistently so scanner can report them predictably.",
      "confidence": "high",
      "impact_scope": "subsystem",
      "fix_scope": "architectural_change"
    },
    {
      "dimension": "error_consistency",
      "identifier": "plugin_registration_uses_panic_while_cli_paths_return_errors",
      "summary": "Plugin init panics on registration failure instead of using returned error flow.",
      "related_files": [
        "internal/quality/plugins/go/plugin.go",
        "cmd/root.go"
      ],
      "evidence": [
        "internal/quality/plugins/go/plugin.go:360-363 panics in `init()` when registration fails.",
        "cmd/root.go:41-45 follows controlled error propagation (`Execute` prints error and exits), indicating a different process-level failure strategy."
      ],
      "suggestion": "Replace panic-based registration with explicit initialization returning errors (or a centralized startup validation step) so failures follow the same surfaced error path as other startup errors.",
      "confidence": "medium",
      "impact_scope": "subsystem",
      "fix_scope": "architectural_change"
    }
  ],
  "review_quality": {
    "batch_count": 1,
    "dimension_coverage": 1.0,
    "evidence_density": 1.0,
    "high_score_without_risk": 0,
    "finding_pressure": 12.12,
    "dimensions_with_findings": 1
  }
}
