name: querido description: Use querido (qdo) to explore database schemas, profile data, enrich tables with metadata, and generate SQL. Use when working with SQLite, DuckDB, Snowflake, or Parquet files, when asked to write SQL against a local or named database, when asked to profile or summarize a table, or when the user mentions qdo. globs: “*/.{py,sql,yaml,yml}” alwaysApply: false —

Using querido (qdo)

qdo is an agent-first data exploration CLI that turns one-off investigation into reusable team knowledge.

Pass -f json on scanning and query invocations you need to parse — the envelope is {command, data, next_steps, meta} with deterministic next_steps hints that chain investigations. Canonical placement is right after qdo (qdo -f json <cmd> ...). Artifact-producing and interactive commands keep their own output behavior. Shortcut: export QDO_FORMAT=json sets the default for a shell session.

Unless the user clearly asks for something else, use this path. It is the main story qdo is optimized for: discover data, understand it, capture what you learned, answer the question, then share the result.

qdo -f json catalog -c <connection>                                   # 1. discover candidate tables
qdo -f json context -c <connection> -t <table>                         # 2. understand one table deeply
qdo -f json values -c <connection> -t <table> -C <column> --write-metadata  # 3. capture observed enum-like values
qdo -f json metadata show -c <connection> -t <table>                   #    read full shared business knowledge when needed
qdo metadata init -c <connection> -t <table>                           #    or scaffold broader metadata if none exists
qdo metadata suggest -c <connection> -t <table> --apply                #    and enrich it from deterministic scans
qdo -f json query -c <connection> --sql "select ..."                   # 4. answer a concrete question
qdo -f json assert -c <connection> --sql "select ..." --expect ...     #    verify an invariant when useful
qdo report table -c <connection> -t <table> -o report.html             # 5. hand off a shareable artifact (file output)
qdo bundle export -c <connection> -t <table> -o bundle.zip             #    ...or a portable knowledge bundle
qdo bundle inspect bundle.zip                                          #    always inspect after export

Treat catalog -> context -> capture metadata -> query/assert -> report/bundle as the default path.

A bundle is a directory or ZIP archive containing metadata and optional column sets, never sessions or workflows. A .zip output suffix selects ZIP output. Always follow qdo bundle export with qdo bundle inspect <path> so the hand-off describes what the bundle contains. When a prior bundle exists, qdo bundle diff <previous> <new> can compare them.

Agent rules

For a new database, start here:

qdo catalog -c <connection>          # all tables and columns
qdo context -c <connection> -t <table>   # full context for one table (use this first)

context returns schema + null rates + distinct counts + sample values for categoricals + min/max for numerics in one call. If metadata files exist (.qdo/metadata/), descriptions and valid values are merged in automatically. It is the most efficient starting point for understanding a table.

Connection syntax

# Named connection (configured via qdo config add)
qdo catalog -c mydb

# File path — DuckDB, SQLite, or Parquet
qdo catalog -c /path/to/data.duckdb
qdo catalog -c ./warehouse.db
qdo catalog -c ./data.parquet

The -c flag accepts either a named connection or a direct file path.

Drill-down commands

Use these only when the promoted workflow leaves a specific unanswered question:

context vs profile vs quality. context is the default first call. profile is for deeper statistical detail on selected columns. quality is for anomaly-oriented checks and invariant violations.

values --write-metadata closes the compounding loop. It enumerates a column’s distinct values and writes them into the metadata YAML as valid_values. Next time qdo context/qdo quality runs, those values surface automatically. Captured values are observations (confidence 0.8), so quality flags violations only after a human approves them or confidence is 1.0. The write is intentionally limited to complete string sets with 1–19 distinct values; truncated, non-string, empty, or 20+-value results are not captured.

context — everything about a table in one call

context is the fastest way to understand a table. On DuckDB and Snowflake it uses a single SQL scan to compute stats and fetch sample values via approx_top_k. On SQLite it runs one profile scan plus sequential frequency queries. Stored metadata is loaded from disk concurrently.

qdo context -c <connection> -t <table>
qdo -f json context -c <connection> -t <table>          # machine-readable
qdo context -c <connection> -t <table> --sample-values 10   # more samples
qdo context -c <connection> -t <table> --no-sample      # exact counts, no sampling

envelope.data shape (trimmed):

{
  "table": "orders",
  "dialect": "duckdb",
  "row_count": 50000,
  "table_description": "Customer orders",
  "columns": [
    {
      "name": "status",
      "type": "VARCHAR",
      "nullable": true,
      "null_pct": 0.5,
      "distinct_count": 4,
      "sample_values": ["pending", "shipped", "delivered", "cancelled"],
      "description": "Fulfillment status",
      "valid_values": ["pending", "shipped", "delivered", "cancelled"]
    },
    {
      "name": "amount",
      "type": "DOUBLE",
      "null_pct": 1.2,
      "distinct_count": 12543,
      "min": 0.99,
      "max": 9999.0,
      "sample_values": null
    }
  ]
}

Use context as the primary tool call when you need to understand a table before writing SQL. It replaces separate calls to inspect, preview, and much of profile for most workflows.

JSON output for programmatic use

Canonical placement is right after qdo:

qdo -f json catalog -c mydb
qdo -f json context -c mydb -t orders
qdo -f json metadata show -c mydb -t orders

Shortcut if you want JSON to be the default for commands that support structured output:

export QDO_FORMAT=json   # prefer explicit -f json per call; this is a convenience

Errors go to stderr as structured JSON when -f json is set:

{"error": true, "code": "TABLE_NOT_FOUND", "message": "...", "try_next": [{"cmd": "qdo catalog ...", "why": "..."}]}

Documented or contract-tested error codes and try_next records receive compatibility treatment. Human-readable message wording does not.

Most scan/query commands and many management/reference commands support -f json; artifact-oriented commands such as report table still keep their file-writing behavior.

Metadata workflow

Metadata files live under .qdo/metadata/ and contain both machine-populated observations and human-written business context. Their purpose is to give agents candidate filter values, nullability, meaning, ownership, and caveats that schema or samples alone cannot provide; comparative impact remains an evaluation question.

Create and enrich metadata

# Preview what the metadata scaffold looks like (no file written)
qdo template -c <connection> -t <table> --sample-values 10

# Initialize the YAML file (machine fields auto-populated)
qdo metadata init -c <connection> -t <table>

# Open in $EDITOR to fill in human fields
qdo metadata edit -c <connection> -t <table>

# Read back the enriched metadata
qdo metadata show -c <connection> -t <table>

# Deterministically propose additions from scans
qdo metadata suggest -c <connection> -t <table>

# Check completeness across all documented tables
qdo metadata list -c <connection>

# Find stored tables / columns by description keyword (lexical, local)
qdo metadata search -c <connection> "fulfillment" --limit 5

# Re-profile after data changes (preserves human fields)
qdo metadata refresh -c <connection> -t <table>

Human fields to fill in

Field Level Purpose
table_description table What this table contains and its role
data_owner table Team or person responsible
update_frequency table How often data is refreshed
notes table Gotchas, quirks, caveats
description column What this column means in business terms
valid_values column Observed values when inferred; allowed values when human-approved or confidence 1.0
pii column true if column contains personal data

Using metadata as agent context

Export metadata as JSON and paste it into your prompt:

qdo metadata show -c <connection> -t <table1> -f json
qdo metadata show -c <connection> -t <table2> -f json

Prompt template:

You are a SQL expert. I'm working with a DuckDB database.

Table metadata:
[paste output of: qdo metadata show -c <db> -t <table1> -f json]
[paste output of: qdo metadata show -c <db> -t <table2> -f json]

Question: <your question>

Requirements:
- Use lowercase SQL keywords
- Handle nullable columns per null_pct in metadata
- Treat plain or confidence-1.0 valid_values as approved filter values; lower-confidence values are observations to verify
- Respect pii: true columns (do not expose in output unless asked)

The metadata tells the agent what schema alone cannot: observed or approved enum values, which columns are nullable, business meaning, ownership, and PII flags. Read it before writing nontrivial SQL, and distinguish observations from approved policy.

SQL generation

# SELECT scaffold — all columns, ready to trim
qdo sql select -c <connection> -t <table>

# CREATE TABLE DDL — portable to another database
qdo sql ddl -c <connection> -t <table>

# INSERT template with named placeholders
qdo sql insert -c <connection> -t <table>

# Scratch pad — TEMP TABLE + sample INSERTs from real data
qdo sql scratch -c <connection> -t <table>

Export

# CSV to stdout — pipe to file or another tool
qdo -f csv preview -c <connection> -t <table> -r 100

# JSON lines — one object per row (file export)
qdo export -c <connection> --sql "select ..." -e jsonl -o rows.jsonl

# Export command uses its own -e/--export-format for file format
qdo export -c <connection> -t <table> -e csv

Sampling and accuracy

Commands that scan table data (context, profile, quality) automatically sample tables over 1M rows for speed. When results are sampled, the JSON output includes "sampled": true and a "sampling_note" field. Check these fields before treating statistics as exact.

Gotchas

Workflows — author, run, share

Operator opt-in only: workflow and session commands are absent unless the operator sets QDO_EXPERIMENTAL=1. Their command APIs, schemas, and recovery behavior have no compatibility promise before qdo 1.0. Do not enable this mode on the user’s behalf.

A workflow is a YAML file that composes qdo commands into a parameterized, repeatable investigation. Use workflows when the same 3+ step pattern repeats against different tables or connections.

export QDO_EXPERIMENTAL=1
qdo workflow list                   # bundled + user + project workflows
qdo workflow spec                   # JSON Schema (authoritative contract)
qdo workflow spec --examples        # bundled example YAMLs
qdo workflow show <name>            # print the YAML
qdo workflow lint <name-or-path>    # structured issues with fix hints
qdo workflow run <name> key=value key=value

Canonical invocation is qdo workflow run <name>. There is no top-level qdo <workflow-name> alias.

Authoring loop (investigate interactively, then codify):

QDO_EXPERIMENTAL=1 QDO_SESSION=scratch qdo catalog -c mydb
QDO_EXPERIMENTAL=1 QDO_SESSION=scratch qdo context -c mydb -t orders
QDO_EXPERIMENTAL=1 QDO_SESSION=scratch qdo quality -c mydb -t orders
qdo workflow from-session scratch --name orders-summary \
  -o .qdo/workflows/orders-summary.yaml
qdo workflow lint .qdo/workflows/orders-summary.yaml
qdo workflow run orders-summary connection=mydb table=orders

Full guides (in the qdo repo):

Discover all commands

qdo --help
qdo <command> --help
qdo -f json overview         # machine-readable command reference