Sample report

quodeq, evaluated by quodeq

A read-only excerpt of a real evaluation of this project's own repository: seven dimensions, 3,875 files, commit a6830b9, 5 October 2026, Codex with gpt-6-luna, about 12 minutes. The findings are exactly as reported, picked major first. The app shows every one of them, with filters, the code map and the fix plans.

security

8.7good 35 major · 66 minor · 2458 done right

Open findings

Open security findings are not published on this page; they go to the maintainers first. This run reported 35 major and 66 minor.

Done right

compliantGeneric error handling in main entry pointtools/compile_standards.py:245

Accountability · S-ACC-11

The `main` function is wrapped in a try-except block that catches `ValueError` and `FileNotFoundError` and exits with a system message. This prevents stack traces from being exposed to the user in case of file or data errors, adhering to the principle of not revealing implementation details.

240 241 242if __name__ == "__main__":243    try:244        main()245    except (ValueError, FileNotFoundError) as _exc:246        raise SystemExit(str(_exc)) from _exc247 
compliantMasks credential-like text before logging or displaysrc/quodeq/shared/_security.py:20

Confidentiality · S-CON-2

sanitize_sensitive replaces API keys, tokens, secrets, passwords, and authorization values with *** so callers can emit diagnostic text without exposing those credential values.

20 21def sanitize_sensitive(text: str) -> str:22    """Mask potential secrets in *text* for safe logging/display."""23    return SENSITIVE_PATTERNS.sub(r"\1=***", text)24 

reliability

8.5good 30 major · 22 minor · 1238 done right

What it found

majorMalformed JSON-RPC input is silently discardedsrc/quodeq/assistant/mcp/_jsonrpc.py:30

Fault Tolerance · R-FT-14

The JSON-RPC server reads requests from its stdio client, but this handler discards each malformed JSON line and sends no parse-error response. The caller receives no response for that request and blocks or times out instead of learning that its request was invalid.

25        line = line.strip()26        if not line:27            continue28        try:29            obj = json.loads(line)30        except json.JSONDecodeError:31            continue32        if isinstance(obj, dict):33            return obj34    return None35 
majorJSON text arrays crash stream parsingsrc/quodeq/services/_violations_stream.py:33

Fault Tolerance · R-FT-4

`json.loads` accepts valid JSON arrays, but this code immediately calls `obj.get` without checking that the result is a dict. A provider stream containing a text line such as `[]` reaches this parser and raises AttributeError, aborting the live findings response with a server error instead of skipping the malformed finding row.

28        return None29    try:30        obj = json.loads(stripped_line)31    except json.JSONDecodeError:32        return None33    if not obj.get("p") or obj.get("t") not in FINDING_TYPES:34        return None35    key = f"{obj['p']}:{obj.get('file', '')}:{obj.get('line', '')}:{obj['t']}"36    if key in seen:37        return None38    seen.add(key)
majorValid non-object repository metadata crashes estimatessrc/quodeq/analysis/estimates.py:39

Fault Tolerance · R-FT-4

`json.loads` accepts valid JSON arrays and scalars, but this line calls `.get` without requiring a mapping. If `repository_info.json` contains a valid non-object value, `_resolve_repo_source` raises `AttributeError` before the endpoint's fallback handler and the estimates request returns an error instead of the documented zero payload.

34    info_path = project_dir / "repository_info.json"35    try:36        info = json.loads(info_path.read_text(encoding="utf-8"))37    except (OSError, json.JSONDecodeError):38        return None39    src = Path(info.get("path") or "")40    if not info.get("path") or not src.is_dir():41        return None42    return src, info.get("scopePath") or None43 44 
majorValid JSON scalar event aborts evidence extractionsrc/quodeq/analysis/stream/parser.py:81

Fault Tolerance · R-FT-4

The expression `etype = data.get("type", "unknown")` assumes `json.loads(line)` produced a mapping, but valid JSON lines such as `[]`, `null`, or `"text"` produce other types and are not rejected by the preceding `JSONDecodeError` handler. An unexpected scalar from the CLI stream raises `AttributeError` here and aborts parsing the entire evidence stream, failing that evaluation instead of skipping the invalid event.

76            try:77                data = json.loads(line)78            except json.JSONDecodeError:79                continue80 81            etype = data.get("type", "unknown")82            extractor = TEXT_EXTRACTORS.get(etype)83            if extractor:84                _process_texts(extractor(data), out, stats)85                files_read.update(_collect_file_reads(data))86 

Done right

compliantSync job states use a typed finite vocabularysrc/quodeq/core/types/sync_phase.py:12

Maturity · R-MAT-8

`SyncKind` and `SyncPhase` are string enums with explicit supported states, preventing arbitrary string values from silently entering sync status logic.

7from __future__ import annotations8 9from enum import StrEnum10 11 12class SyncKind(StrEnum):13    """Which sync job ran."""14 15    CONNECT = "connect"16    REFRESH = "refresh"17    PULL = "pull"
compliantDashboard view values are constrained by an enumsrc/quodeq/core/types/dashboard_view.py:13

Maturity · R-MAT-8

The StrEnum defines the two supported wire values, avoiding arbitrary strings in this type.

8from __future__ import annotations9 10from enum import StrEnum11 12 13class DashboardView(StrEnum):14    """The two dashboard payload shapes; the wire value of ``?view=``."""15 16    FULL = "full"17    OVERVIEW = "overview"18 

maintainability

9.3exemplary 6 major · 35 minor · 1374 done right

What it found

majorReturns the shared mutable skills cachesrc/quodeq/assistant/skills.py:128

Reusability · M-REU-2

cached_skills returns the dictionary stored in the module-level memo directly. Any caller that edits the returned mapping changes the result seen by every later caller for the same file stamp, leaving the cache inconsistent with the skill files.

123    directory = skills_dir or skills_directory(env)124    stamp = _skills_stamp(directory)125    with _SKILLS_MEMO_LOCK:126        hit = _SKILLS_MEMO.get(directory)127        if hit is not None and hit[0] == stamp:128            return hit[1]129    skills = load_skills(directory)130    with _SKILLS_MEMO_LOCK:131        _SKILLS_MEMO[directory] = (stamp, skills)132    return skills133 
majorDate persistence has no injectable index pathsrc/quodeq/data/fs/report_parser/run_dates.py:79

Reusability · M-REU-4

remember_run_dates also resolves the index database from process environment with no env argument, preventing a caller from injecting its configuration and isolating the operation.

74def remember_run_dates(project: str, dates: dict[str, tuple[str | None, str]]) -> None:75    """Store the dates ``parse_run_date`` resolved for *project*'s runs; best-effort."""76    if not dates:77        return78    try:79        db = open_index(Path(get_index_db_path()))80        try:81            write_run_dates(db, project, dates)82        finally:83            db.close()84    except (sqlite3.Error, OSError):
majorShell lookup ignores the injected environment PATHsrc/quodeq/terminal/_pty_windows.py:23

Reusability · M-REU-4

resolve_shell accepts env and reads COMSPEC from that mapping, but shutil.which(cand) searches the process PATH instead of src['PATH']. Callers supplying an isolated environment therefore still launch a shell selected from the host process, making shell resolution non-deterministic and preventing tests or embedders from controlling it.

18# keeps the read promptly stoppable (the reader loop re-checks its stop flag19# each cycle instead of parking).20_EMPTY_READ_SLEEP_S = 0.0521 22 23def resolve_shell(env: dict[str, str] | None = None) -> str:24    src = resolve_env(env)25    for cand in ("pwsh", "powershell"):26        found = shutil.which(cand)27        if found:28            return found29    return src.get("COMSPEC", "cmd.exe")30 31 32class WindowsPty:33    def __init__(self, argv: list[str] | None = None, env: dict[str, str] | None = None):
majorMapNoDimensionsState takes nine positional parameterssrc/quodeq/ui/src/features/map/components/MapPageStates.jsx:73

Modularity · M-MOD-4

The component accepts nine separately named inputs, exceeding the six parameter limit; each caller must keep a wide positional prop contract synchronized, and changes to state inputs require updating that large signature and forwarding list.

68// A failed fetch with nothing to show must render as an error, not the69// "no evaluations yet" empty state -- otherwise a 404/500/timeout tells70// the user their existing evaluations are gone. While a retry is in71// flight (error still set, isFetching true), show the loader instead so72// clicking Retry visibly does something.73export function MapNoDimensionsState({ loading, error, isFetching, selectedSource, selectedProject, projectName, isRefreshing, onNavigate, onRetry }) {74  if (loading) return <MapLoadingState />;75  if (error) return isFetching ? <MapLoadingState /> : <MapErrorState error={error} onRetry={onRetry} />;76  return (77    <MapNoEvaluationsState78      selectedSource={selectedSource} selectedProject={selectedProject} projectName={projectName}

Done right

compliantConnect job helpers stay below 60 linessrc/quodeq/services/shared_connect_job.py:53

Analyzability · M-ANA-2

The URL mapping, outcome mapping, worker, and start functions each stay below the 60-line function limit.

53"""Background connect job for the shared results repository.54 55Connecting clones the remote repo, which can take as long as the git56timeout, so PUT /api/shared/config claims a single process-wide connect slot,57runs ``connect_shared_repo`` on a daemon thread and answers 202. The UI polls58GET /api/shared/status, which reports this slot under ``connect``. Mirrors the59publish job in services/shared_publish.py.60"""61from __future__ import annotations62 63import time64from collections.abc import Mapping65from dataclasses import dataclass66from enum import StrEnum67from http import HTTPStatus68from typing import Callable69 70from quodeq.core.observability import NULL_LOG, LogSink71from quodeq.core.types.sync_phase import SyncKind, SyncPhase72from quodeq.services.github_access import forget_url73from quodeq.services.job_spawn import spawn_daemon74from quodeq.services.job_status import JobSlotStatus75from quodeq.services.shared_connect import ConnectOutcome, ConnectStatus, connect_shared_repo76from quodeq.services.shared_repo import RepoFormat, shared_evaluations_root, validate_remote_url77from quodeq.services.shared_listing import warm_shared_listing78from quodeq.services.sync_progress import SYNC_IDLE_FIELDS, WarmListing, progress_writer, read_projects79from quodeq.shared.fault_isolation import run_isolated80from quodeq.shared.git_errors import NOT_A_GIT_REPO_CODE, NOT_A_GIT_REPO_MESSAGE, NotAGitRepoError81 82# Wire ``code`` values for a failed connect. The UI maps each to a83# translated message, so the strings are API contract.84CODE_INVALID_URL = "INVALID_URL"85CODE_CLONE_FAILED = "CLONE_FAILED"86CODE_FOREIGN_REPO = "FOREIGN_REPO"87CODE_UNSUPPORTED_VERSION = "UNSUPPORTED_VERSION"88CODE_CONNECT_FAILED = "CONNECT_FAILED"89 90_PERCENT_DONE = 10091 92MESSAGE_CONNECT_UNEXPECTED = "An unexpected error occurred while connecting."
compliantTally functions stay below 60 linessrc/quodeq/data/fs/evidence_tally.py:71

Analyzability · M-ANA-2

The classification and tally functions are each under 60 lines, with the row logic split into focused helpers.

71"""Live evidence tally: unique finding counts from a dim's raw evidence jsonl.72 73Single source of truth for the subagent-pool heartbeat and the dashboard's74live scan-progress reader, so the terminal and UI never disagree mid-batch --75before the on-disk deduplication pass runs at end of pool, the file holds raw76appends from many parallel agents and contains overlapping findings.77"""78from __future__ import annotations79 80import json81import logging82from dataclasses import dataclass83from enum import StrEnum84from pathlib import Path85from typing import Callable86 87from quodeq.core.evidence.req_mapping import PrincipleResolver88from quodeq.core.types.finding_type import FINDING_TYPES, FindingType89from quodeq.shared.appended_lines import AppendedLines90from quodeq.shared.utils import open_text91 92_logger = logging.getLogger(__name__)93 94 95class RowClass(StrEnum):96    """_classify_finding_row's non-finding-type outcomes (see its docstring).97 98    A finding row classifies as one of these, or as FindingType.VIOLATION /99    FindingType.COMPLIANCE.100    """101 102    SKIP = "skip"103    DUPLICATE = "duplicate"104    QUARANTINED = "quarantined"105    SUPPRESSED = "suppressed"106 107 108# The row classes a tally counts, one counter each.109_COUNTED_KINDS = (110    FindingType.VIOLATION, FindingType.COMPLIANCE,

performance

8.6good 17 major · 20 minor · 221 done right

What it found

majorRuns llama.cpp inference inside the request handlersrc/quodeq/api/llm_bridge_routes.py:100

Capacity · P-CAP-2

`result = run_llamacpp_concurrency_test(model)` runs the slow concurrency probe synchronously in the route. The request worker remains occupied until inference finishes, reducing API request capacity.

95    whatever it was started with.96    """97    _, model, err = model_request(require_nonempty=False)98    if err is not None:99        return err100    result = run_llamacpp_concurrency_test(model)101    return jsonify(result)102 103 104def omlx_status() -> Response:105    """Report whether the omlx server at ``?base_url=`` is reachable.
majorAssistant turns create an unbounded thread per requestsrc/quodeq/api/assistant_turn_routes.py:68

Capacity · P-CAP-4

Each accepted `/messages` request starts a fresh daemon `threading.Thread`, while `AssistantTurnState` limits only SSE streams and does not cap concurrent turns. Concurrent requests from distinct sessions therefore allocate threads without a process-wide bound; sustained slow model calls exhaust the server's thread and memory capacity.

63        try:64            run_turn(turn, repository=repo, tool_ctx=tool_ctx, cancel=cancel)65        finally:66            state.release_turn(turn.session_id)67 68    threading.Thread(target=_worker, daemon=True).start()69 70 71def _sse_release_guard(state: AssistantTurnState):72    """Idempotent release-once wrapper around ``state.close_sse_stream()``.73 
majorAction log merge fully materializes each source filesrc/quodeq/data/actions_log.py:66

Resource Utilisation · P-RES-3

read_text() loads each complete actions log, and splitlines() plus the accumulated lines list retain additional copies while merging. As the append-only logs grow, a merge requires memory proportional to all source log contents.

61    seen: set[str] = set()62    lines: list[str] = []63    for source in srcs:64        if not source.exists():65            continue66        for raw in source.read_text(encoding="utf-8").splitlines():67            line = raw.strip()68            if line and line not in seen:69                seen.add(line)70                lines.append(line)71    if not lines:
majorProject scan runs in the request handlersrc/quodeq/api/routes_project_scan.py:130

Capacity · P-CAP-2

`scan_project(...)` completes before the HTTP response, keeping the Flask request worker occupied for the full filesystem scan; scanning a large local project ties up a worker and delays other requests.

125    if cached is not None:126        return cached127    project_path, err = _local_scan_root(project_dir)128    if err is not None:129        return err130    return _scan_response(scan_project(project_path, output_dir=project_dir))131 132 133def project_estimates(project: str) -> Response | tuple[Response, int]:134    """Return read-only pre-run per-dimension file estimates for a project.135 

Done right

compliantFilesystem module checks are memoized during the scantools/_private_imports_strict.py:34

Time Behaviour · P-TIM-6

The bounded gate run repeatedly resolves the same package/name pairs across roughly 1,900 files, and the cache prevents repeating those filesystem existence checks.

29from typing import Iterator30 31from _private_imports_rules import (32    FileCtx,33    Hit,34    dir_for_segments,35    is_private,36    make_hit,37    quodeq_segments,38    resolve_module_dir,39)
compliantMemoizes descendant counts across tooltip updatessrc/quodeq/ui/src/features/map/viz/components/galaxyFolderTooltip.test.jsx:25

Time Behaviour · P-TIM-6

The characterization test invokes updateTooltip three times for mouse movement and asserts countDescendants runs once, confirming redundant tree traversal is avoided on repeated updates for the same node.

20    const updateTooltip = createTooltipUpdater(refs);21 22    updateTooltip(10, 10);23    updateTooltip(11, 11);24    updateTooltip(12, 12);25 26    expect(spy).toHaveBeenCalledTimes(1);27  });28});29 

usability

9.0exemplary 6 major · 50 minor · 383 done right

What it found

majorRequirement reference accepts empty required valuessrc/quodeq/core/types/req_ref.py:15

User Error Protection · U-UEP-4

ReqRef requires both constructor arguments syntactically, but its documented model-building path allows empty strings for both fields. A reference with no label or URL is therefore represented as valid typed data and downstream users cannot rely on these required fields being usable.

10 11    Built by ``core.finding_mappings._coerce_req_refs`` from whatever the12    model emitted, so both fields can be empty strings.13    """14 15    label: str16    url: str17 
major`!path.startsWith(rootPath)`src/quodeq/ui/src/features/evaluation/hooks/useFolderNavigation.js:41

User Error Protection · U-UEP-1

The root boundary check accepts any sibling path sharing the same string prefix. With rootPath `/srv/project`, navigating to `/srv/project-old` passes and the folder browser displays files outside the selected root, so this validation fails to protect the user's chosen scope.

36  }37  const navigation = { setLoading, setNavError, updateNavState };38 39  const navigate = useCallback((path) => {40    // Prevent navigating above rootPath when rootPath is set41    if (rootPath && path && !path.startsWith(rootPath)) {42      setPathInput(rootPath);43      return;44    }45    // Fire-and-forget: navigateFolder already catches its own errors and46    // sets navError; callers (click handlers, the mount effect below) are
majorAccumulated shared finding detail is fetched from the local APIsrc/quodeq/ui/src/features/explorer/hooks/useHydratedCompliance.js:21

Appropriateness Recognisability · U-APR-1

When a shared-project reference has no run ID, this query always calls api.getFindingDetail, ignoring ref.source. The shared project ID is therefore sent to the local endpoint, so deferred compliance detail on accumulated shared views fails to load and is marked unavailable.

16      queryFn: () => fetchDetail(ref.project, { kind, dimension: ref.dimension, run: ref.run, ...scope }),17    };18  }19  return {20    queryKey: projectKeys.findingDetail(ref.project, ref.asOf, kind, ref.dimension, ref.generation, scope),21    queryFn: () => api.getFindingDetail(ref.project, { kind, dimension: ref.dimension, asOf: ref.asOf, ...scope }),22  };23}24 25/**26 * Items of one kind with the detail /scores or /scores/<run> deferred
majorClickable statistic's accessible name omits its valuesrc/quodeq/ui/src/components/terminal/StatStrip.jsx:69

Accessibility · U-ACC-1

The explicit `aria-label` overrides the button's descendant text and defaults to only `label`; screen-reader users activating or reviewing a clickable stat hear its category (for example, “SCORE”) without the displayed score or count.

64    // breaks hydration, and is an accessibility trap. The button's ::after is65    // stretched over the whole card in CSS so the full square is the click66    // target; severity badges remain independent siblings raised above it.67    return (68      <div className={className}>69        <button type="button" className="term-stat__hitbox" onClick={onClick} aria-label={ariaLabel || label}>70          {labelValue}71        </button>72        {hintEl}73      </div>74    );

Done right

compliantScoring scale's required data is enforced by the type constructorsrc/quodeq/core/types/scoring.py:31

User Error Protection · U-UEP-4

`ScaleInfo` declares `tier`, `multiplier`, and `files_read` without defaults, so callers cannot construct the dataclass while omitting those required values.

26 27    Set by ``core.scoring.engine.run_scoring``; the multiplier is what scales28    the per-severity deduction caps for a large codebase.29    """30 31    tier: str32    multiplier: int33    files_read: int34 35 36@dataclass(frozen=True, slots=True)
compliantLauncher focus behavior is coveredsrc/quodeq/ui/src/features/compare/components/useLauncherFocus.a11y.test.jsx:45

Accessibility · U-ACC-3

The test covers focus placement, arrow-key navigation, Tab and Shift+Tab closure, focus restoration, and recovery when items change.

40  trigger().focus();41  view.rerender(<Launcher open close={close} {...props} />);42  return view;43}44 45describe('useLauncherFocus', () => {46  it('moves focus to the first menu item when the menu opens', () => {47    openMenu();48    expect(item('one')).toHaveFocus();49  });50 

flexibility

9.4exemplary 3 major · 13 minor · 545 done right

What it found

majorDashboard port range is fixed in sourcesrc/quodeq/shared/dashboard_ports.py:20

Adaptability · F-ADP-1

DASHBOARD_BASE_PORT is hardcoded as 7863 while the dashboard also accepts QUODEQ_DASHBOARD_PORT at runtime. A deployment that changes the configured port leaves this generated port allowlist tied to the default, so the API CSP does not adapt to the active dashboard port.

15out of scope here and stays uncovered by connect-src beyond 'self' (not16widened to dashboard/_networking.py's MAX_PORT_SCAN_TRIES).17"""18from __future__ import annotations19 20DASHBOARD_BASE_PORT = 786321PORT_SCAN_SPAN = 522 23 24def alt_ports() -> tuple[int, ...]:25    """Return the dashboard alt ports the API's CSP allows explicitly."""
majorEvidence loading is coupled to the SQLite repositorysrc/quodeq/data/fs/report_parser/_evidence_sqlite.py:17

Replaceability · F-RPL-1

This parser imports the concrete SqliteFindingsRepository and constructs it directly in load_evidence_map_from_db, so replacing the findings backend requires editing this parser instead of supplying an implementation through a persistence boundary.

12from quodeq.core.types.finding_type import FindingType13from quodeq.data.fs.report_parser._date_utils import find_date_in_dir, normalize_date14from quodeq.data.fs.report_parser._run_info import safe_read_dir15from quodeq.data.fs.report_parser.finding_response import finding_to_response_dict16from quodeq.data.sqlite.connection import EVALUATION_DB_FILENAME17from quodeq.data.sqlite.findings_repository import SqliteFindingsRepository18from quodeq.shared.constants import EVIDENCE_DIRNAME, MANIFEST_FILENAME19from quodeq.shared.utils import read_json20 21_logger = logging.getLogger(__name__)22 
majorDeduplication store protocol cannot be injectedsrc/quodeq/analysis/mcp/router.py:112

Replaceability · F-RPL-1

Although `DeduplicationStore` is declared as an abstraction, the constructor assigns a concrete set and exposes no collaborator parameter. Replacing deduplication storage requires modifying FindingsRouter instead of substituting an implementation.

107        file_reader: FileReader | None = None,108        event_log: "EventLogWriter | None" = None,109        on_file_done: "Callable[[str, list[dict]], None] | None" = None,110    ):111        self._fh = output_fh112        self._enricher = FindingEnricher(context or CompiledContext(), file_reader, log=SHARED_LOG)113        self._seen: DeduplicationStore = set()114        self._event_log: EventLogWriter | None = event_log115        self._on_file_done: "Callable[[str, list[dict]], None] | None" = on_file_done116        self._findings_by_file: dict[str, list[dict]] = {}117        # (file, line, reported req) refused once: the model gets one retry,
minorJob state is confined to one processsrc/quodeq/services/_job_model.py:192

Scalability · F-SCL-4

The default job store keeps every job in a local dictionary. A worker restart loses job status, and other workers cannot read or update those jobs, so dispatch/status handling does not scale across workers.

187    ``create_job_store``.188    """189    # See https://github.com/anthropics/quodeq/issues/42 for persistent adapter plans.190 191    def __init__(self) -> None:192        self._jobs: dict[str, Job] = {}193        self._lock = threading.Lock()194 195    def get(self, job_id: str) -> Job | None:196        with self._lock:197            return self._jobs.get(job_id)

Done right

compliantConfigurable or replaceable boundarysrc/quodeq/ui/src/features/onboarding/components/steps/CloneTargetStep.jsx:11

Adaptability · F-ADP-1

The default clone destination is a user-home relative default, while readInitialDest first loads the user’s stored selection through a storage adapter; the location remains user-configurable.

11import { useState } from 'react';12import { TermHeader } from '../../../../components/terminal/index.js';13import FolderBrowser from '../../../evaluation/components/FolderBrowser.jsx';14import { t } from '../../../../strings/index.js';15import { readString } from '../../../../adapters/storage.js';16import { LAST_CLONE_ROOT_STORAGE_KEY } from '../../../../constants.js';17import AccessPanel from '../../../github-access/components/AccessPanel.jsx';18 19// Where working copies go unless the user picks another folder. The server20// expands the tilde and creates the folder on first use.21export const DEFAULT_CLONE_ROOT = '~/quodeq/repos';22 23function readInitialDest() {24  return readString(LAST_CLONE_ROOT_STORAGE_KEY) || DEFAULT_CLONE_ROOT;25}26 27function CloneTargetForm({ cloneDest, setCloneDest, submitting, error, detail, accessFailure, handleSubmit, onBack, onBrowse }) {28  return (29    <form onSubmit={handleSubmit} className="onboarding-clone-target__form">30      <label htmlFor="clone-dest-input" className="onboarding-clone-target__label">{t('onboarding.cloneDestLabel')}</label>31      <div className="onboarding-repo-row">32        <input33          id="clone-dest-input"34          type="text"35          className="onboarding-clone-target__input"36          value={cloneDest}37          onChange={(e) => setCloneDest(e.target.value)}38          disabled={submitting}39          autoFocus40        />41        <button42          type="button"43          className="term-btn--secondary onboarding-repo-row__browse"44          onClick={onBrowse}45          disabled={submitting}46        >47          {t('onboarding.chooseCloneFolder')}48        </button>49      </div>50      <p className="onboarding-clone-target__hint">
compliantDatabase paths are configurable at runtimesrc/quodeq/shared/_env_db.py:17

Adaptability · F-ADP-1

The SQLite index path comes from QUODEQ_INDEX_DB_PATH or an injected default, with a state-directory fallback; the score cache path follows equivalent environment-based resolution. This lets separate installs and environments select their own storage paths.

17"""Environment-based configuration accessors -- SQLite DB paths and kill switches."""18from __future__ import annotations19 20import os21from pathlib import Path22 23from quodeq.shared._env_sanitize import sanitized_env_path24from quodeq.shared.env_paths import get_quodeq_dir25from quodeq.shared.env_resolve import resolve_env26 27SQLITE_DISABLE_TRUTHY = {"1", "true", "yes", "on"}28 29_INDEX_DB_FILENAME = "index.db"30_SCORE_CACHE_FILENAME = "score_cache.db"31 32 33def get_index_db_path(default: str | None = None, env: dict[str, str] | None = None) -> str:34    """Return the absolute path to the SQLite run index DB.35 36    Resolution order: QUODEQ_INDEX_DB_PATH env var, then *default*, then37    ``<state dir>/index.db`` where the state dir is QUODEQ_DIR or ``~/.quodeq``38    (resolved on each call, so a second instance with its own QUODEQ_DIR never39    reads the live app's index). Always returns a str for downstream40    Path/sqlite3 use.41    """42    environ = resolve_env(env)43    if "QUODEQ_INDEX_DB_PATH" in environ:44        return sanitized_env_path(environ["QUODEQ_INDEX_DB_PATH"])45    return default or str(get_quodeq_dir(environ) / _INDEX_DB_FILENAME)46 47 48def get_score_cache_path(env: dict[str, str] | None = None) -> str:49    """Return the absolute path to the rescored-score cache DB.50 51    Resolution: QUODEQ_SCORE_CACHE_PATH env var, else next to the index DB52    (so the test suite's QUODEQ_INDEX_DB_PATH override auto-isolates it), else53    ``<state dir>/score_cache.db``. This cache is disposable -- deleting it is safe.54    """55    environ = resolve_env(env)56    if "QUODEQ_SCORE_CACHE_PATH" in environ:

clean architecture

9.1exemplary 42 major · 14 minor · 1467 done right

What it found

majorStandards query service enumerates the filesystem directlysrc/quodeq/services/_standards_queries.py:53

Separation of Concerns · CLEA-SEP-03

`evaluators_dir.is_dir()` and `evaluators_dir.glob("*.json")` make the service layer depend on directory layout and filesystem access. A change to the standards storage adapter requires changing this service as well.

53"""Query operations for listing and retrieving standards."""54from __future__ import annotations55 56import logging57from collections.abc import Callable58from pathlib import Path59 60from quodeq.core.types.standard import StandardDetail, StandardMeta61from quodeq.services._standards_io import (62    build_builtin_detail, build_builtin_meta, build_custom_meta, build_detail,63    count_principles_and_requirements, get_builtin_weight, is_builtin_id,64    load_cwe_entries,65)66from quodeq.shared.validation import validate_path_segment67 68logger = logging.getLogger(__name__)69 70 71def list_builtin(dimensions_file: Path, compiled_dir: Path,72                 read_json: Callable) -> list[StandardMeta]:73    """Return metadata for all built-in standards."""74    try:75        data = read_json(dimensions_file)76    except (OSError, ValueError) as exc:77        logger.warning("Cannot read dimensions file: %s", exc)78        return []79    out: list[StandardMeta] = []80    for dim in data.get("applies", []):81        try:82            p_count, r_count, description, version = _read_compiled_meta(dim["id"], compiled_dir, read_json)83            out.append(build_builtin_meta(dim, p_count, r_count, description, version))84        except (OSError, ValueError, KeyError) as exc:85            logger.warning("Skipping invalid dimension entry %r: %s", dim, exc)86    return out87 88 89def _read_compiled_meta(dimension_id: str, compiled_dir: Path,90                        read_json: Callable) -> tuple[int, int, str, str | None]:91    """Return (principle_count, requirement_count, description, version) for *dimension_id*."""92    path = compiled_dir / f"{dimension_id}.json"
majorScoring use case depends directly on filesystem adapterssrc/quodeq/services/score_run.py:24

Use Case Encapsulation · CLEA-USE-05

The use case imports concrete `data.fs` loaders and `services.wiring` filesystem operations and calls them throughout scoring. This couples cancellation scoring to the filesystem implementation, so changing persistence requires editing the use case.

24"""Use case: score completed evidence after cancellation.25 26Extracted from ``evaluation_mixin`` so the API layer has a public entry27point instead of importing a private helper.28"""29from __future__ import annotations30 31import json32import logging33import time34from collections.abc import Callable35from dataclasses import dataclass36from pathlib import Path37from typing import Any38 39from quodeq.config.evidence_env import cwe_url_template40from quodeq.config.services_env import cancel_escalation_window_s41from quodeq.core.evidence.parser import (42    EvidenceContext, EvidenceParseOptions, parse_jsonl_to_evidence)43from quodeq.core.run.dimensions import DimState44from quodeq.core.run.job_status import JobStatus45from quodeq.core.run.state import STATUS_FILENAME46from quodeq.core.scoring.params import ScoringParams47from quodeq.data.fs.standards_loader import load_compiled_refs, read_req_to_principle_map48from quodeq.core.scoring.engine import score_evidence49from quodeq.core.utils.io import resolve_child_dir50from quodeq.services.scored_jobs_registry import ScoringClaims51from quodeq.services.background import BackgroundRunner52from quodeq.services.grade_formula import load_params53from quodeq.shared.fault_isolation import run_isolated54from quodeq.shared.log_sink import log_malformed_jsonl_line, log_quarantined_findings55from quodeq.services.wiring import (56    dimension_queue_file,57    dimension_report_exists,58    ensure_dir,59    list_dimension_evidence,60    queue_file_exists,61    read_dimensions,62    read_queue_files_count,63    read_scan_total_files,
majorSubagent workflow constructs a concrete file queuesrc/quodeq/analysis/subagents/runner.py:32

Use Case Encapsulation · CLEA-USE-05

The dimension workflow imports and constructs `FileQueue` directly while preparing dispatch. Queue persistence is a concrete filesystem adapter dependency inside orchestration, so changing queue storage requires changing the subagent workflow.

32"""Subagent processing path -- runs a dimension via N parallel subagents.33 34The verify-pool is gone. V2's content-addressed cache35already invalidates on file/standards/prompts changes, triggering a36full fresh dispatch. The V1 "carry-forward + verify-when-rules-change"37optimization no longer earns its complexity.38"""39from __future__ import annotations40 41from dataclasses import dataclass42from pathlib import Path43from typing import Any, Callable44 45from quodeq.analysis.run_types import RunConfig, AnalysisContext46from quodeq.core.evidence.model import Evidence47from quodeq.core.observability import NULL_LOG, LogSink48 49# Re-exports from split modules -- keep the public API stable50from quodeq.analysis.subagents.source_files import list_source_files51from quodeq.analysis.subagents._prompts import build_subagent_prompt52from quodeq.analysis.subagents._pool_launcher import (  # noqa: F40153    LaunchPoolParams,54    compute_files_per_agent,55    default_subagent_model,56    launch_pool,57    collect_all_evidence,58)59from quodeq.analysis.subagents._evidence_collector import (60    CollectionContext,61    collect_evidence,62)63from quodeq.analysis.subagents.file_queue import FileQueue64from quodeq.analysis.subagents._consolidated import (65    process_consolidated_dimensions as _process_consolidated_impl,66)67 68 69@dataclass70class DimensionCallbacks:71    """Collaborators a dimension dispatch is handed: the single-agent
majorAnalysis compatibility module imports the storage adaptersrc/quodeq/analysis/cache/local.py:10

Dependency Rule · CLEA-DEP-01

The analysis namespace imports LocalFileBackend from quodeq.data.cache_store, making the inner analysis package depend on an outer storage implementation. Replacing or relocating the cache adapter therefore requires preserving a reverse dependency in the analysis layer.

5This module re-exports the public names so every pre-existing6``quodeq.analysis.cache.local`` import path keeps working.7"""8from __future__ import annotations9 10from quodeq.data.cache_store.local import LocalFileBackend, default_cache_root  # noqa: F40111 

Done right

compliantJudgment factory depends on core types onlysrc/quodeq/core/checks/_judgments.py:9

Dependency Rule · CLEA-DEP-01

This checker helper imports source location, judgment, finding type, confidence, and severity definitions from quodeq.core and constructs a core result without adapter or framework dependencies.

9"""One shape for every deterministic finding.10 11Checkers are added over time by different hands; without a shared constructor12they drift on severity, confidence and whether a clean result says anything at13all. Those are exactly the fields that decide how a finding scores.14"""15from __future__ import annotations16 17from quodeq.core.checks.model import SourceLocation18from quodeq.core.events.models import Judgment19from quodeq.core.types.finding_type import FindingType20from quodeq.core.constants import FULL_CONFIDENCE21from quodeq.core.types.severity import Severity22 23SEVERITY = Severity.MAJOR24 25 26def violation(*, req: str, dimension: str, at: SourceLocation,27              title: str, reason: str) -> Judgment:28    return Judgment(29        practice_id=req, req=req, verdict=FindingType.VIOLATION, dimension=dimension,30        file=at.file, line=at.line, title=title, reason=reason,31        severity=SEVERITY, confidence=FULL_CONFIDENCE,  # a static fact is not a guess32    )33 34 35def compliance(*, req: str, dimension: str, anchor: str,36               title: str, reason: str) -> Judgment:37    """A requirement the check covered and found clean.38 39    Emitting nothing would leave the requirement exactly as unmeasured as it40    was before the checker existed -- "no violations" and "never looked" must41    not read the same. One instance per requirement, not one per file:42    confidence is scored on instance count, and a single traversal has not43    earned more than one.44    """45    return Judgment(46        practice_id=req, req=req, verdict=FindingType.COMPLIANCE, dimension=dimension,47        file=anchor, line=1, title=title, reason=reason,48        severity=SEVERITY, confidence=FULL_CONFIDENCE,  # a static fact is not a guess
compliantVisibility rules operate on standard-library and core datasrc/quodeq/core/standards/visibility.py:20

Dependency Rule · CLEA-DEP-01

The visibility module uses iterable and path value types and pure normalization, validation, and partition functions; it has no UI, persistence implementation, or framework package dependency.

20"""Per-project selection of which standards are shown.21 22Hiding a standard is project configuration, not a per-browser view preference:23the dashboard and the assistant must both agree on which standards are in24play (there is no CLI consumer). The selection lives in the analyzed25repository at26``<project root>/.quodeq/standards-visibility.json``, alongside27``standards-overrides.json``, so the whole team shares it:28 29    {"version": 1, "visibleStandardIds": ["security", "reliability"]}30 31An absent file means the six ISO defaults, NOT "everything". Quodeq ships more32built-in standards than the default selection shows, so treating absence as33"no filtering" would leave a fresh install disagreeing with its own dashboard.34 35A malformed file never fails a read; it degrades to the defaults with a warning.\nRead/write of the file itself lives in ``data/fs/standards_prefs.py``.36"""37from __future__ import annotations38 39from collections.abc import Iterable40from pathlib import Path41 42VISIBILITY_RELPATH = Path(".quodeq") / "standards-visibility.json"43 44# Must stay in lockstep with DEFAULT_VISIBLE_STANDARDS in45# src/quodeq/ui/src/constants.js -- pinned by46# tests/core/test_visible_standards_defaults_match_ui.py.47DEFAULT_VISIBLE_STANDARDS: tuple[str, ...] = (48    "security", "reliability", "maintainability",49    "performance", "usability", "flexibility",50)51 52 53def normalize_ids(ids: Iterable[object]) -> tuple[str, ...]:54    """Lowercase, de-duplicate and drop non-strings, preserving first order."""55    out: list[str] = []56    seen: set[str] = set()57    for raw in ids:58        if not isinstance(raw, str):59            continue

Run it on your own repository: pipx install quodeq, or start with the quickstart.