{"id":51330692,"url":"https://github.com/alexandrefimov/query-doctor","last_synced_at":"2026-07-01T23:00:38.058Z","repository":{"id":363676816,"uuid":"1256281340","full_name":"alexandrefimov/Query-Doctor","owner":"alexandrefimov","description":"Local-first Big Data query diagnostics for Apache Impala triage and bounded local Trino support, with raw-data-safe reports and read-only optimizer guidance.","archived":false,"fork":false,"pushed_at":"2026-07-01T21:01:41.000Z","size":12624,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-01T23:00:12.502Z","etag":null,"topics":["apache-impala","big-data","data-engineering","observability","performance","query-diagnostics","query-optimizer"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/query-doctor/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexandrefimov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-01T16:20:10.000Z","updated_at":"2026-07-01T20:55:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"0abbed5f-06b1-4183-b772-ce75c4418f0d","html_url":"https://github.com/alexandrefimov/Query-Doctor","commit_stats":null,"previous_names":["alexandrefimov/query-doctor"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/alexandrefimov/Query-Doctor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrefimov%2FQuery-Doctor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrefimov%2FQuery-Doctor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrefimov%2FQuery-Doctor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrefimov%2FQuery-Doctor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexandrefimov","download_url":"https://codeload.github.com/alexandrefimov/Query-Doctor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrefimov%2FQuery-Doctor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35025983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-impala","big-data","data-engineering","observability","performance","query-diagnostics","query-optimizer"],"created_at":"2026-07-01T23:00:16.399Z","updated_at":"2026-07-01T23:00:38.044Z","avatar_url":"https://github.com/alexandrefimov.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Query Doctor\n\nLast reviewed: 2026-07-01\n\nLanguage: English | [Russian](README.ru.md)\n\n[![Safety CI](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/ci.yml)\n[![Package CI](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/package.yml/badge.svg?branch=main)](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/package.yml)\n[![Docs CI](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/docs.yml/badge.svg?branch=main)](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/docs.yml)\n[![CodeQL](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/alexandrefimov/Query-Doctor/actions/workflows/codeql.yml)\n[![PyPI](https://img.shields.io/pypi/v/query-doctor.svg?cacheSeconds=300)](https://pypi.org/project/query-doctor/)\n\nQuery Doctor is a local-first Big Data query diagnostic tool for Apache Impala\nproduction triage and official bounded local Trino production lanes. It helps\noperators rank suspicious Recent\nqueries, collect bounded profile context, derive deterministic evidence, and\ngenerate validated reports without exposing raw SQL or raw profiles in trusted\nbrowser/report surfaces.\n\nCore rule:\n\n```text\nPython owns facts. LLM owns wording only.\n```\n\nRecent scan is the flagship workflow. Query ID diagnosis is secondary for one\nknown Impala query. Trino is officially supported for configured local\nretained-list Recent diagnosis, one explicit Query ID, raw-free Details,\ndeterministic Python Report, and optimizer guidance over materialized Trino web\ncases. Query Optimizer is separate, read-only, and does not execute or echo\nsubmitted SQL.\n\n## Quickstart\n\n```bash\npython -m pip install query-doctor\nquery-doctor-self-test\nquery-doctor-analyze \\\n  --profile-text ./exported-impala-profile.txt \\\n  --out cases/cm-corpus\nquery-doctor-web --corpus-dir cases/cm-corpus\n```\n\nRun `query-doctor-self-test` after installation to verify the installed console\nscripts, synthetic demo generation, one-profile analysis, local web rendering,\nImpala Web UI filename fallback, deterministic report generation, and corpus\nsmoke path. It uses synthetic local data only and does not contact Cloudera\nManager, impalad, Spark, Trino, Prometheus, Ollama, or external LLM services.\nPackage and release CI also run a README Quickstart smoke against a clean wheel\ninstall: `query-doctor-self-test`, `query-doctor-analyze --profile-text\n./exported-impala-profile.txt --out cases/cm-corpus`, and\n`query-doctor-web --corpus-dir cases/cm-corpus`.\n\nThe profile-analysis path needs one exported Impala text profile and no\nCloudera Manager, Kerberos, local config, browser upload, Prometheus, or LLM. A\ndirect Impala Web UI download named `profile_\u003cquery-id-high\u003e_\u003cquery-id-low\u003e` can\nbe used as-is. The web UI opens staged cases from `--corpus-dir` automatically.\nSee [Pick A First Path](#pick-a-first-path) for the demo and Cloudera Manager\noptions.\n\n## What It Is / Is Not\n\nQuery Doctor is:\n\n- a local-first Impala production triage workbench with official bounded local\n  Trino production lanes;\n- a deterministic evidence extractor;\n- a Recent-query ranking workflow for operators and administrators;\n- a safe report generator using validated facts;\n- a practical tool for deciding what to inspect, change, and verify next;\n- a Big Data SQL/lakehouse diagnostics wedge whose full production triage\n  engine is Apache Impala, with official bounded raw-free local Trino\n  production lanes and future-engine preview seams.\n\nQuery Doctor is not:\n\n- a generic AI chatbot over raw profiles;\n- a replacement for the Impala Web UI;\n- a tool that executes user SQL or optimizer draft SQL;\n- a tool that sends raw SQL/profile data to remote services by default;\n- a root-cause oracle;\n- a broad live multi-engine query-history collector.\n\n## What It Does\n\n- Turns one exported Apache Impala text profile into a local deterministic\n  diagnosis without Cloudera Manager, Kerberos, metadata, Prometheus, browser\n  upload, or an LLM provider.\n- Scans completed Recent queries as the flagship production workflow, with\n  Running queries and one explicit Known Query ID as focused secondary modes.\n- Works with Cloudera Manager when available, or with bounded direct Impala\n  daemon endpoints for non-Cloudera-Manager Impala clusters.\n- Supports bounded local Trino production lanes when explicitly configured:\n  retained-list Recent, one explicit Query ID, raw-free materialized Details,\n  deterministic Python Report, and optimizer guidance over the same\n  server-owned case facts.\n- Optionally adds bounded Prometheus runtime summaries for direct Impala\n  workflows and bounded read-only Impala metadata through `impala-shell`.\n- Ranks suspicious cases and action candidates from deterministic analyzer\n  facts, not LLM scoring.\n- Presents Details as an analyst decision page: why the query matters, where to\n  inspect, what to try, how to verify a comparable rerun, and what evidence is\n  missing.\n- Folds validated selected-case optimizer guidance into the same Recommended\n  change area when available. Report generation remains an explicit selected-case\n  action, and optimizer generation is offered only when deterministic rewrite\n  support marks the case safe to attempt.\n- Generates trusted reports only after deterministic normalization,\n  sanitization, and validation.\n- Provides a separate read-only Query Optimizer workflow for pasted SQL review,\n  plus explicit selected-case optimizer actions for server-owned analyzed\n  cases.\n- Keeps raw SQL, raw profiles, raw metadata, local paths, secrets, subprocess\n  output, model/runtime internals, and raw artifact filenames out of browser and\n  trusted report surfaces.\n\n## Support Boundary\n\n| Surface | Current status |\n| --- | --- |\n| Query engine | Apache Impala is the full production triage engine. Trino is officially supported for the bounded local raw-free production lanes named below. |\n| First-value intake | One local exported Impala text profile can be staged, redacted, analyzed, and opened from Known Query ID. |\n| Recent scan | Cloudera Manager is the full Recent discovery/profile/metrics/events provider for Impala workflows. |\n| Direct Impala | Bounded Recent scans, Running scans, and one Known Query ID through impalad daemon endpoints; no Cloudera Manager events and no SQL execution. |\n| Runtime metrics | Optional bounded Prometheus summaries for configured direct Impala workflows; no arbitrary PromQL from users. |\n| Metadata | Read-only allowlisted Impala metadata statements through `impala-shell`; no user SQL execution or unbounded metadata crawl. |\n| Reports and optimizer | Python-owned facts and validation. Known Query ID prepares the deterministic Python report in its explicit submit job; LLM narratives remain explicit selected-case actions, and optimizer actions are shown only for cases with safe-to-attempt rewrite support. |\n| Trusted SSO/auth proxy deployment | Query Doctor supports deployment behind a trusted SSO/auth proxy via `viewer_identity_header` for shared/non-local `owner_raw` access only after the raw-free D3 support-readiness gate passes. The proxy or ingress owns authentication, MFA, session lifecycle, token handling, and inbound-header stripping; Query Doctor only enforces the normalized viewer owner header against `query.user`. |\n| Trino local | Official bounded local production support. Local web Trino mode can read one bounded retained pruned coordinator query list for Recent diagnosis, then bounded pruned coordinator QueryInfo payloads for selected rows or one explicit Query ID, render deterministic compact diagnosis, materialize server-owned raw-free case artifacts, open a raw-free Details view, and generate deterministic Python Report plus optimizer guidance from those materialized case facts. `trino_support_mode=production` is the release-facing mode; `trino_support_mode=beta` keeps the legacy beta label for existing local setups. No Running scans, query-history crawling, metadata collection, LLM report output, Query Optimizer jobs, generated Trino SQL, SQL execution, or broader/shared Trino production triage support. |\n| Spark | Bounded compact support surfaces only. Spark is not production engine support, live Recent scans, Details/trusted report output, optimizer behavior, raw event-log handling, Spark job execution, or Query Doctor-generated SQL. |\n\nTrino compact/dev surfaces include offline or compact raw-free imports and checks:\nsanitized evidence packages, bounded local compact imports, explicit\nsource-contract checks, a contract-gated local metadata CLI summary builder\nand dev-only round-trip smoke gate that emit aggregate metadata coverage only,\nand bounded pruned QueryInfo paths\ndocumented in the engine docs. The official local production Trino product surfaces are local web retained-list\nRecent diagnosis, One Query ID diagnosis, the raw-free Details view,\ndeterministic Python Report, and optimizer guidance for server-owned materialized cases from those\nlanes. The diagnosis lanes require\n`trino_support_mode=beta` or `trino_support_mode=production`,\n`trino_coordinator_url`, and `trino_query_info_source_contract` in local config;\nRecent also requires `trino_query_list_source_contract`. The legacy\n`trino_beta_enabled=true` key remains beta-only for existing local setups and\nmust not be combined with `trino_support_mode=production`. Startup validation\nchecks local source contracts, safe coordinator URL shape, and optional auth\nreference (`trino_auth_header_file` or local Kerberos/SPNEGO settings) before\nthe lane is marked configured. Configured beta sources are marked as\n`Trino Beta Recent + One Query ID` or `Trino Beta One Query ID`; configured\nproduction-mode sources are marked without the beta label. The Diagnose Engine\ncontrol narrows the Source cluster selector to Impala-capable sources or\nTrino-ready sources before workflow selection, and stale or forged Trino submits\nstill fail closed before analysis or async job creation.\nCoordinator URL, auth header references, raw QueryInfo, raw SQL, and local paths\nstay out of the browser. Trino web case artifacts contain only the normalized\nboundary, compact diagnosis, metadata-not-collected summary, typed analysis, and\nsafe analyzer facts view; Details opens only after those artifacts exist.\nPython Report and optimizer guidance use the same raw-free facts and hide raw payloads, query IDs,\npaths, LLM report output, Query Optimizer jobs, and generated SQL. Broader/shared Trino\nlive collection and broader Trino production triage remain unsupported.\nSpark compact support surfaces are limited to bounded compact History Server\nintake, compact evidence-package build/validation, and compact diagnosis; there\nis no public Spark engine support.\n\nFuture Big Data SQL/lakehouse live collectors, broader providers, prepared\nevent/log sources, and Cluster Doctor workflows remain roadmap seams, not\ncurrent support. For the detailed Trino and Spark preview command catalog, use\n[docs/engines/README.md](docs/engines/README.md) and\n[docs/engine-support-gap-matrix.md](docs/engine-support-gap-matrix.md).\n\nDirect Impala Recent and Running scans currently see only the query history\nexposed by the configured coordinator daemon query-list endpoints. Upstream\nImpala keeps the coordinator query log at `--query_log_size=200` entries by\ndefault, further bounded by `--query_log_size_in_bytes`. Operators who need\ndeeper direct history can increase those Impala daemon settings on each\ncoordinator, while watching coordinator Web UI memory and `/queries` response\nlatency. Future deeper-history options are deliberately separate sources:\noperator-managed read-only profile-log directory ingestion, or bounded external\nhistory sources such as Loki or OpenSearch. They require explicit source\ncontracts, allowlists, byte/window bounds, and raw-free browser/report output;\nthe current product does not read coordinator filesystems, pod filesystems, or\nexternal log indexes for direct Recent scans.\n\nApache Impala also has upstream work around native AI query profile analysis.\nQuery Doctor aligns with that direction by staying focused on local-first\nproduction triage across many queries, deterministic evidence, safe enrichment,\nand validated raw-free reports. See\n[docs/upstream-impala-ai-analyzer.md](docs/upstream-impala-ai-analyzer.md).\n\n## Install\n\nInstall the current public package from PyPI:\n\n```bash\npython3 -m venv .venv\n. .venv/bin/activate\npython -m pip install --upgrade pip\npython -m pip install query-doctor\nquery-doctor-self-test\n```\n\n`query-doctor-self-test` is the installed-package confidence check. It uses\nsynthetic local data to exercise packaged console scripts, one-profile analysis,\nImpala Web UI filename fallback, local web rendering, deterministic reports,\nand corpus smoke without contacting Cloudera Manager, impalad, Spark, Trino,\nPrometheus, Ollama, or external LLM services.\n\nFor local development from a checkout:\n\n```bash\npython3 -m venv .venv\n. .venv/bin/activate\npython -m pip install --upgrade pip\npython -m pip install -e \".[dev]\"\npre-commit install\n```\n\nLocal JSON configuration is documented in [docs/configuration.md](docs/configuration.md).\nThe preferred workstation path is `~/.qdcreds/query-doctor-config.json`;\nsecrets stay in environment variables or local env files. Start from\n`query-doctor-config.minimal.example.json` for a Cloudera Manager Impala\nworkflow, then use `query-doctor-config.example.json` only when you need the\nadvanced direct-Impala, Prometheus, metadata, or LLM routing fields.\n\n## Pick A First Path\n\nUse the smallest path that matches the access you have.\n\n| Door | Use when | Starts from |\n| --- | --- | --- |\n| One exported profile | You can get one Impala Web UI text profile, but cannot grant live access yet. | `query-doctor-analyze --profile-text` or `query-doctor-web` with `manual_profile_dir` |\n| Synthetic demo | You want a read-only local click-through with no real data. | `query-doctor-web --public-demo` |\n| Minimal CM scan | You have read-only Cloudera Manager access for an Impala service. | `query-doctor-web` or `query-doctor-batch-recent` |\n\n### Door 1: Analyze One Exported Profile\n\nThe lowest-setup path is one exported Apache Impala text profile to one local\ndiagnosis. This does not contact Cloudera Manager or impalad, does not require\nKerberos, metadata collection, Prometheus, or an LLM provider, and does not\nupload the raw profile through the browser.\n\n```bash\nquery-doctor-analyze \\\n  --profile-text ./exported-impala-profile.txt \\\n  --out cases/cm-corpus\n```\n\nThe command stages a collector-shaped local case under `cases/cm-corpus`,\nredacts users, hosts, credentials, and common secret forms by default, writes\n`analysis_facts.md` plus `analysis.json`, and prints the output case directory.\nUse `--redact-identifiers` when the staged local artifacts may be shared. The\nmanual profile intake accepts exported text profiles only; JSON, Thrift, and\nprofile-v2 payloads remain outside this entry path. The CLI uses the Query ID\nheader from the exported profile, or the downloaded Impala Web UI filename when\nit has the strict `profile_\u003cquery-id-high\u003e_\u003cquery-id-low\u003e` shape. If neither is\nreadable, add `--query-id \u003cquery-id\u003e`; when multiple Query ID sources are\npresent, they must match before the local case is written.\n\nTo inspect staged cases in the local UI, start `query-doctor-web --corpus-dir\ncases/cm-corpus` from the same workspace. The Diagnose page opens an Exported\nProfiles results table from complete manual-profile cases in that corpus\nwithout requiring Cloudera Manager settings, credentials, or default local\nconfig. You can still choose `One Query ID` and enter the Query ID from a staged\nprofile to reopen that exact case. LLM narrative and optimizer actions remain\nexplicit buttons.\n\nYou can also configure a local profile inbox for the web UI. Put the exported\ntext profile in `manual_profile_dir` using the Query ID slug as the file name\n(for example, replace the Query ID separator with `_` and save\n`\u003cquery-id-slug\u003e.txt`), start `query-doctor-web`, choose `One Query ID`, and\nenter the original Query ID. The web path stages and analyzes the local file\nthrough the same text-only, bounded, redacted analyzer path; it does not upload\nthe raw profile through the browser. If the file contains an embedded Query ID\nfor a different query, staging fails closed before replacing any existing case.\nFor a self-contained one-profile workspace, set both paths in an ignored local\nconfig file and keep generated cases outside the source tree:\n\n```json\n{\n  \"manual_profile_dir\": \"/path/to/profile-inbox\",\n  \"corpus_dir\": \"/path/to/query-doctor-cases\",\n  \"no_llm\": true\n}\n```\n\nThen start `query-doctor-web --config ./query-doctor-one-profile.json`.\nRelative `corpus_dir` values in config resolve from the config file; the\n`--corpus-dir` CLI flag resolves relative paths from the current directory.\nWhen neither is set, the web UI stores generated Query ID cases under\n`./cases/cm-corpus` from the directory where you started `query-doctor-web`.\n\n### Troubleshooting One Exported Profile\n\n- `Profile text does not include a Query ID`: keep the original Impala Web UI\n  download name when it has the strict\n  `profile_\u003cquery-id-high\u003e_\u003cquery-id-low\u003e` shape, or pass\n  `--query-id \u003cquery-id\u003e`. Query Doctor also accepts a `Query ID:` header inside\n  the text export. If multiple Query ID sources are present, they must match.\n- `Parsed operators: 0`: the case is still staged and can open in the UI, but\n  that text export did not include a parseable `ExecSummary`/operator table.\n  Use the preserved Impala text profile export when available; JSON, Thrift,\n  and profile-v2 payloads are outside this manual profile path.\n- `query-doctor-web --corpus-dir cases/cm-corpus` asks for Cloudera Manager\n  settings: confirm that `query-doctor-analyze` wrote a complete case under the\n  same corpus directory you pass to web, and run web from the same workspace or\n  use an absolute `--corpus-dir`.\n\n### Door 2: Run The Synthetic Demo\n\nThe synthetic demo is the fastest way to see the product. It is deterministic,\nlocal-only, and contains no real SQL, profiles, metadata, hostnames, users, or\ncredentials.\n\n```bash\nquery-doctor-web --public-demo\n```\n\nThis one-command mode is documented in [docs/demo-mode.md](docs/demo-mode.md).\nIt generates the synthetic demo pack in a dedicated temp directory, forces\nPython-only mode, ignores default local config, and blocks all POST actions.\n\nIf you need to inspect or reuse the generated pack manually, use the lower-level\ncommands:\n\n```bash\nquery-doctor-demo-preflight\nDEMO_PACK=\"${TMPDIR:-/tmp}/query-doctor-demo-pack\"\nquery-doctor-demo --out \"$DEMO_PACK\" --overwrite\nQUERY_DOCTOR_ACTION_OUTCOMES_PATH=\"$DEMO_PACK/action_outcomes.jsonl\" \\\n  query-doctor-web --host 127.0.0.1 --port 8766 --batch-summary \"$DEMO_PACK/batch_summary.json\"\n```\n\nOpen the localhost URL printed by `query-doctor-web`. Start with\n`/?query_group=workloads#scan-context` to show the compact Scan context\nworkload follow-up links and local synthetic action outcomes before opening\nWorkload Details.\nWhen a Recent summary has repeated safe row-level workload fingerprints but no\nmaterialized workload payload, the UI derives bounded repeated workload details\nfrom the sanitized rows; those details have no baseline or regression claim\nuntil local history evidence is available.\n\nThe local web UI starts with a bounded search form and renders synthetic\nFinished Queries results for review:\n\n![Synthetic Query Doctor demo search form](docs/assets/demo_search.png)\n\n![Synthetic Query Doctor finished queries results](docs/assets/demo_finished_queries.png)\n\nThe synthetic demo pack contains eleven sanitized Impala cases covering\nworkload follow-up, repeated patterns, trusted optimizer recommendations,\nstats maintenance, storage/HDFS follow-up, frequent-short workloads, mixed\nsignals, unknown but useful limited evidence, and direct-Impala compatibility.\nIt also includes two read-only raw-free Trino Beta demo cases rendered from\nstatic compact diagnosis facts, without contacting a Trino coordinator or\nenabling Details, reports, optimizer guidance, generated SQL, or SQL execution.\nSee\n[docs/demo-cases.md](docs/demo-cases.md) for the full scenario list and talk\ntrack.\n\n### Door 3: Run A Minimal Cloudera Manager Scan\n\nUse this when you have read-only Cloudera Manager access for an Impala service.\nKeep secrets in the shell environment or a local env file, not in JSON config.\nCreate `~/.qdcreds/cm-ro.env` with `CM_USERNAME` plus `CM_PASSWORD` or\n`CM_TOKEN` before sourcing it.\n\n```bash\nmkdir -p ~/.qdcreds\ncp query-doctor-config.minimal.example.json ~/.qdcreds/query-doctor-config.json\n# Edit ~/.qdcreds/query-doctor-config.json with CM URL, cluster, service, and CA bundle if needed.\nset -a\nsource ~/.qdcreds/cm-ro.env\nset +a\nquery-doctor-web \\\n  --config ~/.qdcreds/query-doctor-config.json \\\n  --host 127.0.0.1 \\\n  --port 8765\n```\n\nFor a headless bounded Recent scan without automatic LLM reports:\n\n```bash\nquery-doctor-batch-recent \\\n  --config ~/.qdcreds/query-doctor-config.json \\\n  --recent-window-minutes 60 \\\n  --triage-profile-limit 10 \\\n  --top-reports 0\n```\n\nThe minimal path uses Cloudera Manager for Impala Recent discovery and profile\ncollection. Add metadata, CM time-series, direct Impala, Prometheus, or LLM\nsettings only after this basic scan path works. See\n[docs/configuration.md](docs/configuration.md) and\n[docs/credentials.md](docs/credentials.md).\n\n## Main Workflows\n\n- `query-doctor-self-test --help`: local installed-package confidence check\n  over synthetic data and core offline user paths.\n- `query-doctor-web --help`: local browser UI for Recent scan, Running now, one\n  Known Query ID, Details pages, explicit report actions, and explicit\n  details-page optimizer actions.\n- `query-doctor-batch-recent --help`: headless Recent scan workflow for bounded\n  local collection and ranking.\n- `query-doctor-analyze --help`: deterministic analyzer over collected local\n  case files, or over one staged local exported Impala text profile.\n- `query-doctor-report --help`: validated report generation from Python-owned\n  facts.\n- `query-doctor-optimize-query --help`: read-only pasted-SQL optimizer review.\n\nEvery packaged console script accepts `--help`. Root-level compatibility\nlaunchers have been removed; use `query-doctor-*` commands or\n`python -m query_doctor.cli.\u003ccommand_module\u003e` from an uninstalled checkout.\n\nQuery Doctor is supported as a single-user, local-first tool run by an operator\nwith their own local Cloudera Manager, Kerberos, Impala, Prometheus, and LLM\ncredentials. Use localhost or a tightly controlled local bind for the web UI.\nDo not deploy ordinary local mode as a shared service without a separate design\nfor authentication, authorization, tenant/job isolation, audit logging,\nTLS/reverse-proxy trust, and resource limits. Shared public demos should use\nthe read-only `query-doctor-web --public-demo` mode. Shared `owner_raw` source\naccess requires authenticated per-request viewer identity through an explicit\n`viewer_identity_header` supplied only by a trusted SSO/auth proxy or ingress\nthat strips inbound copies of the same header and sets exactly one normalized\nsimple owner value. Query Doctor supports that deployment pattern after the\nraw-free support-readiness gate in\n[docs/owner-raw-d3-deployment.md](docs/owner-raw-d3-deployment.md). A\ndev-only Keycloak/oauth2-proxy smoke is available in\n[docs/dev-sso-keycloak.md](docs/dev-sso-keycloak.md) to test the front-door\nviewer header contract locally; `scripts/dev_sso_keycloak_smoke.py` verifies\nthe running local compose path with raw-free output. The dev smoke is not\nproduction SSO support evidence and does not add native SSO to Query Doctor.\n\n## Safety Model\n\n- Python/analyzer-owned facts are the only trusted diagnostic evidence.\n- Raw LLM output is untrusted unless normalized, sanitized, and validated.\n- Trusted browser/report surfaces must not expose raw SQL, raw profiles, raw\n  metadata, local paths, secrets, subprocess output, model/runtime internals, or\n  raw artifact filenames. The isolated owner-only selected-case source surface is\n  the narrow raw-SQL browser exception.\n- External collection must be explicit, bounded, read-only, redacted, and safe\n  by default.\n- Local config `privacy_mode` defaults to `true`; disabling it can relax local\n  artifact identifier/host masking, but trusted browser/report surfaces still do\n  not show raw SQL, profiles, or metadata.\n- Local config `no_llm=true` keeps report and optimizer actions on deterministic\n  Python-owned output.\n- SQL browser exceptions are selected-case and owner-gated: Details can show a\n  validated optimizer SQL draft for an explicit safe-to-attempt optimizer action\n  when `source_visibility=owner_raw`, and the isolated owner-only source view can\n  show read-only original SQL for an authorized query owner. On localhost, raw\n  viewer subjects come from local collectable owner users; on shared binds they\n  must come from authenticated per-request viewer identity. The original source\n  view can be disabled globally with `owner_raw_source_enabled=false` or\n  `--disable-owner-raw-source`, and each attempt writes a reason-coded raw-free\n  server audit line. The default `safe` mode shows trusted\n  recommendations/no-rewrite guidance instead.\n- Query Optimizer accepts only a single safe read-only statement and never\n  executes pasted SQL.\n\nSee [docs/safety-contract.md](docs/safety-contract.md) for the full trust and\nredaction contract, including the narrow owner-only source exception. For\nshared/non-local owner-raw deployment, use\n[docs/owner-raw-d3-deployment.md](docs/owner-raw-d3-deployment.md). For a\nreviewer-oriented overview, see\n[docs/security-model.md](docs/security-model.md).\n\n## Documentation\n\nStart with [docs/README.md](docs/README.md). It separates current user docs,\noperations guides, architecture contracts, audit docs, and supporting\nreferences.\n\nHigh-value next reads:\n\n- [docs/demo-mode.md](docs/demo-mode.md): synthetic demo pack generation and\n  README screenshot refresh path.\n- [docs/DEMO.md](docs/DEMO.md): localhost UI demo runbook and talk track.\n- [docs/local-smoke.md](docs/local-smoke.md): local validation and smoke checks.\n- [docs/credentials.md](docs/credentials.md): local credentials layout.\n- [docs/roadmap.md](docs/roadmap.md): implemented scope and planned seams.\n- [docs/security-model.md](docs/security-model.md): public security, privacy,\n  and demo-sharing overview.\n- [docs/query-optimizer-contract.md](docs/query-optimizer-contract.md):\n  optimizer trust boundary.\n- [docs/release-checklist.md](docs/release-checklist.md): final tag,\n  package-index, and visibility-change checklist.\n\nThe canonical documentation language is English. The Russian layer is limited\nto [README.ru.md](README.ru.md) plus practical user/operator instructions under\n[docs/i18n/ru/](docs/i18n/ru/); internal, agent, research, release, and engine\ndeep-dive docs stay English-only.\n\n## Development Checks\n\nFor ordinary changes, run focused tests for the touched area and always run:\n\n```bash\ngit diff --check\n```\n\nUse [docs/agent-quickstart.md](docs/agent-quickstart.md) and\n[docs/test-matrix.md](docs/test-matrix.md) to choose focused validation. Before\nrelease cleanup or public-sharing work, broaden to:\n\n```bash\npre-commit run --all-files\nscripts/local_gate.sh\nquery-doctor-demo-preflight --public-release\n```\n\nStage only explicit files. Do not commit generated cases, reports, local\nconfigs, credentials, raw profiles, raw metadata, or temporary outputs.\n\n## Public Status\n\nThis repository is public. Public source releases start at `v0.4.2`; `v0.10.0`\ncontinues that public source release line. Older package-index releases remain\nvisible on\n[query-doctor on PyPI](https://pypi.org/project/query-doctor/) where needed for\ninstalled-artifact history. The public license is Apache-2.0.\n\nPyPI publishing uses GitHub OIDC Trusted Publishing. The repository-side\n`testpypi` and `pypi` environments require maintainer approval and do not use\nstored package-index API tokens.\n\n## Licensing\n\nQuery Doctor is licensed under the Apache License, Version 2.0\n(`Apache-2.0`). See [LICENSE](LICENSE).\n\nApache, Apache Impala, and Impala are trademarks of The Apache Software\nFoundation. Query Doctor is an independent project and is not endorsed by The\nApache Software Foundation or the Apache Impala project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandrefimov%2Fquery-doctor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandrefimov%2Fquery-doctor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandrefimov%2Fquery-doctor/lists"}