diff --git a/.claude/skills/otai/SKILL.md b/.claude/skills/otai/SKILL.md index bad78f5..9797bb6 100644 --- a/.claude/skills/otai/SKILL.md +++ b/.claude/skills/otai/SKILL.md @@ -52,11 +52,17 @@ column names, types, descriptions, and cross-dataset relationships/nested subfields, parsed from the release's croissant schema. ### `otai run-sql "" [--timeout SECONDS]` -Positional ``, a read-only SQL string. No `--release` flag: -- Unqualified table names resolve against `latest`. -- Schema-qualify a table to target a specific (possibly non-latest) - release, e.g. `"26.03".target`; this also enables cross-release joins in - a single query, e.g. `"26.06".target JOIN "26.03".target ...`. +Positional ``, a read-only SQL string. + +**No `--release` flag, unlike the subcommands above — don't pass one.** +Each release is a DuckDB schema named after its identifier, and `otai` +reads which release(s) it needs straight off your query's schema +qualifiers: `select * from "26.06".target` → release `26.06`, fetched/built +automatically if needed. Unqualified names (e.g. `target`) resolve to +`latest`. A single call can span any number of releases this way, e.g. +`... "26.06".target join "26.03".target on ...` — no separate flag or step +for comparing releases. + - The CLI enforces read-only SQL, a ~1000-row cap (response says whether results were truncated), and a timeout — do not attempt to replicate or second-guess these checks yourself. @@ -120,9 +126,17 @@ Every command emits one of: ` if the query is already minimal and legitimately slow; `sql_error` / `guardrail_violation` → fix the SQL; `release_not_found` → check `list-releases` before retrying. -6. **Cite your sources in the final answer**: state which release(s) were - queried and show the actual SQL you executed, so the user can verify or - rerun it. +6. **End your final answer with every `run-sql` query you ran**, not just + the last one if you iterated — plus the release(s) queried — so the + user can verify or rerun them. +7. **Check `data.truncated` on a successful `run-sql`, not just errors.** + A capped result (~1000 rows) is still `ok: true`; ignoring `truncated` + risks presenting a partial result as complete. When it's `true`, prefer + re-querying with an aggregate (`COUNT`, `GROUP BY`, `TOP N`) over the + raw rows; if the user genuinely needs row-level detail beyond 1000, + add an `ORDER BY` on a stable column and page with repeated + `LIMIT`/`OFFSET` calls. Either way, tell the user when what you're + showing is a subset. ## Example