{
  "batch": "Abstractions & Dependencies",
  "batch_index": 2,
  "assessments": {
    "abstraction_fitness": 68.0
  },
  "dimension_notes": {
    "abstraction_fitness": {
      "evidence": [
        "Language-to-doc behavior is spread across multiple large switches: URL construction in cmd/get.go:78-173, type mapping in cmd/get.go:175-205, and term derivation in cmd/ask.go:205-260+.",
        "External scraper implementations repeat the same transport/change-detection scaffold (config+parser+http client fields, URL check, fetchPage, generateHash, DetectChanges) across multiple files, e.g. internal/scraper/external/godocs.go:17-121, internal/scraper/external/javadocs.go:16-115, internal/scraper/external/nuxtdocs.go:16-120, internal/scraper/external/cloudflaredocs.go:16-105.",
        "Vector store abstraction exposes implementations that are selected by default config but intentionally unimplemented: internal/config/config.go:121-125 defaults to chromem, while internal/vector/store.go:221-243 returns \"chromem store not implemented\" for all operations.",
        "Configuration defaults are duplicated in two representations (typed defaults and hand-written YAML template), increasing drift risk: cmd/init.go:92-149 and internal/config/config.go:104-160."
      ],
      "impact_scope": "subsystem",
      "fix_scope": "architectural_change",
      "confidence": "high",
      "sub_axes": {
        "abstraction_leverage": 62.0,
        "indirection_cost": 71.0,
        "interface_honesty": 60.0
      }
    }
  },
  "findings": [
    {
      "dimension": "abstraction_fitness",
      "identifier": "language_catalog_scattered_switches",
      "summary": "Language routing logic is duplicated across CLI flows instead of one catalog abstraction",
      "related_files": [
        "cmd/get.go",
        "cmd/ask.go"
      ],
      "evidence": [
        "cmd/get.go:78-173 defines a large language switch for URL building; cmd/get.go:175-205 defines a second switch for source type mapping.",
        "cmd/ask.go:205-260+ adds a third language switch for term heuristics, creating three independent sources of truth for one domain model."
      ],
      "suggestion": "Introduce a single `LanguageSpec` registry (aliases, source type, URL builder, optional query-term strategy) in one package and have both `get` and `ask` consume it; keep per-language behavior as data/functions attached to that registry.",
      "confidence": "high",
      "impact_scope": "subsystem",
      "fix_scope": "architectural_change"
    },
    {
      "dimension": "abstraction_fitness",
      "identifier": "external_scraper_scaffold_duplication",
      "summary": "External scraper adapters reimplement the same transport/hash lifecycle repeatedly",
      "related_files": [
        "internal/scraper/external/godocs.go",
        "internal/scraper/external/javadocs.go",
        "internal/scraper/external/nuxtdocs.go",
        "internal/scraper/external/cloudflaredocs.go"
      ],
      "evidence": [
        "Each file defines near-identical struct fields (`config`, `parser`, `client`), constructor wiring, URL-required guard, `fetchPage`, `generateHash`, and `DetectChanges` flow (e.g., godocs.go:17-121 and javadocs.go:16-115).",
        "Duplication scales linearly with each new source adapter, increasing edit surface for cross-cutting behavior (timeouts, headers, error mapping)."
      ],
      "suggestion": "Extract a shared `HTTPDocScraperBase` (or composable helper functions) for request execution, status handling, hashing, and change detection; keep each adapter focused on parser invocation and domain-specific document mapping.",
      "confidence": "high",
      "impact_scope": "subsystem",
      "fix_scope": "multi_file_refactor"
    },
    {
      "dimension": "abstraction_fitness",
      "identifier": "default_selects_unimplemented_store",
      "summary": "Store interface contract is dishonest because default backend is not operational",
      "related_files": [
        "internal/vector/store.go",
        "internal/config/config.go"
      ],
      "evidence": [
        "internal/config/config.go:121-125 sets default vector DB type to `chromem`.",
        "internal/vector/store.go:221-243 returns `chromem store not implemented` for all `Store` operations after `NewStore` can select that backend (store.go:63-72)."
      ],
      "suggestion": "Either implement `ChromemStore` before exposing it as default, or switch default to a working backend and gate chromem behind explicit opt-in plus capability check at startup.",
      "confidence": "high",
      "impact_scope": "module",
      "fix_scope": "architectural_change"
    },
    {
      "dimension": "abstraction_fitness",
      "identifier": "config_defaults_double_encoded",
      "summary": "Initialization defaults are encoded twice with different abstractions",
      "related_files": [
        "cmd/init.go",
        "internal/config/config.go"
      ],
      "evidence": [
        "cmd/init.go:92-149 hardcodes YAML defaults as a template string.",
        "internal/config/config.go:104-160 hardcodes defaults again in typed structs, requiring synchronized updates across two representations."
      ],
      "suggestion": "Generate init YAML from `config.Default()` via marshal + small post-processing/comments, or maintain a single canonical defaults schema consumed by both loader and init command.",
      "confidence": "high",
      "impact_scope": "module",
      "fix_scope": "multi_file_refactor"
    }
  ]
}