mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-03 20:13:03 +00:00
i dont like commits
This commit is contained in:
@@ -0,0 +1,467 @@
|
||||
{
|
||||
"assessments": {
|
||||
"abstraction_fitness": {
|
||||
"score": 45.8,
|
||||
"components": [
|
||||
"Abstraction Leverage",
|
||||
"Indirection Cost",
|
||||
"Interface Honesty"
|
||||
],
|
||||
"component_scores": {
|
||||
"Abstraction Leverage": 65.5,
|
||||
"Indirection Cost": 62.1,
|
||||
"Interface Honesty": 71.5
|
||||
}
|
||||
},
|
||||
"cross_module_architecture": 56.0,
|
||||
"design_coherence": 49.3,
|
||||
"error_consistency": 44.4,
|
||||
"test_strategy": 46.3
|
||||
},
|
||||
"dimension_notes": {
|
||||
"cross_module_architecture": {
|
||||
"evidence": [
|
||||
"`internal/quality/enhanced_types.go` centralizes many unrelated boundary contracts (scoring metrics, detector transparency, narrative strategy/tools, debt tracking, config) in one package-level type hub.",
|
||||
"`internal/quality/types.go` also acts as a second broad contract hub (findings, scan result, scorecard, language/config, extraction structs), overlapping the same ownership area as `enhanced_types.go` instead of separating by subdomain.",
|
||||
"`internal/quality/scoring_test.go` consumes these shared package-level contracts directly, which reinforces coupling to a wide internal surface rather than narrower scorer-specific interfaces/types."
|
||||
],
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high",
|
||||
"unreported_risk": ""
|
||||
},
|
||||
"abstraction_fitness": {
|
||||
"evidence": [
|
||||
"Four external scrapers (Astro, Docker, Cloudflare, Nuxt) each reimplement the same transport/change-detection skeleton (`fetchPage`, `DetectChanges`, `generateHash`, per-page `Document` assembly) with only parser/model differences.",
|
||||
"`cmd/serve.go` RPC path for `devour_scrape` mutates CLI globals (`scrapeFormat`, `scrapeOutput`, `scrapeAllowEmpty`) to call `scrapeOne` from `cmd/scrape.go`, showing a leaky abstraction where server flow depends on CLI stateful wiring.",
|
||||
"`vector.Store` advertises interchangeable backends, but `NewStore` can return `ChromemStore` whose methods are all unimplemented runtime errors, so the abstraction surface overstates usable implementations."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high",
|
||||
"unreported_risk": "",
|
||||
"sub_axes": {
|
||||
"abstraction_leverage": 68.0,
|
||||
"indirection_cost": 73.0,
|
||||
"interface_honesty": 70.0
|
||||
}
|
||||
},
|
||||
"test_strategy": {
|
||||
"evidence": [
|
||||
"internal/quality/scoring_test.go is heavily unit-focused and validates scorer internals, but does not validate public contract stability between quality types and README-documented behavior.",
|
||||
"README.md publishes CLI and JSON-RPC command contracts, but assigned tests do not exercise those published interfaces as compatibility gates.",
|
||||
"pkg/rustdocs/parser_test.go and internal/quality/scoring_test.go include brittle assertions (fixed positional result indexing and strict output text matching) that couple tests to implementation/presentation details."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high",
|
||||
"unreported_risk": ""
|
||||
},
|
||||
"design_coherence": {
|
||||
"evidence": [
|
||||
"Command passthrough wrappers add non-functional indirection in language command modules: `languages/dart/commands.py` defines `_cmd_*_impl` plus thin `cmd_*` forwarders for each command (`cmd_large`, `cmd_complexity`, `cmd_deps`, `cmd_cycles`, `cmd_orphaned`, `cmd_dupes`).",
|
||||
"C# deps module mixes parsing, graph construction, CLI arg resolution, and terminal rendering in one file (`languages/csharp/detectors/deps.py` contains core graph builders and also `cmd_deps`/`cmd_cycles` UI handlers).",
|
||||
"Status rendering duplicates score-bar construction logic in two loops in `app/commands/status_parts/render.py` (same threshold/color/filled computation blocks around lines ~191-199 and ~223-231), increasing drift risk."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high",
|
||||
"unreported_risk": ""
|
||||
},
|
||||
"error_consistency": {
|
||||
"evidence": [
|
||||
"RPC paths mix strict and lax decode behavior: `cmd/serve.go` returns decode errors for `devour_scrape`/`devour_ask` but ignores decode errors for `devour_query` and `devour_sync` (`_ = json.Unmarshal(...)`).",
|
||||
"`cmd/serve.go` `devour_status` ignores errors from `LoadSourceState` and `EnsureIndexed` then dereferences `idxStats.Documents`, which can panic on nil when indexing fails.",
|
||||
"`internal/server/server.go` exposes raw internal errors to clients (`Message: err.Error()`), while parse/invalid-request errors are normalized strings; HTTP transport always emits 400 for any RPC error, collapsing error classes.",
|
||||
"`internal/ai/openai.go` does not check HTTP status before JSON decode, unlike scraper fetchers in `internal/scraper/external/*.go` and `internal/scraper/openapi.go` that explicitly gate on status codes.",
|
||||
"`internal/search/engine.go` and `internal/scraper/openapi.go` mix wrapped and passthrough errors in adjacent paths, producing uneven context for operators."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high",
|
||||
"unreported_risk": ""
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "cross_module_architecture",
|
||||
"identifier": "quality_package_contract_hub_coupling",
|
||||
"summary": "Quality contracts are concentrated in broad type hubs, creating a coupling hotspot.",
|
||||
"related_files": [
|
||||
"internal/quality/enhanced_types.go",
|
||||
"internal/quality/types.go",
|
||||
"internal/quality/scoring_test.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`enhanced_types.go` and `types.go` both define large cross-cutting models for multiple concerns (analysis narrative, scoring, detector stats, config, extraction metadata) under one package boundary.",
|
||||
"The two files blur subdomain ownership, so edits to one concern can force unrelated consumers in the same package to track evolving shared structs.",
|
||||
"Scoring tests rely on shared package contracts rather than a tighter scorer-local contract, indicating broad internal API exposure."
|
||||
],
|
||||
"suggestion": "Split `internal/quality` contracts by bounded concern (for example: `qualitycore` findings/scan types, `qualityscore` scorecard/metrics, `qualitynarrative` narrative/report DTOs) and keep scorer-facing types in a narrow subpackage/API. Migrate tests to import only scorer-relevant types to reduce transitive coupling.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "duplicated_external_scraper_skeleton",
|
||||
"summary": "External docs scrapers duplicate the same orchestration instead of sharing one adapter base",
|
||||
"related_files": [
|
||||
"internal/scraper/external/astrodocs.go",
|
||||
"internal/scraper/external/cloudflaredocs.go",
|
||||
"internal/scraper/external/dockerdocs.go",
|
||||
"internal/scraper/external/nuxtdocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"Each scraper defines near-identical `fetchPage`, `DetectChanges`, and `generateHash` logic.",
|
||||
"Each `Scrape` method repeats the same flow: validate URL -> fetch HTML -> parser call -> append main doc + sub-doc loop(s).",
|
||||
"Differences are mostly parser/model-specific mapping, but transport/error/hash logic is copy-pasted."
|
||||
],
|
||||
"suggestion": "Introduce a shared docs-scraper base (or helper pipeline) for HTTP fetch + hashing + standard error handling, and keep only parser-specific mapping in per-provider adapters.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "scrape_api_leaks_cli_state",
|
||||
"summary": "Server scrape RPC depends on mutable CLI globals to reuse scrape pipeline",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/scrape.go",
|
||||
"cmd/get.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`handleServeMethod` temporarily rewrites `scrapeFormat`, `scrapeOutput`, and `scrapeAllowEmpty` before calling `scrapeOne`, then restores them.",
|
||||
"`scrapeOne` is not a pure service API; it is coupled to CLI-level shared state and output behavior.",
|
||||
"`cmd/get.go` also routes through `runScrape`, reinforcing that scraping orchestration is command-centric rather than a reusable application service."
|
||||
],
|
||||
"suggestion": "Extract a stateless scrape service function (explicit request struct + options) used by both CLI commands and RPC handlers; keep CLI flags as translation-only at command boundary.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "vector_store_interface_overpromises",
|
||||
"summary": "Vector store abstraction exposes backends that are selectable but not actually implemented",
|
||||
"related_files": [
|
||||
"internal/vector/store.go",
|
||||
"internal/indexer/indexer.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`NewStore` can return `ChromemStore` when config type is `chromem`.",
|
||||
"All `ChromemStore` interface methods currently return `not implemented` errors.",
|
||||
"`Indexer` depends only on `vector.Store`, so backend failure appears at runtime after abstraction selection instead of at wiring/validation time."
|
||||
],
|
||||
"suggestion": "Make backend capabilities explicit: either remove/guard `chromem` selection until complete, or return an initialization error type from store construction and enforce backend readiness before indexing starts.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "cross_module_architecture",
|
||||
"identifier": "docs_runtime_quality_contract_drift",
|
||||
"summary": "Quality dimensions/statuses drift between public docs and runtime model contracts.",
|
||||
"related_files": [
|
||||
"README.md",
|
||||
"internal/quality/enhanced_types.go",
|
||||
"internal/quality/types.go"
|
||||
],
|
||||
"evidence": [
|
||||
"README.md frames score interpretation around a specific dimension set and user workflow.",
|
||||
"internal/quality/enhanced_types.go includes extra dimension constants not represented in README contract text.",
|
||||
"internal/quality/types.go includes StatusIgnored while README resolution examples only expose fixed/wontfix/false_positive paths."
|
||||
],
|
||||
"suggestion": "Define a single versioned public quality contract (dimensions + statuses) as source-of-truth, generate README contract tables from it, and add a CI check that fails when exported enums and published docs diverge.",
|
||||
"confidence": "medium",
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "test_strategy",
|
||||
"identifier": "missing_public_contract_compat_tests",
|
||||
"summary": "Published CLI/RPC governance contracts are not protected by compatibility tests.",
|
||||
"related_files": [
|
||||
"README.md",
|
||||
"internal/quality/scoring_test.go",
|
||||
"internal/quality/types.go"
|
||||
],
|
||||
"evidence": [
|
||||
"README.md documents stable command and RPC method surfaces for users.",
|
||||
"internal/quality/scoring_test.go covers scoring behavior but not end-to-end contract assertions tied to documented surfaces.",
|
||||
"No assigned test verifies that externally documented score/status semantics remain compatible with exported model types."
|
||||
],
|
||||
"suggestion": "Add contract tests that parse/validate documented command and RPC surface claims against runtime registration/types, and add schema-level golden tests for serialized quality/status payloads.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "test_strategy",
|
||||
"identifier": "brittle_assertions_on_order_and_formatting",
|
||||
"summary": "Tests are fragile due to strict ordering and presentation-string coupling.",
|
||||
"related_files": [
|
||||
"internal/quality/scoring_test.go",
|
||||
"pkg/rustdocs/parser_test.go"
|
||||
],
|
||||
"evidence": [
|
||||
"pkg/rustdocs/parser_test.go asserts semantic expectations through fixed indexes (results[0], results[1], results[2]) rather than identity-based matching.",
|
||||
"internal/quality/scoring_test.go asserts many exact output substrings in FormatScorecard, coupling tests to formatting text that can change without behavioral regressions."
|
||||
],
|
||||
"suggestion": "Refactor tests to assert semantic invariants (presence by key/kind, normalized structured fields) and reserve strict golden-output checks for explicitly versioned presentation contracts.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "passthrough_command_wrappers_add_low_leverage_layers",
|
||||
"summary": "Language command modules include thin forwarding wrappers with no behavioral value.",
|
||||
"related_files": [
|
||||
"desloppify/desloppify/desloppify/languages/dart/commands.py",
|
||||
"desloppify/desloppify/desloppify/languages/csharp/commands.py",
|
||||
"desloppify/desloppify/desloppify/languages/framework/commands_base.py"
|
||||
],
|
||||
"evidence": [
|
||||
"`languages/dart/commands.py` creates `_cmd_*_impl` callables and then defines six `cmd_*` functions that only call the corresponding impl.",
|
||||
"`languages/csharp/commands.py` also keeps thin wrappers (`cmd_large`, `cmd_complexity`, `cmd_deps`, `cmd_cycles`) that forward directly to other callables.",
|
||||
"The framework already provides factory-returned callables; wrapper layers increase symbol count and call depth without adding policy."
|
||||
],
|
||||
"suggestion": "Assign factory outputs directly to exported command names (or build the registry directly from generated callables) and keep wrappers only where they add language-specific behavior, validation, or formatting.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "csharp_deps_module_blends_core_and_cli_responsibilities",
|
||||
"summary": "C# dependency detector file combines analysis engine logic with CLI presentation.",
|
||||
"related_files": [
|
||||
"desloppify/desloppify/desloppify/languages/csharp/detectors/deps.py",
|
||||
"desloppify/desloppify/desloppify/languages/csharp/commands.py",
|
||||
"desloppify/desloppify/desloppify/languages/_shared/scaffold_detect_commands.py"
|
||||
],
|
||||
"evidence": [
|
||||
"`languages/csharp/detectors/deps.py` includes internal graph/parsing functions (`_parse_project_assets_references`, `_build_dep_graph_roslyn`, `build_dep_graph`) and command handlers (`cmd_deps`, `cmd_cycles`) in the same module.",
|
||||
"`languages/csharp/commands.py` forwards to `cmd_deps_direct`/`cmd_cycles_deps`, meaning command routing depends on detector-module UI functions instead of a clean detector API.",
|
||||
"Other language paths use shared command scaffolding (`languages/_shared/scaffold_detect_commands.py`) that separates command shell concerns from graph/detection logic."
|
||||
],
|
||||
"suggestion": "Split C# deps into `detectors/deps_core.py` (graph/parsing only) and command-facing adapters in `commands.py` (or scaffold factories), so detectors expose data and command modules own JSON/table rendering.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "status_bar_render_logic_duplicated_in_two_paths",
|
||||
"summary": "Status renderer repeats identical score-bar construction for mechanical and subjective rows.",
|
||||
"related_files": [
|
||||
"desloppify/desloppify/desloppify/app/commands/status_parts/render.py",
|
||||
"desloppify/desloppify/desloppify/app/output/scorecard_parts/projection.py"
|
||||
],
|
||||
"evidence": [
|
||||
"`show_dimension_table` in `status_parts/render.py` computes `filled`, score thresholds, and colored bar in one loop for mechanical dimensions and repeats the same logic in a second loop for subjective entries.",
|
||||
"Duplicated threshold constants (`>=98`, `>=93`) and color composition appear in both blocks, creating a two-site maintenance point for one rendering policy."
|
||||
],
|
||||
"suggestion": "Extract a shared `render_score_bar(score_val, bar_len)` helper (or move the row formatting policy into scorecard projection/output helpers) and reuse it for both loops to keep display semantics consistent.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "single_edit"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "rpc_decode_and_response_contract_drift",
|
||||
"summary": "RPC methods use inconsistent decode and error-response contracts",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"internal/server/server.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`cmd/serve.go` ignores JSON decode errors in `devour_query`/`devour_sync` but returns decode errors in `devour_scrape`/`devour_ask`.",
|
||||
"`internal/server/server.go` returns raw `err.Error()` in RPC payloads and maps all RPC errors to HTTP 400 in `writeRPC`."
|
||||
],
|
||||
"suggestion": "Define one RPC error policy: always validate/decode params the same way, map known classes to stable RPC codes/messages, and map transport HTTP statuses by error class (client input vs internal failure).",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "serve_status_swallows_errors_then_dereferences_nil",
|
||||
"summary": "Status handler ignores errors and can panic from nil stats",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"internal/search/engine.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`cmd/serve.go` uses `state, _ := projectstate.LoadSourceState(...)` and `idxStats, _ := engine.EnsureIndexed(ctx)` in `devour_status`.",
|
||||
"The same block unconditionally reads `idxStats.Documents` and `idxStats.LastIndexedAt`, which is unsafe if `EnsureIndexed` returned an error."
|
||||
],
|
||||
"suggestion": "Handle both errors explicitly in `devour_status`; return structured partial-status with an error field or fail the method uniformly, but do not ignore and dereference.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "single_edit"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "openai_http_error_path_not_normalized",
|
||||
"summary": "OpenAI client lacks explicit HTTP status error handling",
|
||||
"related_files": [
|
||||
"internal/ai/openai.go",
|
||||
"internal/scraper/openapi.go",
|
||||
"internal/scraper/external/astrodocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`internal/ai/openai.go` decodes response bodies directly and only checks `embeddingResp.Error`/`chatResp.Error`; non-2xx responses without expected JSON become generic decode errors.",
|
||||
"`internal/scraper/openapi.go` and external scrapers explicitly validate HTTP status before body parsing and return explicit HTTP status errors."
|
||||
],
|
||||
"suggestion": "Add explicit non-2xx handling in both OpenAI request paths: include status code, bounded response body excerpt, and endpoint context before JSON decode.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "mixed_wrapping_vs_passthrough_in_core_flows",
|
||||
"summary": "Adjacent paths alternate between wrapped and raw error returns",
|
||||
"related_files": [
|
||||
"internal/search/engine.go",
|
||||
"internal/scraper/openapi.go",
|
||||
"internal/config/config.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`internal/search/engine.go` frequently returns raw errors (`return nil, err`) from filesystem/index operations.",
|
||||
"`internal/scraper/openapi.go` similarly passes through request/file errors raw in `readSpec`, while other branches wrap with operation context.",
|
||||
"`internal/config/config.go` demonstrates contextual wrapping style (`read config`, `parse config`), creating drift against less-informative paths."
|
||||
],
|
||||
"suggestion": "Adopt a package-level rule: wrap external boundary failures with operation context (read/write/parse/network) and preserve `%w`; apply consistently across search/openapi paths.",
|
||||
"confidence": "medium",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "scanner_pipeline_fail_open_is_inconsistent",
|
||||
"summary": "Quality scan path mixes fail-open and fail-fast behaviors",
|
||||
"related_files": [
|
||||
"internal/quality/scanner.go",
|
||||
"internal/quality/plugins/go/analyzers/test_coverage.go",
|
||||
"internal/quality/plugins/go/analyzers/detectors.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`internal/quality/scanner.go` logs detector failures and continues, silently reducing coverage of reported findings.",
|
||||
"`test_coverage.go` returns `(nil, nil)` for missing `go` tool or missing generated coverage file, while other detector failures return explicit errors.",
|
||||
"`detectors.go` has parse/count paths that silently `continue` on per-file errors, further mixing behavior."
|
||||
],
|
||||
"suggestion": "Standardize detector error semantics with typed outcomes (hard error, soft-skip with reason, per-file skip count) and surface these in scan results so degraded scans are explicit.",
|
||||
"confidence": "medium",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "cross_module_architecture",
|
||||
"identifier": "rpc_cli_global_state_coupling",
|
||||
"summary": "RPC handlers mutate CLI global flags to execute workflows across command boundaries.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/scrape.go",
|
||||
"cmd/sync.go"
|
||||
],
|
||||
"evidence": [
|
||||
"cmd/serve.go sets scrapeFormat/scrapeOutput/scrapeAllowEmpty before calling scrapeOne and restores afterward.",
|
||||
"cmd/serve.go sets syncForce/syncRebuild/syncSource before calling runSync and restores afterward."
|
||||
],
|
||||
"suggestion": "Extract scrape/sync/query use-cases into stateless service functions (input structs + return structs), call them from both Cobra commands and RPC handlers, and remove shared mutable command globals from runtime execution paths.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "silent_error_drops_in_rpc_paths",
|
||||
"summary": "Several RPC paths ignore parse/index/state errors, producing inconsistent failure contracts.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"internal/search/engine.go",
|
||||
"internal/projectstate/state.go"
|
||||
],
|
||||
"evidence": [
|
||||
"cmd/serve.go ignores JSON unmarshal errors for devour_query/devour_sync (`_ = json.Unmarshal(...)`).",
|
||||
"cmd/serve.go ignores errors from LoadSourceState and EnsureIndexed, yet reads fields from returned values.",
|
||||
"Other command paths generally propagate wrapped errors with `%w`."
|
||||
],
|
||||
"suggestion": "Treat request decode, source-state load, and index-check failures uniformly: return explicit wrapped errors from each branch and avoid underscore-discarded errors in RPC handlers.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "single_edit"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "external_scraper_transport_duplication",
|
||||
"summary": "External scrapers duplicate the same HTTP fetch/hash/change-detection boilerplate.",
|
||||
"related_files": [
|
||||
"internal/scraper/external/reactdocs.go",
|
||||
"internal/scraper/external/tsdocs.go",
|
||||
"internal/scraper/external/godocs.go",
|
||||
"internal/scraper/external/rustdocs.go",
|
||||
"internal/scraper/external/cloudflaredocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"Each scraper reimplements equivalent `fetchPage` with identical request/header/response-body flow.",
|
||||
"Each scraper reimplements nearly identical `DetectChanges` and `generateHash` logic."
|
||||
],
|
||||
"suggestion": "Introduce a shared base helper (e.g., `fetchPage`, `contentHash`, `detectChanges`) in internal/scraper/external/types.go or a dedicated internal transport module, then keep per-scraper files focused on parser-to-document mapping.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "test_strategy",
|
||||
"identifier": "missing_tests_on_orchestration_and_adapters",
|
||||
"summary": "Critical orchestration commands and most external adapters have no direct tests.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/sync.go",
|
||||
"cmd/query.go",
|
||||
"internal/scraper/external/godocs.go",
|
||||
"internal/scraper/external/reactdocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"No *_test.go peers for cmd/serve.go, cmd/sync.go, cmd/query.go despite high-risk orchestration behavior.",
|
||||
"Only one external scraper has direct tests while many adapter implementations contain custom mapping and error-path logic."
|
||||
],
|
||||
"suggestion": "Add table-driven tests for RPC method branches and error propagation in cmd/serve.go, plus httptest-based adapter contract tests covering fetch failures, parser errors, and document mapping for each external scraper family.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "serve_handler_multi_responsibility_switch",
|
||||
"summary": "Single handler function mixes transport, parsing, orchestration, and mutable state management.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/scrape.go",
|
||||
"cmd/sync.go",
|
||||
"cmd/query.go"
|
||||
],
|
||||
"evidence": [
|
||||
"handleServeMethod contains method routing plus per-method request schemas, domain calls, and response shaping in one body.",
|
||||
"The function coordinates temporary mutation of command globals to reuse CLI code paths."
|
||||
],
|
||||
"suggestion": "Split each RPC method into dedicated handler functions (e.g., handleQueryRPC, handleScrapeRPC, handleSyncRPC) that depend on explicit service interfaces instead of command globals.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
}
|
||||
],
|
||||
"review_quality": {
|
||||
"batch_count": 6,
|
||||
"dimension_coverage": 0.367,
|
||||
"evidence_density": 1.667,
|
||||
"high_score_without_risk": 0,
|
||||
"finding_pressure": 48.928,
|
||||
"dimensions_with_findings": 5
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
You are a focused subagent reviewer for a single holistic investigation batch.
|
||||
|
||||
Repository root: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour
|
||||
Immutable packet: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour/.desloppify/review_packets/holistic_packet_20260224_101201.json
|
||||
Batch index: 1
|
||||
Batch name: Architecture & Coupling
|
||||
Batch dimensions: cross_module_architecture
|
||||
Batch rationale: god modules, import-time side effects
|
||||
|
||||
Files assigned:
|
||||
- internal/quality/enhanced_types.go
|
||||
- internal/quality/scoring_test.go
|
||||
- internal/quality/types.go
|
||||
- pkg/rustdocs/parser_test.go
|
||||
|
||||
Task requirements:
|
||||
1. Read the immutable packet and follow `system_prompt` constraints exactly.
|
||||
2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
|
||||
3. Return 0-10 high-quality findings for this batch (empty array allowed).
|
||||
4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
|
||||
5. Every finding must include `related_files` with at least 2 files when possible.
|
||||
6. Every finding must include `impact_scope` and `fix_scope`.
|
||||
7. Every scored dimension MUST include dimension_notes with concrete evidence.
|
||||
8. If a dimension score is >85, include `unreported_risk` in dimension_notes.
|
||||
9. Use exactly one decimal place for every assessment and abstraction sub-axis score.
|
||||
10. Do not edit repository files.
|
||||
11. Return ONLY valid JSON, no markdown fences.
|
||||
|
||||
Scope enums:
|
||||
- impact_scope: "local" | "module" | "subsystem" | "codebase"
|
||||
- fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
|
||||
|
||||
Output schema:
|
||||
{
|
||||
"batch": "Architecture & Coupling",
|
||||
"batch_index": 1,
|
||||
"assessments": {"<dimension>": <0-100 with one decimal place>},
|
||||
"dimension_notes": {
|
||||
"<dimension>": {
|
||||
"evidence": ["specific code observations"],
|
||||
"impact_scope": "local|module|subsystem|codebase",
|
||||
"fix_scope": "single_edit|multi_file_refactor|architectural_change",
|
||||
"confidence": "high|medium|low",
|
||||
"unreported_risk": "required when score >85",
|
||||
"sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
|
||||
}
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
You are a focused subagent reviewer for a single holistic investigation batch.
|
||||
|
||||
Repository root: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour
|
||||
Immutable packet: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour/.desloppify/review_packets/holistic_packet_20260224_101201.json
|
||||
Batch index: 2
|
||||
Batch name: Abstractions & Dependencies
|
||||
Batch dimensions: abstraction_fitness
|
||||
Batch rationale: abstraction hotspots (wrappers/interfaces/param bags), dep cycles
|
||||
|
||||
Files assigned:
|
||||
- internal/config/config.go
|
||||
- cmd/scrape.go
|
||||
- internal/quality/plugins/go/analyzers/detectors.go
|
||||
- internal/quality/plugins/go/analyzers/advanced.go
|
||||
- internal/scraper/web.go
|
||||
- internal/quality/plugins/go/plugin.go
|
||||
- internal/scheduler/scheduler.go
|
||||
- cmd/push.go
|
||||
- internal/scraper/localsearch_test.go
|
||||
- cmd/ask.go
|
||||
- internal/ai/openai.go
|
||||
- internal/server/server.go
|
||||
- cmd/get.go
|
||||
- internal/quality/analyzers/controlflow.go
|
||||
- internal/vector/store.go
|
||||
- examples/demo_scrapers.go
|
||||
- internal/indexer/indexer.go
|
||||
- internal/scraper/openapi.go
|
||||
- pkg/pythondocs/parser.go
|
||||
- cmd/get_test.go
|
||||
- internal/quality/scanner_test.go
|
||||
- internal/scraper/localsearch.go
|
||||
- internal/scraper/external/nuxtdocs.go
|
||||
- internal/quality/plugins/go/analyzers/test_coverage.go
|
||||
- internal/quality/scanner.go
|
||||
- internal/search/engine.go
|
||||
- cmd/serve.go
|
||||
- internal/scraper/github.go
|
||||
- internal/scraper/external/astrodocs.go
|
||||
- internal/scraper/external/cloudflaredocs.go
|
||||
- internal/scraper/external/dockerdocs.go
|
||||
|
||||
Task requirements:
|
||||
1. Read the immutable packet and follow `system_prompt` constraints exactly.
|
||||
2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
|
||||
3. Return 0-10 high-quality findings for this batch (empty array allowed).
|
||||
4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
|
||||
5. Every finding must include `related_files` with at least 2 files when possible.
|
||||
6. Every finding must include `impact_scope` and `fix_scope`.
|
||||
7. Every scored dimension MUST include dimension_notes with concrete evidence.
|
||||
8. If a dimension score is >85, include `unreported_risk` in dimension_notes.
|
||||
9. Use exactly one decimal place for every assessment and abstraction sub-axis score.
|
||||
10. Do not edit repository files.
|
||||
11. Return ONLY valid JSON, no markdown fences.
|
||||
|
||||
Scope enums:
|
||||
- impact_scope: "local" | "module" | "subsystem" | "codebase"
|
||||
- fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
|
||||
|
||||
Output schema:
|
||||
{
|
||||
"batch": "Abstractions & Dependencies",
|
||||
"batch_index": 2,
|
||||
"assessments": {"<dimension>": <0-100 with one decimal place>},
|
||||
"dimension_notes": {
|
||||
"<dimension>": {
|
||||
"evidence": ["specific code observations"],
|
||||
"impact_scope": "local|module|subsystem|codebase",
|
||||
"fix_scope": "single_edit|multi_file_refactor|architectural_change",
|
||||
"confidence": "high|medium|low",
|
||||
"unreported_risk": "required when score >85",
|
||||
"sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
|
||||
}
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
You are a focused subagent reviewer for a single holistic investigation batch.
|
||||
|
||||
Repository root: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour
|
||||
Immutable packet: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour/.desloppify/review_packets/holistic_packet_20260224_101201.json
|
||||
Batch index: 3
|
||||
Batch name: Governance & Contracts
|
||||
Batch dimensions: cross_module_architecture, test_strategy
|
||||
Batch rationale: architecture contracts, compatibility policy, docs-vs-runtime scope, and quality-gate coverage
|
||||
|
||||
Files assigned:
|
||||
- README.md
|
||||
- internal/quality/enhanced_types.go
|
||||
- internal/quality/scoring_test.go
|
||||
- internal/quality/types.go
|
||||
- pkg/rustdocs/parser_test.go
|
||||
|
||||
Task requirements:
|
||||
1. Read the immutable packet and follow `system_prompt` constraints exactly.
|
||||
2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
|
||||
3. Return 0-10 high-quality findings for this batch (empty array allowed).
|
||||
4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
|
||||
5. Every finding must include `related_files` with at least 2 files when possible.
|
||||
6. Every finding must include `impact_scope` and `fix_scope`.
|
||||
7. Every scored dimension MUST include dimension_notes with concrete evidence.
|
||||
8. If a dimension score is >85, include `unreported_risk` in dimension_notes.
|
||||
9. Use exactly one decimal place for every assessment and abstraction sub-axis score.
|
||||
10. Do not edit repository files.
|
||||
11. Return ONLY valid JSON, no markdown fences.
|
||||
|
||||
Scope enums:
|
||||
- impact_scope: "local" | "module" | "subsystem" | "codebase"
|
||||
- fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
|
||||
|
||||
Output schema:
|
||||
{
|
||||
"batch": "Governance & Contracts",
|
||||
"batch_index": 3,
|
||||
"assessments": {"<dimension>": <0-100 with one decimal place>},
|
||||
"dimension_notes": {
|
||||
"<dimension>": {
|
||||
"evidence": ["specific code observations"],
|
||||
"impact_scope": "local|module|subsystem|codebase",
|
||||
"fix_scope": "single_edit|multi_file_refactor|architectural_change",
|
||||
"confidence": "high|medium|low",
|
||||
"unreported_risk": "required when score >85",
|
||||
"sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
|
||||
}
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
You are a focused subagent reviewer for a single holistic investigation batch.
|
||||
|
||||
Repository root: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour
|
||||
Immutable packet: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour/.desloppify/review_packets/holistic_packet_20260224_101201.json
|
||||
Batch index: 4
|
||||
Batch name: Design Coherence — Mechanical Concern Signals
|
||||
Batch dimensions: design_coherence
|
||||
Batch rationale: mechanical detectors identified structural patterns needing judgment; concern types: design_concern, duplication_design
|
||||
|
||||
Files assigned:
|
||||
- desloppify/desloppify/desloppify/app/commands/_show_terminal.py
|
||||
- desloppify/desloppify/desloppify/app/commands/fix/apply_flow.py
|
||||
- desloppify/desloppify/desloppify/app/commands/issues_cmd.py
|
||||
- desloppify/desloppify/desloppify/app/commands/next.py
|
||||
- desloppify/desloppify/desloppify/app/commands/resolve/selection.py
|
||||
- desloppify/desloppify/desloppify/app/commands/scan/scan_reporting_llm.py
|
||||
- desloppify/desloppify/desloppify/app/commands/status_parts/render.py
|
||||
- desloppify/desloppify/desloppify/app/output/scorecard_parts/projection.py
|
||||
- desloppify/desloppify/desloppify/engine/detectors/security/rules.py
|
||||
- desloppify/desloppify/desloppify/engine/scoring_internal/subjective/core.py
|
||||
- desloppify/desloppify/desloppify/engine/state_internal/resolution.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/__init__.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/context_internal/structure.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/dimensions/data.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/importing/holistic.py
|
||||
- desloppify/desloppify/desloppify/languages/_shared/phases_common.py
|
||||
- desloppify/desloppify/desloppify/languages/_shared/review_data/dimensions.json
|
||||
- desloppify/desloppify/desloppify/languages/_shared/scaffold_detect_commands.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/_parse_helpers.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/commands.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/deps/cli.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/deps/fallback.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/phases.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/test_coverage.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/__init__.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/commands.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/extractors.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/move.py
|
||||
- desloppify/desloppify/desloppify/languages/framework/commands_base.py
|
||||
- desloppify/desloppify/desloppify/languages/gdscript/__init__.py
|
||||
- desloppify/desloppify/desloppify/languages/gdscript/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/python/__init__.py
|
||||
- desloppify/desloppify/desloppify/languages/python/commands.py
|
||||
- desloppify/desloppify/desloppify/languages/python/detectors/security.py
|
||||
- desloppify/desloppify/desloppify/languages/python/detectors/smells.py
|
||||
- desloppify/desloppify/desloppify/languages/python/move.py
|
||||
- desloppify/desloppify/desloppify/languages/python/phases.py
|
||||
- desloppify/desloppify/desloppify/languages/python/test_coverage.py
|
||||
- desloppify/desloppify/desloppify/languages/python/tests/test_py_facade.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/_smell_detectors.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/_smell_effects.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/exports.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/react.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/unused.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/fixers/common.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/fixers/if_chain.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/fixers/logs.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_concerns.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_deprecated.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_deps.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_exports.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_fixers.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_logs.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/tests/test_ts_react.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/fix/test_cmd_fix_review.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/test_cmd_detect.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/test_cmd_fix.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/test_cmd_next.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/test_cmd_scan.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/test_cmd_show.py
|
||||
- desloppify/desloppify/desloppify/tests/commands/test_config_cmd.py
|
||||
- desloppify/desloppify/desloppify/tests/detectors/test_architecture_boundaries.py
|
||||
- desloppify/desloppify/desloppify/tests/detectors/test_complexity.py
|
||||
- desloppify/desloppify/desloppify/tests/detectors/test_coupling.py
|
||||
- desloppify/desloppify/desloppify/tests/detectors/test_gods.py
|
||||
- desloppify/desloppify/desloppify/tests/detectors/test_naming.py
|
||||
- desloppify/desloppify/desloppify/tests/detectors/test_orphaned.py
|
||||
- desloppify/desloppify/desloppify/tests/lang/common/test_lang_contract_validation.py
|
||||
- desloppify/desloppify/desloppify/tests/lang/csharp/test_csharp_deps.py
|
||||
- desloppify/desloppify/desloppify/tests/lang/csharp/test_csharp_scan.py
|
||||
- desloppify/desloppify/desloppify/tests/lang/dart/test_dart_deps.py
|
||||
- desloppify/desloppify/desloppify/tests/review/test_review_coverage.py
|
||||
- desloppify/desloppify/desloppify/tests/review/test_review_dimensions_direct.py
|
||||
- desloppify/desloppify/desloppify/tests/review/test_work_queue.py
|
||||
- desloppify/desloppify/desloppify/tests/scan/test_flat_dirs.py
|
||||
- desloppify/desloppify/desloppify/tests/scan/test_scan_reporting_direct.py
|
||||
- desloppify/desloppify/desloppify/tests/scan/test_scan_workflow_wontfix_direct.py
|
||||
- desloppify/desloppify/desloppify/tests/scoring/test_scorecard.py
|
||||
- desloppify/desloppify/desloppify/tests/scoring/test_scorecard_draw_direct.py
|
||||
- desloppify/desloppify/desloppify/tests/snapshots/cli_smoke/state-python.json
|
||||
- desloppify/desloppify/desloppify/tests/state/test_state.py
|
||||
- desloppify/desloppify/desloppify/tests/state/test_state_internal_direct.py
|
||||
- devour_data/docs/docker_compose_-_ask_me_about_docker_1.md
|
||||
- devour_data/docs/docker_compose_-_browse_common_faqs_10.md
|
||||
- devour_data/docs/docker_compose_-_docker_compose_2.md
|
||||
- devour_data/docs/docker_compose_-_explore_the_compose_file_referenc_8.md
|
||||
- devour_data/docs/docker_compose_-_how_compose_works_4.md
|
||||
- devour_data/docs/docker_compose_-_install_compose_5.md
|
||||
- devour_data/docs/docker_compose_-_use_compose_bridge_9.md
|
||||
- internal/scraper/web.go
|
||||
- pkg/godocs/parser.go
|
||||
|
||||
Task requirements:
|
||||
1. Read the immutable packet and follow `system_prompt` constraints exactly.
|
||||
2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
|
||||
3. Return 0-10 high-quality findings for this batch (empty array allowed).
|
||||
4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
|
||||
5. Every finding must include `related_files` with at least 2 files when possible.
|
||||
6. Every finding must include `impact_scope` and `fix_scope`.
|
||||
7. Every scored dimension MUST include dimension_notes with concrete evidence.
|
||||
8. If a dimension score is >85, include `unreported_risk` in dimension_notes.
|
||||
9. Use exactly one decimal place for every assessment and abstraction sub-axis score.
|
||||
10. Do not edit repository files.
|
||||
11. Return ONLY valid JSON, no markdown fences.
|
||||
|
||||
Scope enums:
|
||||
- impact_scope: "local" | "module" | "subsystem" | "codebase"
|
||||
- fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
|
||||
|
||||
Output schema:
|
||||
{
|
||||
"batch": "Design Coherence — Mechanical Concern Signals",
|
||||
"batch_index": 4,
|
||||
"assessments": {"<dimension>": <0-100 with one decimal place>},
|
||||
"dimension_notes": {
|
||||
"<dimension>": {
|
||||
"evidence": ["specific code observations"],
|
||||
"impact_scope": "local|module|subsystem|codebase",
|
||||
"fix_scope": "single_edit|multi_file_refactor|architectural_change",
|
||||
"confidence": "high|medium|low",
|
||||
"unreported_risk": "required when score >85",
|
||||
"sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
|
||||
}
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
You are a focused subagent reviewer for a single holistic investigation batch.
|
||||
|
||||
Repository root: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour
|
||||
Immutable packet: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour/.desloppify/review_packets/holistic_packet_20260224_101201.json
|
||||
Batch index: 5
|
||||
Batch name: Cross-cutting Sweep
|
||||
Batch dimensions: error_consistency
|
||||
Batch rationale: selected dimensions had no direct batch mapping; review representative cross-cutting files
|
||||
|
||||
Files assigned:
|
||||
- internal/quality/enhanced_types.go
|
||||
- internal/quality/scoring_test.go
|
||||
- internal/quality/types.go
|
||||
- pkg/rustdocs/parser_test.go
|
||||
- internal/config/config.go
|
||||
- cmd/scrape.go
|
||||
- internal/quality/plugins/go/analyzers/detectors.go
|
||||
- internal/quality/plugins/go/analyzers/advanced.go
|
||||
- internal/scraper/web.go
|
||||
- internal/quality/plugins/go/plugin.go
|
||||
- internal/scheduler/scheduler.go
|
||||
- cmd/push.go
|
||||
- internal/scraper/localsearch_test.go
|
||||
- cmd/ask.go
|
||||
- internal/ai/openai.go
|
||||
- internal/server/server.go
|
||||
- cmd/get.go
|
||||
- internal/quality/analyzers/controlflow.go
|
||||
- internal/vector/store.go
|
||||
- examples/demo_scrapers.go
|
||||
- internal/indexer/indexer.go
|
||||
- internal/scraper/openapi.go
|
||||
- pkg/pythondocs/parser.go
|
||||
- cmd/get_test.go
|
||||
- internal/quality/scanner_test.go
|
||||
- internal/scraper/localsearch.go
|
||||
- internal/scraper/external/nuxtdocs.go
|
||||
- internal/quality/plugins/go/analyzers/test_coverage.go
|
||||
- internal/quality/scanner.go
|
||||
- internal/search/engine.go
|
||||
- cmd/serve.go
|
||||
- internal/scraper/github.go
|
||||
- internal/scraper/external/astrodocs.go
|
||||
- internal/scraper/external/cloudflaredocs.go
|
||||
- internal/scraper/external/dockerdocs.go
|
||||
- README.md
|
||||
- desloppify/desloppify/desloppify/app/commands/_show_terminal.py
|
||||
- desloppify/desloppify/desloppify/app/commands/fix/apply_flow.py
|
||||
- desloppify/desloppify/desloppify/app/commands/issues_cmd.py
|
||||
- desloppify/desloppify/desloppify/app/commands/next.py
|
||||
- desloppify/desloppify/desloppify/app/commands/resolve/selection.py
|
||||
- desloppify/desloppify/desloppify/app/commands/scan/scan_reporting_llm.py
|
||||
- desloppify/desloppify/desloppify/app/commands/status_parts/render.py
|
||||
- desloppify/desloppify/desloppify/app/output/scorecard_parts/projection.py
|
||||
- desloppify/desloppify/desloppify/engine/detectors/security/rules.py
|
||||
- desloppify/desloppify/desloppify/engine/scoring_internal/subjective/core.py
|
||||
- desloppify/desloppify/desloppify/engine/state_internal/resolution.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/__init__.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/context_internal/structure.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/dimensions/data.py
|
||||
- desloppify/desloppify/desloppify/intelligence/review/importing/holistic.py
|
||||
- desloppify/desloppify/desloppify/languages/_shared/phases_common.py
|
||||
- desloppify/desloppify/desloppify/languages/_shared/review_data/dimensions.json
|
||||
- desloppify/desloppify/desloppify/languages/_shared/scaffold_detect_commands.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/_parse_helpers.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/commands.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/deps/cli.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/deps/fallback.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/phases.py
|
||||
- desloppify/desloppify/desloppify/languages/csharp/test_coverage.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/__init__.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/commands.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/extractors.py
|
||||
- desloppify/desloppify/desloppify/languages/dart/move.py
|
||||
- desloppify/desloppify/desloppify/languages/framework/commands_base.py
|
||||
- desloppify/desloppify/desloppify/languages/gdscript/__init__.py
|
||||
- desloppify/desloppify/desloppify/languages/gdscript/detectors/deps.py
|
||||
- desloppify/desloppify/desloppify/languages/python/__init__.py
|
||||
- desloppify/desloppify/desloppify/languages/python/commands.py
|
||||
- desloppify/desloppify/desloppify/languages/python/detectors/security.py
|
||||
- desloppify/desloppify/desloppify/languages/python/detectors/smells.py
|
||||
- desloppify/desloppify/desloppify/languages/python/move.py
|
||||
- desloppify/desloppify/desloppify/languages/python/phases.py
|
||||
- desloppify/desloppify/desloppify/languages/python/test_coverage.py
|
||||
- desloppify/desloppify/desloppify/languages/python/tests/test_py_facade.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/_smell_detectors.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/_smell_effects.py
|
||||
- desloppify/desloppify/desloppify/languages/typescript/detectors/deps.py
|
||||
|
||||
Task requirements:
|
||||
1. Read the immutable packet and follow `system_prompt` constraints exactly.
|
||||
2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
|
||||
3. Return 0-10 high-quality findings for this batch (empty array allowed).
|
||||
4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
|
||||
5. Every finding must include `related_files` with at least 2 files when possible.
|
||||
6. Every finding must include `impact_scope` and `fix_scope`.
|
||||
7. Every scored dimension MUST include dimension_notes with concrete evidence.
|
||||
8. If a dimension score is >85, include `unreported_risk` in dimension_notes.
|
||||
9. Use exactly one decimal place for every assessment and abstraction sub-axis score.
|
||||
10. Do not edit repository files.
|
||||
11. Return ONLY valid JSON, no markdown fences.
|
||||
|
||||
Scope enums:
|
||||
- impact_scope: "local" | "module" | "subsystem" | "codebase"
|
||||
- fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
|
||||
|
||||
Output schema:
|
||||
{
|
||||
"batch": "Cross-cutting Sweep",
|
||||
"batch_index": 5,
|
||||
"assessments": {"<dimension>": <0-100 with one decimal place>},
|
||||
"dimension_notes": {
|
||||
"<dimension>": {
|
||||
"evidence": ["specific code observations"],
|
||||
"impact_scope": "local|module|subsystem|codebase",
|
||||
"fix_scope": "single_edit|multi_file_refactor|architectural_change",
|
||||
"confidence": "high|medium|low",
|
||||
"unreported_risk": "required when score >85",
|
||||
"sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
|
||||
}
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
You are a focused subagent reviewer for a single holistic investigation batch.
|
||||
|
||||
Repository root: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour
|
||||
Immutable packet: /home/tdvorak/Desktop/PROG_projekty/GOLANG/Devour/.desloppify/review_packets/holistic_packet_20260224_101201.json
|
||||
Batch index: 6
|
||||
Batch name: Full Codebase Sweep
|
||||
Batch dimensions: cross_module_architecture, error_consistency, abstraction_fitness, test_strategy, design_coherence
|
||||
Batch rationale: thorough default: evaluate cross-cutting quality across all production files
|
||||
|
||||
Files assigned:
|
||||
- cleanup_unused.go
|
||||
- cmd/ask.go
|
||||
- cmd/auto.go
|
||||
- cmd/demo.go
|
||||
- cmd/desloppify_proxy.go
|
||||
- cmd/devour/main.go
|
||||
- cmd/generate_scorecards/main.go
|
||||
- cmd/get.go
|
||||
- cmd/init.go
|
||||
- cmd/languages.go
|
||||
- cmd/push.go
|
||||
- cmd/quality.go
|
||||
- cmd/query.go
|
||||
- cmd/realtest/main.go
|
||||
- cmd/review.go
|
||||
- cmd/root.go
|
||||
- cmd/runtime_helpers.go
|
||||
- cmd/scorecard.go
|
||||
- cmd/scrape.go
|
||||
- cmd/serve.go
|
||||
- cmd/status.go
|
||||
- cmd/sync.go
|
||||
- cmd/verify.go
|
||||
- examples/demo_scrapers.go
|
||||
- internal/ai/ai.go
|
||||
- internal/ai/openai.go
|
||||
- internal/config/config.go
|
||||
- internal/indexer/indexer.go
|
||||
- internal/markdown/formatter.go
|
||||
- internal/projectstate/state.go
|
||||
- internal/quality/analyzers/controlflow.go
|
||||
- internal/quality/analyzers/dataflow.go
|
||||
- internal/quality/analyzers/practices.go
|
||||
- internal/quality/detector.go
|
||||
- internal/quality/detectors/complexity.go
|
||||
- internal/quality/detectors/duplication.go
|
||||
- internal/quality/detectors/naming.go
|
||||
- internal/quality/docs_evidence.go
|
||||
- internal/quality/enhanced_types.go
|
||||
- internal/quality/languages.go
|
||||
- internal/quality/plugins/go/analyzers/advanced.go
|
||||
- internal/quality/plugins/go/analyzers/deadcode.go
|
||||
- internal/quality/plugins/go/analyzers/detectors.go
|
||||
- internal/quality/plugins/go/analyzers/security.go
|
||||
- internal/quality/plugins/go/analyzers/test_coverage.go
|
||||
- internal/quality/plugins/go/fixers/advanced_fixers.go
|
||||
- internal/quality/plugins/go/fixers/fixers.go
|
||||
- internal/quality/plugins/go/plugin.go
|
||||
- internal/quality/plugins/plugin.go
|
||||
- internal/quality/plugins/registry.go
|
||||
- internal/quality/scanner.go
|
||||
- internal/quality/scoring.go
|
||||
- internal/quality/state.go
|
||||
- internal/quality/types.go
|
||||
- internal/scheduler/scheduler.go
|
||||
- internal/scraper/external/astrodocs.go
|
||||
- internal/scraper/external/cloudflaredocs.go
|
||||
- internal/scraper/external/dockerdocs.go
|
||||
- internal/scraper/external/godocs.go
|
||||
- internal/scraper/external/javadocs.go
|
||||
- internal/scraper/external/mcpdocs.go
|
||||
- internal/scraper/external/nuxtdocs.go
|
||||
- internal/scraper/external/pythondocs.go
|
||||
- internal/scraper/external/reactdocs.go
|
||||
- internal/scraper/external/register.go
|
||||
- internal/scraper/external/rustdocs.go
|
||||
- internal/scraper/external/springdocs.go
|
||||
- internal/scraper/external/tsdocs.go
|
||||
- internal/scraper/external/types.go
|
||||
- internal/scraper/external/vuedocs.go
|
||||
- internal/scraper/github.go
|
||||
- internal/scraper/local.go
|
||||
- internal/scraper/localsearch.go
|
||||
- internal/scraper/normalize.go
|
||||
- internal/scraper/openapi.go
|
||||
- internal/scraper/register_core.go
|
||||
- internal/scraper/registry_simple.go
|
||||
- internal/scraper/scraper.go
|
||||
- internal/scraper/web.go
|
||||
- internal/scraper/wrapper.go
|
||||
- internal/search/engine.go
|
||||
- internal/server/server.go
|
||||
- internal/storage/writer.go
|
||||
- internal/ui/banner.go
|
||||
- internal/ui/character.go
|
||||
- internal/vector/store.go
|
||||
- main.go
|
||||
- pkg/astrodocs/parser.go
|
||||
- pkg/astrodocs/types.go
|
||||
- pkg/client/client.go
|
||||
- pkg/cloudflaredocs/parser.go
|
||||
- pkg/cloudflaredocs/types.go
|
||||
- pkg/dockerdocs/parser.go
|
||||
- pkg/dockerdocs/types.go
|
||||
- pkg/godocs/parser.go
|
||||
- pkg/godocs/types.go
|
||||
- pkg/javadocs/parser.go
|
||||
- pkg/javadocs/types.go
|
||||
- pkg/mcpdocs/parser.go
|
||||
- pkg/mcpdocs/types.go
|
||||
- pkg/nuxtdocs/parser.go
|
||||
- pkg/nuxtdocs/types.go
|
||||
- pkg/parserutil/url.go
|
||||
- pkg/pythondocs/parser.go
|
||||
- pkg/pythondocs/types.go
|
||||
- pkg/reactdocs/parser.go
|
||||
- pkg/reactdocs/types.go
|
||||
- pkg/rustdocs/parser.go
|
||||
- pkg/rustdocs/types.go
|
||||
- pkg/springdocs/parser.go
|
||||
- pkg/springdocs/types.go
|
||||
- pkg/tsdocs/parser.go
|
||||
- pkg/tsdocs/types.go
|
||||
- pkg/types/types.go
|
||||
- pkg/vuedocs/parser.go
|
||||
- pkg/vuedocs/types.go
|
||||
|
||||
Task requirements:
|
||||
1. Read the immutable packet and follow `system_prompt` constraints exactly.
|
||||
2. Evaluate ONLY listed files and ONLY listed dimensions for this batch.
|
||||
3. Return 0-10 high-quality findings for this batch (empty array allowed).
|
||||
4. Score/finding consistency is required: broader or more severe findings MUST lower dimension scores.
|
||||
5. Every finding must include `related_files` with at least 2 files when possible.
|
||||
6. Every finding must include `impact_scope` and `fix_scope`.
|
||||
7. Every scored dimension MUST include dimension_notes with concrete evidence.
|
||||
8. If a dimension score is >85, include `unreported_risk` in dimension_notes.
|
||||
9. Use exactly one decimal place for every assessment and abstraction sub-axis score.
|
||||
10. Do not edit repository files.
|
||||
11. Return ONLY valid JSON, no markdown fences.
|
||||
|
||||
Scope enums:
|
||||
- impact_scope: "local" | "module" | "subsystem" | "codebase"
|
||||
- fix_scope: "single_edit" | "multi_file_refactor" | "architectural_change"
|
||||
|
||||
Output schema:
|
||||
{
|
||||
"batch": "Full Codebase Sweep",
|
||||
"batch_index": 6,
|
||||
"assessments": {"<dimension>": <0-100 with one decimal place>},
|
||||
"dimension_notes": {
|
||||
"<dimension>": {
|
||||
"evidence": ["specific code observations"],
|
||||
"impact_scope": "local|module|subsystem|codebase",
|
||||
"fix_scope": "single_edit|multi_file_refactor|architectural_change",
|
||||
"confidence": "high|medium|low",
|
||||
"unreported_risk": "required when score >85",
|
||||
"sub_axes": {"abstraction_leverage": 0-100 with one decimal place, "indirection_cost": 0-100 with one decimal place, "interface_honesty": 0-100 with one decimal place} // required for abstraction_fitness when evidence supports it
|
||||
}
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"batch": "Architecture & Coupling",
|
||||
"batch_index": 1,
|
||||
"assessments": {
|
||||
"cross_module_architecture": 82.0
|
||||
},
|
||||
"dimension_notes": {
|
||||
"cross_module_architecture": {
|
||||
"evidence": [
|
||||
"`internal/quality/enhanced_types.go` centralizes many unrelated boundary contracts (scoring metrics, detector transparency, narrative strategy/tools, debt tracking, config) in one package-level type hub.",
|
||||
"`internal/quality/types.go` also acts as a second broad contract hub (findings, scan result, scorecard, language/config, extraction structs), overlapping the same ownership area as `enhanced_types.go` instead of separating by subdomain.",
|
||||
"`internal/quality/scoring_test.go` consumes these shared package-level contracts directly, which reinforces coupling to a wide internal surface rather than narrower scorer-specific interfaces/types."
|
||||
],
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "cross_module_architecture",
|
||||
"identifier": "quality_package_contract_hub_coupling",
|
||||
"summary": "Quality contracts are concentrated in broad type hubs, creating a coupling hotspot.",
|
||||
"related_files": [
|
||||
"internal/quality/enhanced_types.go",
|
||||
"internal/quality/types.go",
|
||||
"internal/quality/scoring_test.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`enhanced_types.go` and `types.go` both define large cross-cutting models for multiple concerns (analysis narrative, scoring, detector stats, config, extraction metadata) under one package boundary.",
|
||||
"The two files blur subdomain ownership, so edits to one concern can force unrelated consumers in the same package to track evolving shared structs.",
|
||||
"Scoring tests rely on shared package contracts rather than a tighter scorer-local contract, indicating broad internal API exposure."
|
||||
],
|
||||
"suggestion": "Split `internal/quality` contracts by bounded concern (for example: `qualitycore` findings/scan types, `qualityscore` scorecard/metrics, `qualitynarrative` narrative/report DTOs) and keep scorer-facing types in a narrow subpackage/API. Migrate tests to import only scorer-relevant types to reduce transitive coupling.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"batch": "Abstractions & Dependencies",
|
||||
"batch_index": 2,
|
||||
"assessments": {
|
||||
"abstraction_fitness": 72.0
|
||||
},
|
||||
"dimension_notes": {
|
||||
"abstraction_fitness": {
|
||||
"evidence": [
|
||||
"Four external scrapers (Astro, Docker, Cloudflare, Nuxt) each reimplement the same transport/change-detection skeleton (`fetchPage`, `DetectChanges`, `generateHash`, per-page `Document` assembly) with only parser/model differences.",
|
||||
"`cmd/serve.go` RPC path for `devour_scrape` mutates CLI globals (`scrapeFormat`, `scrapeOutput`, `scrapeAllowEmpty`) to call `scrapeOne` from `cmd/scrape.go`, showing a leaky abstraction where server flow depends on CLI stateful wiring.",
|
||||
"`vector.Store` advertises interchangeable backends, but `NewStore` can return `ChromemStore` whose methods are all unimplemented runtime errors, so the abstraction surface overstates usable implementations."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high",
|
||||
"sub_axes": {
|
||||
"abstraction_leverage": 68.0,
|
||||
"indirection_cost": 73.0,
|
||||
"interface_honesty": 70.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "duplicated_external_scraper_skeleton",
|
||||
"summary": "External docs scrapers duplicate the same orchestration instead of sharing one adapter base",
|
||||
"related_files": [
|
||||
"internal/scraper/external/astrodocs.go",
|
||||
"internal/scraper/external/cloudflaredocs.go",
|
||||
"internal/scraper/external/dockerdocs.go",
|
||||
"internal/scraper/external/nuxtdocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"Each scraper defines near-identical `fetchPage`, `DetectChanges`, and `generateHash` logic.",
|
||||
"Each `Scrape` method repeats the same flow: validate URL -> fetch HTML -> parser call -> append main doc + sub-doc loop(s).",
|
||||
"Differences are mostly parser/model-specific mapping, but transport/error/hash logic is copy-pasted."
|
||||
],
|
||||
"suggestion": "Introduce a shared docs-scraper base (or helper pipeline) for HTTP fetch + hashing + standard error handling, and keep only parser-specific mapping in per-provider adapters.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "scrape_api_leaks_cli_state",
|
||||
"summary": "Server scrape RPC depends on mutable CLI globals to reuse scrape pipeline",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/scrape.go",
|
||||
"cmd/get.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`handleServeMethod` temporarily rewrites `scrapeFormat`, `scrapeOutput`, and `scrapeAllowEmpty` before calling `scrapeOne`, then restores them.",
|
||||
"`scrapeOne` is not a pure service API; it is coupled to CLI-level shared state and output behavior.",
|
||||
"`cmd/get.go` also routes through `runScrape`, reinforcing that scraping orchestration is command-centric rather than a reusable application service."
|
||||
],
|
||||
"suggestion": "Extract a stateless scrape service function (explicit request struct + options) used by both CLI commands and RPC handlers; keep CLI flags as translation-only at command boundary.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "vector_store_interface_overpromises",
|
||||
"summary": "Vector store abstraction exposes backends that are selectable but not actually implemented",
|
||||
"related_files": [
|
||||
"internal/vector/store.go",
|
||||
"internal/indexer/indexer.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`NewStore` can return `ChromemStore` when config type is `chromem`.",
|
||||
"All `ChromemStore` interface methods currently return `not implemented` errors.",
|
||||
"`Indexer` depends only on `vector.Store`, so backend failure appears at runtime after abstraction selection instead of at wiring/validation time."
|
||||
],
|
||||
"suggestion": "Make backend capabilities explicit: either remove/guard `chromem` selection until complete, or return an initialization error type from store construction and enforce backend readiness before indexing starts.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"batch": "Governance & Contracts",
|
||||
"batch_index": 3,
|
||||
"assessments": {
|
||||
"cross_module_architecture": 81.0,
|
||||
"test_strategy": 69.0
|
||||
},
|
||||
"dimension_notes": {
|
||||
"cross_module_architecture": {
|
||||
"evidence": [
|
||||
"README.md defines the quality model publicly as 5 mechanical + 7 subjective dimensions, implying a stable external contract for score interpretation.",
|
||||
"internal/quality/enhanced_types.go defines additional dimensions (e.g., DimensionElegance, DimensionContracts) that are not reflected in README governance docs.",
|
||||
"internal/quality/types.go exposes status/state enums (including StatusIgnored) that are absent from README user-facing resolution policy examples, creating docs-vs-runtime boundary drift."
|
||||
],
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "architectural_change",
|
||||
"confidence": "medium"
|
||||
},
|
||||
"test_strategy": {
|
||||
"evidence": [
|
||||
"internal/quality/scoring_test.go is heavily unit-focused and validates scorer internals, but does not validate public contract stability between quality types and README-documented behavior.",
|
||||
"README.md publishes CLI and JSON-RPC command contracts, but assigned tests do not exercise those published interfaces as compatibility gates.",
|
||||
"pkg/rustdocs/parser_test.go and internal/quality/scoring_test.go include brittle assertions (fixed positional result indexing and strict output text matching) that couple tests to implementation/presentation details."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "cross_module_architecture",
|
||||
"identifier": "docs_runtime_quality_contract_drift",
|
||||
"summary": "Quality dimensions/statuses drift between public docs and runtime model contracts.",
|
||||
"related_files": [
|
||||
"README.md",
|
||||
"internal/quality/enhanced_types.go",
|
||||
"internal/quality/types.go"
|
||||
],
|
||||
"evidence": [
|
||||
"README.md frames score interpretation around a specific dimension set and user workflow.",
|
||||
"internal/quality/enhanced_types.go includes extra dimension constants not represented in README contract text.",
|
||||
"internal/quality/types.go includes StatusIgnored while README resolution examples only expose fixed/wontfix/false_positive paths."
|
||||
],
|
||||
"suggestion": "Define a single versioned public quality contract (dimensions + statuses) as source-of-truth, generate README contract tables from it, and add a CI check that fails when exported enums and published docs diverge.",
|
||||
"confidence": "medium",
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "test_strategy",
|
||||
"identifier": "missing_public_contract_compat_tests",
|
||||
"summary": "Published CLI/RPC governance contracts are not protected by compatibility tests.",
|
||||
"related_files": [
|
||||
"README.md",
|
||||
"internal/quality/scoring_test.go",
|
||||
"internal/quality/types.go"
|
||||
],
|
||||
"evidence": [
|
||||
"README.md documents stable command and RPC method surfaces for users.",
|
||||
"internal/quality/scoring_test.go covers scoring behavior but not end-to-end contract assertions tied to documented surfaces.",
|
||||
"No assigned test verifies that externally documented score/status semantics remain compatible with exported model types."
|
||||
],
|
||||
"suggestion": "Add contract tests that parse/validate documented command and RPC surface claims against runtime registration/types, and add schema-level golden tests for serialized quality/status payloads.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "test_strategy",
|
||||
"identifier": "brittle_assertions_on_order_and_formatting",
|
||||
"summary": "Tests are fragile due to strict ordering and presentation-string coupling.",
|
||||
"related_files": [
|
||||
"internal/quality/scoring_test.go",
|
||||
"pkg/rustdocs/parser_test.go"
|
||||
],
|
||||
"evidence": [
|
||||
"pkg/rustdocs/parser_test.go asserts semantic expectations through fixed indexes (results[0], results[1], results[2]) rather than identity-based matching.",
|
||||
"internal/quality/scoring_test.go asserts many exact output substrings in FormatScorecard, coupling tests to formatting text that can change without behavioral regressions."
|
||||
],
|
||||
"suggestion": "Refactor tests to assert semantic invariants (presence by key/kind, normalized structured fields) and reserve strict golden-output checks for explicitly versioned presentation contracts.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"batch": "Design Coherence \u2014 Mechanical Concern Signals",
|
||||
"batch_index": 4,
|
||||
"assessments": {
|
||||
"design_coherence": 74.0
|
||||
},
|
||||
"dimension_notes": {
|
||||
"design_coherence": {
|
||||
"evidence": [
|
||||
"Command passthrough wrappers add non-functional indirection in language command modules: `languages/dart/commands.py` defines `_cmd_*_impl` plus thin `cmd_*` forwarders for each command (`cmd_large`, `cmd_complexity`, `cmd_deps`, `cmd_cycles`, `cmd_orphaned`, `cmd_dupes`).",
|
||||
"C# deps module mixes parsing, graph construction, CLI arg resolution, and terminal rendering in one file (`languages/csharp/detectors/deps.py` contains core graph builders and also `cmd_deps`/`cmd_cycles` UI handlers).",
|
||||
"Status rendering duplicates score-bar construction logic in two loops in `app/commands/status_parts/render.py` (same threshold/color/filled computation blocks around lines ~191-199 and ~223-231), increasing drift risk."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "passthrough_command_wrappers_add_low_leverage_layers",
|
||||
"summary": "Language command modules include thin forwarding wrappers with no behavioral value.",
|
||||
"related_files": [
|
||||
"desloppify/desloppify/desloppify/languages/dart/commands.py",
|
||||
"desloppify/desloppify/desloppify/languages/csharp/commands.py",
|
||||
"desloppify/desloppify/desloppify/languages/framework/commands_base.py"
|
||||
],
|
||||
"evidence": [
|
||||
"`languages/dart/commands.py` creates `_cmd_*_impl` callables and then defines six `cmd_*` functions that only call the corresponding impl.",
|
||||
"`languages/csharp/commands.py` also keeps thin wrappers (`cmd_large`, `cmd_complexity`, `cmd_deps`, `cmd_cycles`) that forward directly to other callables.",
|
||||
"The framework already provides factory-returned callables; wrapper layers increase symbol count and call depth without adding policy."
|
||||
],
|
||||
"suggestion": "Assign factory outputs directly to exported command names (or build the registry directly from generated callables) and keep wrappers only where they add language-specific behavior, validation, or formatting.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "csharp_deps_module_blends_core_and_cli_responsibilities",
|
||||
"summary": "C# dependency detector file combines analysis engine logic with CLI presentation.",
|
||||
"related_files": [
|
||||
"desloppify/desloppify/desloppify/languages/csharp/detectors/deps.py",
|
||||
"desloppify/desloppify/desloppify/languages/csharp/commands.py",
|
||||
"desloppify/desloppify/desloppify/languages/_shared/scaffold_detect_commands.py"
|
||||
],
|
||||
"evidence": [
|
||||
"`languages/csharp/detectors/deps.py` includes internal graph/parsing functions (`_parse_project_assets_references`, `_build_dep_graph_roslyn`, `build_dep_graph`) and command handlers (`cmd_deps`, `cmd_cycles`) in the same module.",
|
||||
"`languages/csharp/commands.py` forwards to `cmd_deps_direct`/`cmd_cycles_deps`, meaning command routing depends on detector-module UI functions instead of a clean detector API.",
|
||||
"Other language paths use shared command scaffolding (`languages/_shared/scaffold_detect_commands.py`) that separates command shell concerns from graph/detection logic."
|
||||
],
|
||||
"suggestion": "Split C# deps into `detectors/deps_core.py` (graph/parsing only) and command-facing adapters in `commands.py` (or scaffold factories), so detectors expose data and command modules own JSON/table rendering.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "status_bar_render_logic_duplicated_in_two_paths",
|
||||
"summary": "Status renderer repeats identical score-bar construction for mechanical and subjective rows.",
|
||||
"related_files": [
|
||||
"desloppify/desloppify/desloppify/app/commands/status_parts/render.py",
|
||||
"desloppify/desloppify/desloppify/app/output/scorecard_parts/projection.py"
|
||||
],
|
||||
"evidence": [
|
||||
"`show_dimension_table` in `status_parts/render.py` computes `filled`, score thresholds, and colored bar in one loop for mechanical dimensions and repeats the same logic in a second loop for subjective entries.",
|
||||
"Duplicated threshold constants (`>=98`, `>=93`) and color composition appear in both blocks, creating a two-site maintenance point for one rendering policy."
|
||||
],
|
||||
"suggestion": "Extract a shared `render_score_bar(score_val, bar_len)` helper (or move the row formatting policy into scorecard projection/output helpers) and reuse it for both loops to keep display semantics consistent.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "single_edit"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"batch": "Cross-cutting Sweep",
|
||||
"batch_index": 5,
|
||||
"assessments": {
|
||||
"error_consistency": 68.0
|
||||
},
|
||||
"dimension_notes": {
|
||||
"error_consistency": {
|
||||
"evidence": [
|
||||
"RPC paths mix strict and lax decode behavior: `cmd/serve.go` returns decode errors for `devour_scrape`/`devour_ask` but ignores decode errors for `devour_query` and `devour_sync` (`_ = json.Unmarshal(...)`).",
|
||||
"`cmd/serve.go` `devour_status` ignores errors from `LoadSourceState` and `EnsureIndexed` then dereferences `idxStats.Documents`, which can panic on nil when indexing fails.",
|
||||
"`internal/server/server.go` exposes raw internal errors to clients (`Message: err.Error()`), while parse/invalid-request errors are normalized strings; HTTP transport always emits 400 for any RPC error, collapsing error classes.",
|
||||
"`internal/ai/openai.go` does not check HTTP status before JSON decode, unlike scraper fetchers in `internal/scraper/external/*.go` and `internal/scraper/openapi.go` that explicitly gate on status codes.",
|
||||
"`internal/search/engine.go` and `internal/scraper/openapi.go` mix wrapped and passthrough errors in adjacent paths, producing uneven context for operators."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "rpc_decode_and_response_contract_drift",
|
||||
"summary": "RPC methods use inconsistent decode and error-response contracts",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"internal/server/server.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`cmd/serve.go` ignores JSON decode errors in `devour_query`/`devour_sync` but returns decode errors in `devour_scrape`/`devour_ask`.",
|
||||
"`internal/server/server.go` returns raw `err.Error()` in RPC payloads and maps all RPC errors to HTTP 400 in `writeRPC`."
|
||||
],
|
||||
"suggestion": "Define one RPC error policy: always validate/decode params the same way, map known classes to stable RPC codes/messages, and map transport HTTP statuses by error class (client input vs internal failure).",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "serve_status_swallows_errors_then_dereferences_nil",
|
||||
"summary": "Status handler ignores errors and can panic from nil stats",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"internal/search/engine.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`cmd/serve.go` uses `state, _ := projectstate.LoadSourceState(...)` and `idxStats, _ := engine.EnsureIndexed(ctx)` in `devour_status`.",
|
||||
"The same block unconditionally reads `idxStats.Documents` and `idxStats.LastIndexedAt`, which is unsafe if `EnsureIndexed` returned an error."
|
||||
],
|
||||
"suggestion": "Handle both errors explicitly in `devour_status`; return structured partial-status with an error field or fail the method uniformly, but do not ignore and dereference.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "single_edit"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "openai_http_error_path_not_normalized",
|
||||
"summary": "OpenAI client lacks explicit HTTP status error handling",
|
||||
"related_files": [
|
||||
"internal/ai/openai.go",
|
||||
"internal/scraper/openapi.go",
|
||||
"internal/scraper/external/astrodocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`internal/ai/openai.go` decodes response bodies directly and only checks `embeddingResp.Error`/`chatResp.Error`; non-2xx responses without expected JSON become generic decode errors.",
|
||||
"`internal/scraper/openapi.go` and external scrapers explicitly validate HTTP status before body parsing and return explicit HTTP status errors."
|
||||
],
|
||||
"suggestion": "Add explicit non-2xx handling in both OpenAI request paths: include status code, bounded response body excerpt, and endpoint context before JSON decode.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "mixed_wrapping_vs_passthrough_in_core_flows",
|
||||
"summary": "Adjacent paths alternate between wrapped and raw error returns",
|
||||
"related_files": [
|
||||
"internal/search/engine.go",
|
||||
"internal/scraper/openapi.go",
|
||||
"internal/config/config.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`internal/search/engine.go` frequently returns raw errors (`return nil, err`) from filesystem/index operations.",
|
||||
"`internal/scraper/openapi.go` similarly passes through request/file errors raw in `readSpec`, while other branches wrap with operation context.",
|
||||
"`internal/config/config.go` demonstrates contextual wrapping style (`read config`, `parse config`), creating drift against less-informative paths."
|
||||
],
|
||||
"suggestion": "Adopt a package-level rule: wrap external boundary failures with operation context (read/write/parse/network) and preserve `%w`; apply consistently across search/openapi paths.",
|
||||
"confidence": "medium",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "scanner_pipeline_fail_open_is_inconsistent",
|
||||
"summary": "Quality scan path mixes fail-open and fail-fast behaviors",
|
||||
"related_files": [
|
||||
"internal/quality/scanner.go",
|
||||
"internal/quality/plugins/go/analyzers/test_coverage.go",
|
||||
"internal/quality/plugins/go/analyzers/detectors.go"
|
||||
],
|
||||
"evidence": [
|
||||
"`internal/quality/scanner.go` logs detector failures and continues, silently reducing coverage of reported findings.",
|
||||
"`test_coverage.go` returns `(nil, nil)` for missing `go` tool or missing generated coverage file, while other detector failures return explicit errors.",
|
||||
"`detectors.go` has parse/count paths that silently `continue` on per-file errors, further mixing behavior."
|
||||
],
|
||||
"suggestion": "Standardize detector error semantics with typed outcomes (hard error, soft-skip with reason, per-file skip count) and surface these in scan results so degraded scans are explicit.",
|
||||
"confidence": "medium",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
{
|
||||
"batch": "Full Codebase Sweep",
|
||||
"batch_index": 6,
|
||||
"assessments": {
|
||||
"cross_module_architecture": 72.0,
|
||||
"error_consistency": 70.0,
|
||||
"abstraction_fitness": 68.0,
|
||||
"test_strategy": 64.0,
|
||||
"design_coherence": 69.0
|
||||
},
|
||||
"dimension_notes": {
|
||||
"cross_module_architecture": {
|
||||
"evidence": [
|
||||
"cmd/serve.go calls command handlers directly (runSync, scrapeOne) and mutates command-level globals (scrapeFormat/scrapeOutput/scrapeAllowEmpty and syncForce/syncRebuild/syncSource) before invoking them, coupling RPC transport to CLI flag state.",
|
||||
"Source-type detection logic exists in both internal/scraper/scraper.go:92 (DetectSourceType) and cmd/scrape.go:314 (detectSourceType), creating boundary drift for core classification behavior."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change",
|
||||
"confidence": "high"
|
||||
},
|
||||
"error_consistency": {
|
||||
"evidence": [
|
||||
"cmd/serve.go suppresses parse and subsystem errors via `_ = json.Unmarshal(...)` and `state, _ := projectstate.LoadSourceState(...)` / `idxStats, _ := engine.EnsureIndexed(...)`, while sibling paths return wrapped errors.",
|
||||
"Startup failure behavior differs across modules: cmd/root.go exits process with os.Exit(1), while internal/quality/plugins/go/plugin.go init() panics on registration failure."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
},
|
||||
"abstraction_fitness": {
|
||||
"evidence": [
|
||||
"Most external scraper implementations repeat near-identical transport/change-detection scaffolding (`fetchPage`, `DetectChanges`, `generateHash`) across files such as internal/scraper/external/reactdocs.go, tsdocs.go, godocs.go, rustdocs.go, and cloudflaredocs.go.",
|
||||
"This repeated wrapper structure adds maintenance indirection without policy variance (same HTTP GET + user-agent + status check + body read flow)."
|
||||
],
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change",
|
||||
"confidence": "high",
|
||||
"sub_axes": {
|
||||
"abstraction_leverage": 61.0,
|
||||
"indirection_cost": 43.0,
|
||||
"interface_honesty": 74.0
|
||||
}
|
||||
},
|
||||
"test_strategy": {
|
||||
"evidence": [
|
||||
"High-impact command flows lack direct tests: cmd/serve.go, cmd/sync.go, cmd/query.go, cmd/push.go, cmd/verify.go have no file-level tests while they orchestrate indexing/scraping/status behavior.",
|
||||
"Most external scrapers are untested at integration unit level (e.g., internal/scraper/external/{godocs,rustdocs,reactdocs,cloudflaredocs,nuxtdocs,...}.go) even though they include custom parsing-to-document mapping and network error handling."
|
||||
],
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
},
|
||||
"design_coherence": {
|
||||
"evidence": [
|
||||
"cmd/serve.go:71-210 centralizes multiple unrelated workflows (query/status/scrape/ask/sync) in one switch, with request parsing, domain orchestration, and response formatting mixed in a single function.",
|
||||
"The same function also performs cross-command mutable state choreography (temporarily overriding scrape/sync globals), combining transport logic with command execution mechanics."
|
||||
],
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor",
|
||||
"confidence": "high"
|
||||
}
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"dimension": "cross_module_architecture",
|
||||
"identifier": "rpc_cli_global_state_coupling",
|
||||
"summary": "RPC handlers mutate CLI global flags to execute workflows across command boundaries.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/scrape.go",
|
||||
"cmd/sync.go"
|
||||
],
|
||||
"evidence": [
|
||||
"cmd/serve.go sets scrapeFormat/scrapeOutput/scrapeAllowEmpty before calling scrapeOne and restores afterward.",
|
||||
"cmd/serve.go sets syncForce/syncRebuild/syncSource before calling runSync and restores afterward."
|
||||
],
|
||||
"suggestion": "Extract scrape/sync/query use-cases into stateless service functions (input structs + return structs), call them from both Cobra commands and RPC handlers, and remove shared mutable command globals from runtime execution paths.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "architectural_change"
|
||||
},
|
||||
{
|
||||
"dimension": "error_consistency",
|
||||
"identifier": "silent_error_drops_in_rpc_paths",
|
||||
"summary": "Several RPC paths ignore parse/index/state errors, producing inconsistent failure contracts.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"internal/search/engine.go",
|
||||
"internal/projectstate/state.go"
|
||||
],
|
||||
"evidence": [
|
||||
"cmd/serve.go ignores JSON unmarshal errors for devour_query/devour_sync (`_ = json.Unmarshal(...)`).",
|
||||
"cmd/serve.go ignores errors from LoadSourceState and EnsureIndexed, yet reads fields from returned values.",
|
||||
"Other command paths generally propagate wrapped errors with `%w`."
|
||||
],
|
||||
"suggestion": "Treat request decode, source-state load, and index-check failures uniformly: return explicit wrapped errors from each branch and avoid underscore-discarded errors in RPC handlers.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "single_edit"
|
||||
},
|
||||
{
|
||||
"dimension": "abstraction_fitness",
|
||||
"identifier": "external_scraper_transport_duplication",
|
||||
"summary": "External scrapers duplicate the same HTTP fetch/hash/change-detection boilerplate.",
|
||||
"related_files": [
|
||||
"internal/scraper/external/reactdocs.go",
|
||||
"internal/scraper/external/tsdocs.go",
|
||||
"internal/scraper/external/godocs.go",
|
||||
"internal/scraper/external/rustdocs.go",
|
||||
"internal/scraper/external/cloudflaredocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"Each scraper reimplements equivalent `fetchPage` with identical request/header/response-body flow.",
|
||||
"Each scraper reimplements nearly identical `DetectChanges` and `generateHash` logic."
|
||||
],
|
||||
"suggestion": "Introduce a shared base helper (e.g., `fetchPage`, `contentHash`, `detectChanges`) in internal/scraper/external/types.go or a dedicated internal transport module, then keep per-scraper files focused on parser-to-document mapping.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "subsystem",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "test_strategy",
|
||||
"identifier": "missing_tests_on_orchestration_and_adapters",
|
||||
"summary": "Critical orchestration commands and most external adapters have no direct tests.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/sync.go",
|
||||
"cmd/query.go",
|
||||
"internal/scraper/external/godocs.go",
|
||||
"internal/scraper/external/reactdocs.go"
|
||||
],
|
||||
"evidence": [
|
||||
"No *_test.go peers for cmd/serve.go, cmd/sync.go, cmd/query.go despite high-risk orchestration behavior.",
|
||||
"Only one external scraper has direct tests while many adapter implementations contain custom mapping and error-path logic."
|
||||
],
|
||||
"suggestion": "Add table-driven tests for RPC method branches and error propagation in cmd/serve.go, plus httptest-based adapter contract tests covering fetch failures, parser errors, and document mapping for each external scraper family.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "codebase",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
},
|
||||
{
|
||||
"dimension": "design_coherence",
|
||||
"identifier": "serve_handler_multi_responsibility_switch",
|
||||
"summary": "Single handler function mixes transport, parsing, orchestration, and mutable state management.",
|
||||
"related_files": [
|
||||
"cmd/serve.go",
|
||||
"cmd/scrape.go",
|
||||
"cmd/sync.go",
|
||||
"cmd/query.go"
|
||||
],
|
||||
"evidence": [
|
||||
"handleServeMethod contains method routing plus per-method request schemas, domain calls, and response shaping in one body.",
|
||||
"The function coordinates temporary mutation of command globals to reuse CLI code paths."
|
||||
],
|
||||
"suggestion": "Split each RPC method into dedicated handler functions (e.g., handleQueryRPC, handleScrapeRPC, handleSyncRPC) that depend on explicit service interfaces instead of command globals.",
|
||||
"confidence": "high",
|
||||
"impact_scope": "module",
|
||||
"fix_scope": "multi_file_refactor"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user