Imported from yu-iskw/bq-inspector (
AGENTS.md). Install upstream withnpx skills add yu-iskw/bq-inspector. Copyright stays with the author.
bq-inspector — project instructions
Authoritative shared instructions for humans and coding agents. How each product loads this repo: Coding agents & instruction files.
Project overview
Read-only BigQuery job and metadata inspection CLI (src/bq_inspector/). Tooling:
- Package manager: uv (via
requirements.setup.txt, not mise) - CLI toolchain: mise — Trunk, Trivy, OSV-Scanner, Grype, CodeQL (
mise.toml[tasks],mise.lock,minimum_release_age = "7d") - Build system: Hatchling
- Linting/formatting: Trunk (Ruff, Pyright, Pylint, Bandit, Semgrep; Ruff is the formatter; Black is not used)
- Testing: pytest
- Python: 3.10+ (see
.python-versionfor the pinned version)
Quick commands
make setup-tools # mise: trunk, trivy, osv-scanner, grype, codeql (+ trunk install)
make setup # setup-tools + Python venv (uv sync)
make setup-python # Python venv only (skip CLI toolchain)
make lint # mise run lint (Trunk check)
make lint-python # Same as `make lint`
make format # mise run format-trunk + uv ssort
make dead-code # Find unused code with Vulture (see pyproject [tool.vulture])
make vulture # Same as make dead-code
make test # Run pytest with coverage (pytest-cov); alias: `make coverage`
make codeql # Run local CodeQL analysis
make build # Build the package
make clean # Clean build artifacts
Mise toolchain (local vs CI)
- Local / agents: Install mise on
PATH, thenmake setup-toolsormake setup. Commands usemise run <task>frommise.toml—there is nodev/mise-exec.shor other shell wrapper to invoke mise. - CI:
.github/workflows/mise_toolchain.ymlrunsjdx/mise-actionanddev/test-mise-toolchain.sh. Lint in PRs still uses Trunk Action; Python tests use uv. make setup-pythonworks without mise (Python/uv only).make setuprequires mise because it runssetup-toolsfirst.
Code style
- Follow the Google Python Style Guide (see
.pylintrc) - Use type hints for all public functions
- Imports sorted by Ruff (rule
I) - Max line length: 100 characters (Ruff)
snake_casefor functions and variables,PascalCasefor classes
Testing
- Tests live under
src/bq_inspector/tests/(colocated with the package) - Test files must match
test_*.py - Run
make testbefore commits - Aim for meaningful coverage on critical paths
Security
- Static analysis: Trunk runs Ruff, Pyright (types), Pylint, Bandit, Semgrep, and Trivy for quick feedback
- Deep analysis: GitHub CodeQL path analysis (see
.github/workflows/codeql.yml) - Dependencies: OSV-Scanner, Trivy, and Grype (
make scan-vulnerabilities; runs serially via mise; versions from mise) - Local CodeQL:
make codeql(CodeQL CLI via mise); on Linux or macOS ARM64,make setup-toolsskips the CodeQL version check (x64 bundle inmise.lock) make scan-vulnerabilities: OSV-Scanner exits 1 when it reports vulnerabilities (expected); fix deps or document accepted risk.- Use
trunk checkbefore pushing
AI guardrails & code quality
- Cyclomatic complexity: max 10 per function (Ruff
C901) - Maintainability: CodeQL
security-and-qualitytracks long-term health - If an edit pushes complexity over 10, refactor into smaller functions before finishing
Session postmortem (coding agents)
- Purpose: After a substantive session, run a retrospective so failures and inefficiencies surface as ranked Must / Should / Consider improvements. Template:
.agents/skills/postmortem/references/postmortem-report-template.md. - Invocation: Invoke the
postmortemskill (e.g./postmortemin Claude Code). Load from.claude/skills/postmortem/or.agents/skills/postmortem/depending on your tool. Keep output in chat unless the user asks to persist; the skill does not authorize editingAGENTS.md,CLAUDE.md, or skills without a separate request. - Skip: Do not run after purely mechanical work with no learning signal (e.g. obvious typo, format-only pass, trivial dependency bump with no retries). If the session included debugging, ambiguity, or retries, run a postmortem anyway.
Git workflow
- Branch from
main - Run
make lint && make testbefore commits - Conventional commits:
type(scope): description(e.g.feat(api): add user endpoint) - Types:
feat,fix,docs,style,refactor,test,chore - For releases, record changes with the
manage-changelogskill when Changie is available (fragments, batch, merge intoCHANGELOG.md)
Architecture
- Package source:
src/bq_inspector/ - Dev scripts:
dev/ - CI/CD:
.github/workflows/ - Claude Code automation:
.claude/— see CLAUDE.md for how Claude loads this repo and the directory layout - Architecture decision records (ADRs):
docs/adr/. Use themanage-adrskill when theadrCLI is installed
Common gotchas
-
Do not add shell wrappers (e.g.
mise-exec.sh) to call mise; usemise.toml[tasks]andmise run. -
After clone: run
mise trust, thenmise install --locked(ormake setup-tools/make setup); workflows are[tasks]inmise.toml(mise run lint,mise tasks) -
Refresh the toolchain lock with
mise lockand commitmise.lockwhen bumping CLI tools -
Keep mise scanner versions aligned with
.trunk/trunk.yaml(Trivy, OSV-Scanner) when bumping either side -
Run Python tools with
uv run …in the project virtualenv -
Trunk pins linter versions under
.trunk/;make setup-toolsrunsmise run trunk-install -
Commit
uv.lockandmise.lock(do not gitignore them) -
If
mise install --lockedfails locally, extra tools in~/.config/mise/config.tomlmay be missing frommise.lock;make setup-toolsretries without--locked, or runMISE_LOCKED=false mise install -
If Trunk errors about a missing managed linter, run
mise run trunk-install(viamake setup-tools)
Parallel or multi-step work (Claude Code)
- This repo does not ship a built-in parallel orchestration subagent. For concurrent work, use multiple Task invocations, your editor’s multi-agent features, or your own scripts.
- After substantial or overlapping edits, use the
verifiersubagent (.claude/agents/verifier.md) to run build → lint → test → dependency scan → CodeQL by delegating each phase tobuild-and-fix,lint-and-fix,test-and-fix,security-scan, andcodeql-fix.
Claude Code subagents
Invoked from Claude Code (Task tool or slash flows). Definitions: .claude/agents/*.md
verifier— Five-phase verification via preload skills; see .claude/agents/verifier.md.
Claude Code skills
Slash-invoked skills live under .claude/skills/<name>/SKILL.md. Use a skill when it matches the task; each SKILL.md lists prerequisites (some require a CLI on PATH). Skills cite this file and Makefile targets rather than linking peer-to-peer to other SKILL.md files.
| Skill | When to use |
|---|---|
build-and-fix |
Build or packaging failures |
check-directory-structure |
After bulk edits; audit layout; fix flat/misplaced files |
codeql-fix |
Local CodeQL (make codeql); requires CodeQL CLI |
lint-and-fix |
Trunk / linter failures |
test-and-fix |
Failing tests |
setup-dev-env |
First-time or broken environment |
python-upgrade |
Dependency upgrades with uv |
security-scan |
Trivy / OSV / Grype (make scan-vulnerabilities) |
initialize-project |
Renaming the template and bootstrapping |
manage-adr |
ADRs in docs/adr (requires adr CLI) |
postmortem |
Substantive session end; incidents; skip trivial chore-only sessions |
problem-solving |
Single-pass XY-aware analysis and scored comparison (default 5 options) |
deep-problem-solving |
Same style of report after ten multiple-choice questions (one per turn) |
Some tools load mirrored skills under .agents/skills/ instead of .claude/. Other repos may add manage-changelog when Changie is configured (see Git workflow).
Coding agents & instruction files
| Product / channel | How this repo is wired |
|---|---|
| Cursor | Loads root AGENTS.md and root CLAUDE.md for Agent chat (and optional .cursor/rules/). Cursor: Rules |
| OpenAI Codex | Merges ~/.codex/AGENTS.md (or override) with repo AGENTS.md along the path; default size cap (often 32 KiB) applies to the combined project doc. Project overrides (e.g. sandbox_mode, approval_policy, [sandbox_workspace_write]) can live in .codex/config.toml when the project is trusted. Codex: AGENTS.md, Codex: Sandboxing |
| Claude Code | Reads CLAUDE.md (which inlines this file) plus .claude/. Anthropic: CLAUDE.md, Claude directory |
| Gemini CLI | Project .gemini/settings.json includes AGENTS.md in context.fileName with typical GEMINI.md handling. Gemini: context |
| GitHub Copilot (Chat, code review, cloud agent) | Treats root AGENTS.md (and CLAUDE.md / GEMINI.md if present) as agent instructions; may also use .github/copilot-instructions.md and path-scoped files with defined precedence. Custom instructions |
Copilot / GitHub.com: This repo does not add .github/copilot-instructions.md; build, test, and style narrative stay in this file. On GitHub.com, personal instructions override repository content, then path-scoped rules and copilot-instructions.md apply (see Custom instructions). Edit policy: shared rules here; Claude Code-only behavior, @AGENTS.md import, and .claude/ details in CLAUDE.md.
Where things live (quick map)
- This file — Stack,
maketargets, style, testing, security, git, ADR pointers, Claude subagent/skill tables - CLAUDE.md +
.claude/— Claude Code entrypoint and automation layout (see CLAUDE.md for directory breakdown and self-improvement rules) .agents/skills/— Skills for tools that do not read.claude/(e.g.postmortem); may mirror.claude/skills/.gemini/settings.json— Gemini CLI project context.cursor/rules/— Optional Cursor rules (e.g. Always Apply); see Cursor: Rules.codex/config.toml— Optional Codex defaults (sandbox, approvals); links above under OpenAI Codex
Learned User Preferences
- Prefer minimal, focused fixes over broad refactors; do not over-implement beyond stated scope when adding CLI or adapter features.
- Do not commit local
uv.lockormise.lockchurn from setup when unrelated to the task. - Exclude unrelated untracked paths (e.g.
.cursor/hooks/) from commits unless explicitly requested.
Learned Workspace Facts
- This repo is bq-inspector (BigQuery CLI); package source is
src/bq_inspector/, not templatesrc/your_package/. - In git worktrees, run
mise trustbeforemake setup-pythonor other mise tasks. - Pyright resolves imports from
.venv; runmake setup-pythonbeforemake lintor third-party imports fail spuriously. - BigQuery job subcommands are nested under
jobs(e.g.bq-inspector jobs summary); flat shorthand also works (e.g.bq-inspector summary). - The legacy
bq-inspector schemasubcommand was removed; use per-command--input-schemaand--output-schema. - BigQuery composite job IDs (
projectId:location.jobId) may be passed in thejobIdfield;normalize_job_refincore/shared/job_ref.pysplits them. - SDK adapter uses
_resource_to_api_dict()(._propertieswithto_api_reprfallback) for jobs, datasets, and tables so responses include full REST fields. - For job-local lineage/impact verification, use a job that references tables;
SELECT 1-style jobs legitimately have empty lineage/impact fields. jobs lineageis job-local (jobs.getprojection);lineage linksandlineage graphuse the Data Lineage API viadatalineage/(google-cloud-datacatalog-lineage).- Data Lineage BigQuery table FQNs use Dataplex dot-delimited format
bigquery:{projectId}.{datasetId}.{tableId}(not REST path-style). - Lineage commands request
cloud-platformOAuth scope (required bysearchLinks); IAM still requiresroles/datalineage.vieweronclientProjectId. clientProjectIddefaults toprojectIdfor lineage commands when omitted; barelineage --helpshows the lineage group while barelineagewith--params/--input-schemastill flat-aliases tojobs lineage.
