--- name: observe-lens-db description: >- Query databases read-only to see what state data is in while debugging, testing or answering a question: PostgreSQL, MySQL or MariaDB and MongoDB (including AWS RDS, Aurora and DocumentDB), directly or through an SSH tunnel, with a guard that only lets SELECT-style SQL and read-only Mongo expressions through. Discovers tables, columns and collections before querying. Use this whenever the user gives an order, customer, account, request or record id and wants to know what was stored, which status or error a record has, whether a migration or job changed data, or why the data does not match what the UI or an API shows, even if they do not say database, SQL, psql or Mongo. Read-only: for writing migrations, changesets, DDL or data fixes use a development skill instead. compatibility: >- Python 3.11+ (standard library only) on macOS, Linux or Windows, plus the engine's CLI (psql, mysql or mongosh) and ssh for tunnels. Needs an instance in ~/.config/observe-lens/db (see references/setup.md). license: Apache-2.0 metadata: version: "1.0.1" --- # observe-lens: DB Look up the real state of the data with read-only users so an investigation rests on facts instead of guesses. Run scripts with `python3`; on Windows use `python` or `py -3` if `python3` is not found. Paths below are relative to this skill's folder. ## Inputs - What to look up: an id (order, customer, request, trace, correlation), a table or collection, or a question about the data. - Which database: the instance (`config list` shows them, each with its engine and environment). Ask if more than one fits. ## Step 0: Read-command permission The first time this skill is used in a session, before running any command, ask the user once (with the multiple-choice question tool if there is one): 1. **Ask every time**: confirm each read command before running it. 2. **Auto-run reads for this skill**: run this skill's read commands without asking for the rest of the session. 3. **Auto-run reads for all observe-lens skills**: the same for `observe-lens`, `observe-lens-pipelines`, `observe-lens-cd`, `observe-lens-db` and `observe-lens-telemetry` for the rest of the session. Skip the question if the user already picked option 3 in another observe-lens skill this session, or option 2 for this skill. Keep the choice for the session; the user can change it at any time ("ask me again", "stop auto-running"). - **Read commands** (covered by options 2 and 3): `scripts/tunnel.py status|start|stop`, every `scripts/db.py` subcommand except `config init` and `config add` (`ping`, `tables`, `columns`, `query` with statements the guard accepts, `mongo` with read expressions, `config list|check|path|knowledge`). - **Any other read-only operation** (also covered by options 2 and 3, on any OS or shell): commands that only list, read, search or inspect, such as listing files and folders, reading or searching non-secret files, and checking tool versions, processes, open ports, environment variables or the time (for example `ls`/`dir`/`Get-ChildItem`, `cat`/`type`/`Get-Content`, `grep`/`findstr`/`Select-String`). If a command could change anything, treat it as state-changing. Reading credential files is never covered (see Rules). - **Production instances ask once, whatever the choice.** Before the first command against an instance that `config list` marks `confirm=yes` (environment `prod`, `production`, `prd` or `live` unless the instance sets `"confirm": false`, or any instance with `"confirm": true`), name the instance and ask once. Later reads against it follow the choice above for the rest of the session. Production systems are shared and hold real customer data, so a deliberate first look is worth one question. - **Always ask, whatever the choice**, for anything that inserts, updates, deletes or otherwise changes state: `config init`, editing files under the observe-lens config folder, `~/.ssh/config`, `.pgpass` or `.my.cnf`, installing a database CLI, changing file permissions, killing a process the tunnel helper did not start. One yes covers that one action only. Writes to a database stay off even when asked: the guard and read-only users refuse them, so point the user to their migration or change process instead of looking for a way around. ## Workflow 1. **Check config.** `python3 scripts/db.py config check` lists instances and whether their CLI, tunnel and credentials are in place. Fix gaps with `references/setup.md`. 2. **Read the user's notes.** `python3 scripts/db.py config knowledge` lists notes on schemas, key tables, which user reads which schema, id formats and status values. Read them before choosing a table. 3. **Tunnel, if the instance uses one.** `python3 scripts/tunnel.py status `; if it is down, `python3 scripts/tunnel.py start `. If start fails with an authentication error, stop and give the user the fix from `references/setup.md`: tunnels need key-based SSH because a password prompt cannot be answered from here. 4. **Check the connection.** `python3 scripts/db.py --instance ping` (add `--user ` when the instance has several read-only users). 5. **Discover before you assume.** The first time you touch a table or collection in a session, list it: `db.py --instance tables [--schema ] [--filter ]`, then `db.py --instance columns [--schema ]`; for MongoDB `columns ` samples a few documents and lists field paths and types. Column names differ between schemas and releases; a wrong guess wastes a round trip. 6. **Query.** - SQL: `db.py --instance query "