From bc226d8bafbb12a2c967d304ae49c04683d72f4d Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Fri, 27 Feb 2026 11:08:00 +0100 Subject: [PATCH] chore(db): move db/connectors/ to tooling/db/ (#274) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidates all connector scripts under tooling/ per project structure conventions. Symlink at db/connectors → tooling/db/ preserves backwards compatibility (remove after Sprint 22). Updated references in CLAUDE.md, Makefile, DEVOPS.md, all skill files, agent files, rules, schema comments, and Sprint 21 briefings. Python scripts updated with correct SCHEMA_PATH (now relative to WORKTREE_ROOT/db/schema.sql). Co-Authored-By: Claude Opus 4.6 --- .claude/agents/qatux.md | 2 +- .claude/rules/local-services.md | 2 +- .claude/rules/project-structure.md | 6 +++- .claude/settings.json | 17 ++++++++++ .claude/skills/audio-gen/SKILL.md | 30 ++++++++--------- .claude/skills/bug-report/SKILL.md | 2 +- .claude/skills/docs-search/SKILL.md | 6 ++-- .claude/skills/pr-push/SKILL.md | 2 +- .claude/skills/sprint-plan/SKILL.md | 12 +++---- .../references/briefing-template.md | 2 +- .claude/skills/sprint-start/SKILL.md | 22 ++++++------- .claude/skills/sprint-status/SKILL.md | 2 +- .claude/skills/ticket/SKILL.md | 32 +++++++++---------- CLAUDE.md | 22 ++++++------- Makefile | 8 ++--- db/connectors | 1 + db/schema.sql | 4 +-- decisions/README.md | 2 +- docs/DEVOPS.md | 12 +++---- docs/sprints/sprint-21/client.md | 2 +- docs/sprints/sprint-21/server.md | 2 +- docs/sprints/sprint-21/visual.md | 2 +- tooling/check-decision-ids | 2 +- {db/connectors => tooling/db}/audio-batch | 0 {db/connectors => tooling/db}/audio-generate | 0 {db/connectors => tooling/db}/audio-health | 0 {db/connectors => tooling/db}/audio-post | 0 {db/connectors => tooling/db}/audio_batch.py | 0 .../db}/audio_connector.py | 0 {db/connectors => tooling/db}/audio_post.py | 0 {db/connectors => tooling/db}/config.json | 0 {db/connectors => tooling/db}/decision | 0 {db/connectors => tooling/db}/decisions-sync | 0 .../db}/decisions_sync.py | 8 ++--- {db/connectors => tooling/db}/qdrant-count | 0 {db/connectors => tooling/db}/qdrant-health | 0 {db/connectors => tooling/db}/qdrant-index | 0 {db/connectors => tooling/db}/qdrant-search | 0 .../db}/qdrant_connector.py | 0 {db/connectors => tooling/db}/sprint | 15 +++++---- {db/connectors => tooling/db}/sqlite-exec | 0 {db/connectors => tooling/db}/sqlite-init | 0 {db/connectors => tooling/db}/sqlite-query | 0 {db/connectors => tooling/db}/sqlite-seed | 0 .../db}/sqlite_connector.py | 7 ++-- {db/connectors => tooling/db}/ticket | 5 +-- tooling/synth_ui_sounds.py | 2 +- 47 files changed, 128 insertions(+), 103 deletions(-) create mode 120000 db/connectors rename {db/connectors => tooling/db}/audio-batch (100%) rename {db/connectors => tooling/db}/audio-generate (100%) rename {db/connectors => tooling/db}/audio-health (100%) rename {db/connectors => tooling/db}/audio-post (100%) rename {db/connectors => tooling/db}/audio_batch.py (100%) rename {db/connectors => tooling/db}/audio_connector.py (100%) rename {db/connectors => tooling/db}/audio_post.py (100%) rename {db/connectors => tooling/db}/config.json (100%) rename {db/connectors => tooling/db}/decision (100%) rename {db/connectors => tooling/db}/decisions-sync (100%) rename {db/connectors => tooling/db}/decisions_sync.py (98%) rename {db/connectors => tooling/db}/qdrant-count (100%) rename {db/connectors => tooling/db}/qdrant-health (100%) rename {db/connectors => tooling/db}/qdrant-index (100%) rename {db/connectors => tooling/db}/qdrant-search (100%) rename {db/connectors => tooling/db}/qdrant_connector.py (100%) rename {db/connectors => tooling/db}/sprint (98%) rename {db/connectors => tooling/db}/sqlite-exec (100%) rename {db/connectors => tooling/db}/sqlite-init (100%) rename {db/connectors => tooling/db}/sqlite-query (100%) rename {db/connectors => tooling/db}/sqlite-seed (100%) rename {db/connectors => tooling/db}/sqlite_connector.py (97%) rename {db/connectors => tooling/db}/ticket (99%) diff --git a/.claude/agents/qatux.md b/.claude/agents/qatux.md index e6e2082e4..ab83010ea 100644 --- a/.claude/agents/qatux.md +++ b/.claude/agents/qatux.md @@ -44,7 +44,7 @@ Named after Qatux, the Raiel with perfect memory who helped Paula Myo by recalli - **Work in dedicated round files:** All new rounds happen in `docs/discussions/round-NN-topic.md` from the start. DISCUSSION.md is retired for new content. - **Update the discussion index ONLY when closing:** After a round is formally closed, update `docs/discussions/README.md` with the round entry (number, topic, decisions produced, file link). - **Update briefings:** After a round produces new decisions, update the relevant agent briefing files in `docs/briefings/`. -- **Re-index documents:** After archiving or updating documents, re-index them in Qdrant via `db/connectors/qdrant-index `. +- **Re-index documents:** After archiving or updating documents, re-index them in Qdrant via `tooling/db/qdrant-index `. ## Team workflow (mandatory) diff --git a/.claude/rules/local-services.md b/.claude/rules/local-services.md index 4decd8975..df1a95c22 100644 --- a/.claude/rules/local-services.md +++ b/.claude/rules/local-services.md @@ -1,6 +1,6 @@ # Local Services -Endpoints are also preconfigured in `db/connectors/config.json`. +Endpoints are also preconfigured in `tooling/db/config.json`. - **Gitea:** `http://git.schweitz.internal` (login: `schweitz`) - **Qdrant:** `http://tower-of-joy:6333/` diff --git a/.claude/rules/project-structure.md b/.claude/rules/project-structure.md index 02a3fcbb4..63523ee71 100644 --- a/.claude/rules/project-structure.md +++ b/.claude/rules/project-structure.md @@ -17,11 +17,15 @@ docs/ workshops/ # Workshop briefs and outputs db/ schema.sql # Database schema - connectors/ # Connector scripts for SQLite and Qdrant + connectors/ # Symlink → tooling/db/ (backwards compat, remove after Sprint 22) +tooling/ + db/ # Connector scripts for SQLite, Qdrant, and audio config.json # Endpoint configuration ticket # Ticket CLI + sprint # Sprint lifecycle CLI sqlite_connector.py # SQLite mini MCP qdrant_connector.py # Qdrant + ollama mini MCP + audio_connector.py # Stable Audio Open connector .claude/ agents/ # Agent personality files skills/ # Skill definitions diff --git a/.claude/settings.json b/.claude/settings.json index 7fdad419b..970869f6e 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -25,6 +25,23 @@ "Bash(git ls-tree *)", "Bash(git rev-parse --show-toplevel)", + "Bash(tooling/db/ticket *)", + "Bash(tooling/db/sprint *)", + "Bash(tooling/db/sqlite-query *)", + "Bash(tooling/db/sqlite-exec *)", + "Bash(tooling/db/qdrant-search *)", + "Bash(tooling/db/qdrant-index *)", + "Bash(tooling/db/qdrant-health)", + "Bash(tooling/db/qdrant-count)", + "Bash(tooling/db/sqlite-init)", + "Bash(tooling/db/decisions-sync)", + "Bash(tooling/db/decision *)", + + "Bash(tooling/db/audio-generate *)", + "Bash(tooling/db/audio-health)", + "Bash(tooling/db/audio-post *)", + "Bash(tooling/db/audio-batch *)", + "Bash(db/connectors/ticket *)", "Bash(db/connectors/sprint *)", "Bash(db/connectors/sqlite-query *)", diff --git a/.claude/skills/audio-gen/SKILL.md b/.claude/skills/audio-gen/SKILL.md index ef6a17526..4c820e289 100644 --- a/.claude/skills/audio-gen/SKILL.md +++ b/.claude/skills/audio-gen/SKILL.md @@ -13,7 +13,7 @@ description: > # Audio Generation — The Settled Reach Generate sonically consistent audio assets using the Stable Audio Open API via -wrapper scripts at `db/connectors/audio-*`. +wrapper scripts at `tooling/db/audio-*`. Asset descriptions, filenames, bus routing, and design intent are documented in `docs/assets/audio/`. This skill provides the prompt system, generation @@ -25,21 +25,21 @@ workflow, and quality validation. ```bash # Check API health -db/connectors/audio-health +tooling/db/audio-health # Generate a single asset (WAV only) -db/connectors/audio-generate "prompt text" \ +tooling/db/audio-generate "prompt text" \ --duration 10 --steps 100 --cfg 7 \ --output path/to/output.wav # Generate + post-process in one command (WAV → trim → normalize → OGG) -db/connectors/audio-generate "prompt text" \ +tooling/db/audio-generate "prompt text" \ --duration 10 --steps 100 --cfg 7 \ --output path/to/gen/intermediate.wav \ --output-ogg client/assets/audio/final.ogg # Batch-generate from a manifest (preferred for multiple assets) -db/connectors/audio-batch docs/assets/audio/batch-s10-327.json +tooling/db/audio-batch docs/assets/audio/batch-s10-327.json ``` ### Parameters @@ -138,16 +138,16 @@ AMB-001, SFX-002, UI-005). This couples the manifest to the asset inventory. ```bash # Full run -db/connectors/audio-batch docs/assets/audio/batch-s10-327.json +tooling/db/audio-batch docs/assets/audio/batch-s10-327.json # Dry run — preview what would be generated -db/connectors/audio-batch docs/assets/audio/batch-s10-327.json --dry-run +tooling/db/audio-batch docs/assets/audio/batch-s10-327.json --dry-run # Generate only specific assets -db/connectors/audio-batch docs/assets/audio/batch-s10-327.json --only AMB-001,AMB-002 +tooling/db/audio-batch docs/assets/audio/batch-s10-327.json --only AMB-001,AMB-002 # Skip assets that already have OGG files -db/connectors/audio-batch docs/assets/audio/batch-s10-327.json --skip-existing +tooling/db/audio-batch docs/assets/audio/batch-s10-327.json --skip-existing ``` ### 3. Update asset docs with prompts @@ -190,8 +190,8 @@ For one-off generation or iteration on a specific asset: 2. Read `references/sonic-palette.md` for the sonic family prefix. 3. Read `references/category-templates.md` for the matching template. 4. Assemble the full prompt. -5. Run `db/connectors/audio-health` to verify the API is up. -6. Run `db/connectors/audio-generate` with `--post` or `--output-ogg` to +5. Run `tooling/db/audio-health` to verify the API is up. +6. Run `tooling/db/audio-generate` with `--post` or `--output-ogg` to generate and post-process in one step. 7. Verify the output (file size, duration). 8. Update the asset status and prompt in `docs/assets/audio/{category}.md`. @@ -218,12 +218,12 @@ If you need to post-process separately (e.g., re-normalizing an existing file): ```bash # Full pipeline: trim → normalize → convert -db/connectors/audio-post pipeline input.wav --output output.ogg +tooling/db/audio-post pipeline input.wav --output output.ogg # Individual steps -db/connectors/audio-post trim input.wav -db/connectors/audio-post normalize input.wav --lufs -16 -db/connectors/audio-post convert input.wav --output output.ogg +tooling/db/audio-post trim input.wav +tooling/db/audio-post normalize input.wav --lufs -16 +tooling/db/audio-post convert input.wav --output output.ogg ``` ## Manual Synthesis (Insert-Tech Sounds) diff --git a/.claude/skills/bug-report/SKILL.md b/.claude/skills/bug-report/SKILL.md index b23bd634a..4d06aca63 100644 --- a/.claude/skills/bug-report/SKILL.md +++ b/.claude/skills/bug-report/SKILL.md @@ -169,7 +169,7 @@ Construct the ticket title and description from the report summary and any investigation findings. Use the ticket CLI: ```bash -db/connectors/ticket create bug "{title}" --team {team} --description "{description}" +tooling/db/ticket create bug "{title}" --team {team} --description "{description}" ``` The description should include: diff --git a/.claude/skills/docs-search/SKILL.md b/.claude/skills/docs-search/SKILL.md index f36947254..fb20cc01e 100644 --- a/.claude/skills/docs-search/SKILL.md +++ b/.claude/skills/docs-search/SKILL.md @@ -20,14 +20,14 @@ and workflows. For precise indexing of specific content: ```bash -python3 db/connectors/qdrant_connector.py index "unique-id" "Text content to index" --metadata source=manual heading="Custom heading" +python3 tooling/db/qdrant_connector.py index "unique-id" "Text content to index" --metadata source=manual heading="Custom heading" ``` ### Create collection Initialize the Qdrant collection (run once during setup): ```bash -python3 db/connectors/qdrant_connector.py create-collection +python3 tooling/db/qdrant_connector.py create-collection ``` ## Bulk Indexing @@ -35,7 +35,7 @@ python3 db/connectors/qdrant_connector.py create-collection Index all project documents at once: ```bash for f in decisions/*.md DISCUSSION.md TEAM.md docs/discussions/*.md docs/briefings/*.md; do - db/connectors/qdrant-index "$f" + tooling/db/qdrant-index "$f" done ``` diff --git a/.claude/skills/pr-push/SKILL.md b/.claude/skills/pr-push/SKILL.md index 82a996b23..3d8e6a5e9 100644 --- a/.claude/skills/pr-push/SKILL.md +++ b/.claude/skills/pr-push/SKILL.md @@ -123,7 +123,7 @@ Extract ticket IDs from `#NNN` patterns. For each ticket that is currently `in_progress`, update it to `review`: ```bash -db/connectors/ticket status review +tooling/db/ticket status review ``` Report which tickets were moved to review. Skip tickets that are diff --git a/.claude/skills/sprint-plan/SKILL.md b/.claude/skills/sprint-plan/SKILL.md index dd7cd060d..4e8b22a6c 100644 --- a/.claude/skills/sprint-plan/SKILL.md +++ b/.claude/skills/sprint-plan/SKILL.md @@ -88,7 +88,7 @@ the user and a purpose-assembled agent panel. Get carry-overs, backlog candidates, and decision gaps in one shot: ```bash -db/connectors/sprint prepare +tooling/db/sprint prepare ``` This auto-detects the next sprint number (max ID + 1), creates the sprint @@ -103,10 +103,10 @@ record in `planning` status if needed, and outputs: For critical epics, check their children for granular candidates: ```bash -db/connectors/ticket children +tooling/db/ticket children ``` -Use `db/connectors/ticket show --brief [...]` to quickly scan multiple tickets. +Use `tooling/db/ticket show --brief [...]` to quickly scan multiple tickets. ### 3. Read existing code state @@ -184,14 +184,14 @@ Update it with the theme and goal, then assign tickets: ```bash # Update the sprint with theme and goal -db/connectors/sqlite-exec "UPDATE sprints SET name='Sprint N: Theme', goal='goal' WHERE id=N" +tooling/db/sqlite-exec "UPDATE sprints SET name='Sprint N: Theme', goal='goal' WHERE id=N" # Assign tickets -db/connectors/ticket sprint assign +tooling/db/ticket sprint assign ``` The sprint stays in `planning` status until explicitly activated via -`db/connectors/sprint start`. This prevents starting an unplanned sprint. +`tooling/db/sprint start`. This prevents starting an unplanned sprint. ### 8. Present summary diff --git a/.claude/skills/sprint-plan/references/briefing-template.md b/.claude/skills/sprint-plan/references/briefing-template.md index 5a81729cf..34adf6320 100644 --- a/.claude/skills/sprint-plan/references/briefing-template.md +++ b/.claude/skills/sprint-plan/references/briefing-template.md @@ -26,7 +26,7 @@ Each team gets one briefing file at `docs/sprints/sprint-N/.md`. |---|-------|------------| | #ID | Title | #dependency or — | -Use `db/connectors/ticket show ` for full details. +Use `tooling/db/ticket show ` for full details. ## Key Decisions diff --git a/.claude/skills/sprint-start/SKILL.md b/.claude/skills/sprint-start/SKILL.md index cb5148525..6a800083d 100644 --- a/.claude/skills/sprint-start/SKILL.md +++ b/.claude/skills/sprint-start/SKILL.md @@ -38,7 +38,7 @@ When `/sprint-start` is run on `main`, assess the current sprint state and do the next right thing. Query the database to determine the state: ```bash -db/connectors/sqlite-query "SELECT id, name, status FROM sprints ORDER BY id DESC LIMIT 3" +tooling/db/sqlite-query "SELECT id, name, status FROM sprints ORDER BY id DESC LIMIT 3" ``` Then follow the **first matching case**: @@ -48,7 +48,7 @@ Then follow the **first matching case**: First, check whether the sprint's work is actually done: ```bash -db/connectors/sprint status +tooling/db/sprint status ``` This shows ticket counts by status (done, in_progress, backlog). @@ -81,7 +81,7 @@ explicitly chooses to close. #### A1. Close the active sprint ```bash -db/connectors/sprint stop +tooling/db/sprint stop ``` This marks the active sprint as completed and lists carry-over candidates. @@ -142,7 +142,7 @@ A sprint is ready to activate. Verify it looks complete: ``` 2. Check the ticket count: ```bash - db/connectors/sprint status --sprint N + tooling/db/sprint status --sprint N ``` If briefings are missing or the sprint has 0 tickets, report the gap @@ -151,7 +151,7 @@ and suggest running `/sprint-plan` to complete planning. If everything looks ready, activate the sprint: ```bash -db/connectors/sprint start +tooling/db/sprint start ``` Then report: @@ -184,7 +184,7 @@ If the merge has conflicts, report them and stop — do not force-resolve. Run the sprint CLI to get the full context dump in one shot: ```bash -db/connectors/sprint start-work +tooling/db/sprint start-work ``` This auto-detects the active sprint and current team from the branch. @@ -204,7 +204,7 @@ If no matching briefing exists for the team, suggest running For tickets that need more detail than the `start-work` summary provides: ```bash -db/connectors/ticket show +tooling/db/ticket show ``` ### 6. Read key decisions @@ -218,7 +218,7 @@ Mark all actionable (unblocked, non-done) tickets in the sprint as `in_progress`: ```bash -db/connectors/ticket status in_progress +tooling/db/ticket status in_progress ``` Then output a summary: @@ -296,8 +296,8 @@ Task( 2. DB SCRIPTS: When calling ticket/sprint/sqlite scripts, use the exact command with no wrappers or chaining. Examples: - db/connectors/ticket show 528 - db/connectors/ticket list --sprint {N} + tooling/db/ticket show 528 + tooling/db/ticket list --sprint {N} Do NOT prepend python3, do NOT chain with && or ;, do NOT add cleanup commands. Just the bare command. @@ -346,7 +346,7 @@ Task( 7. If no tasks remain, message the team lead. Do NOT shut down on your own. - Use `db/connectors/ticket show ` for full ticket specs.", + Use `tooling/db/ticket show ` for full ticket specs.", description: "Sprint {N} {team}: {name}", run_in_background: true ) diff --git a/.claude/skills/sprint-status/SKILL.md b/.claude/skills/sprint-status/SKILL.md index 5c1ac9b80..ada1ccd56 100644 --- a/.claude/skills/sprint-status/SKILL.md +++ b/.claude/skills/sprint-status/SKILL.md @@ -41,7 +41,7 @@ the workflow. Run these two commands in parallel: ```bash -db/connectors/sprint sweep +tooling/db/sprint sweep ``` ```bash diff --git a/.claude/skills/ticket/SKILL.md b/.claude/skills/ticket/SKILL.md index ce4eaa732..247191da6 100644 --- a/.claude/skills/ticket/SKILL.md +++ b/.claude/skills/ticket/SKILL.md @@ -17,60 +17,60 @@ section. This skill covers the full command reference. ### List tickets (full flags) ```bash -db/connectors/ticket list [--status S] [--priority P] [--epic N] [--sprint N] [--assigned A] [--team T] +tooling/db/ticket list [--status S] [--priority P] [--epic N] [--sprint N] [--assigned A] [--team T] ``` ### Create ticket ```bash -db/connectors/ticket create [--parent N] [--priority P] [--decision D] [--team T] +tooling/db/ticket create <type> <title> [--parent N] [--priority P] [--decision D] [--team T] ``` Types: `initiative`, `epic`, `story`, `task`, `bug` Priorities: `critical`, `high`, `medium`, `low` ### Update status ```bash -db/connectors/ticket status <id> <new_status> -db/connectors/ticket done <id> [<id> ...] +tooling/db/ticket status <id> <new_status> +tooling/db/ticket done <id> [<id> ...] ``` Statuses: `backlog`, `ready`, `in_progress`, `review`, `done`, `cancelled` ### Assignment ```bash -db/connectors/ticket assign <id> <agent> -db/connectors/ticket unassign <id> +tooling/db/ticket assign <id> <agent> +tooling/db/ticket unassign <id> ``` ### Team assignment ```bash -db/connectors/ticket team <id> <teams> +tooling/db/ticket team <id> <teams> ``` Teams are comma-separated, e.g. `server`, `client`, `server,client`. ### Sprint management ```bash -db/connectors/ticket sprint [--active] -db/connectors/ticket sprint assign <id> <sprint_id> +tooling/db/ticket sprint [--active] +tooling/db/ticket sprint assign <id> <sprint_id> ``` For sprint-scoped operations (status overview, context dumps, lifecycle), -use the dedicated sprint CLI instead: `db/connectors/sprint --help` +use the dedicated sprint CLI instead: `tooling/db/sprint --help` ### Dependencies ```bash -db/connectors/ticket deps <id> +tooling/db/ticket deps <id> ``` ### Search and browse ```bash -db/connectors/ticket search <keyword> -db/connectors/ticket epics [--status S] -db/connectors/ticket children <id> -db/connectors/ticket count [--status S] +tooling/db/ticket search <keyword> +tooling/db/ticket epics [--status S] +tooling/db/ticket children <id> +tooling/db/ticket count [--status S] ``` ### Batch show ```bash -db/connectors/ticket show --brief <id> [<id>...] +tooling/db/ticket show --brief <id> [<id>...] ``` ## Workflow diff --git a/CLAUDE.md b/CLAUDE.md index 780a2c88d..708a170b0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,7 +14,7 @@ server/ # Rust/bevy_ecs simulation server tooling/ # Build tools, scripts, asset pipelines tests/ # Integration and end-to-end tests docs/ # Architecture, design, briefings, sprints, workshops -db/ # Schema + connector scripts (ticket CLI, SQLite, Qdrant) +db/ # Schema + seed data (connectors moved to tooling/db/) .claude/ # Agents, skills, rules decisions/ # Decision domain files (D-NNN confirmed, Q-NNN open, R-NNN rejected) ``` @@ -42,7 +42,7 @@ The ticketing database (`settledreach.db`) lives in the **parent directory** sha ### Before starting work 1. Read your sprint briefing at `docs/sprints/sprint-N/{team}.md` for current tasks -2. Use `db/connectors/ticket show <id>` for full ticket details +2. Use `tooling/db/ticket show <id>` for full ticket details 3. Read the relevant `decisions/*.md` domain file(s) referenced in the briefing 4. Background context: `docs/briefings/{your-name}.md`, `docs/discussions/` @@ -52,19 +52,19 @@ The ticketing database (`settledreach.db`) lives in the **parent directory** sha | Tool | Command | Full reference | |------|---------|----------------| -| Tickets | `db/connectors/ticket list`, `show`, `create`, `assign` | `/ticket` skill | -| Sprints | `db/connectors/sprint status`, `start-work`, `prepare` | `/sprint-start` skill | -| SQL queries | `db/connectors/sqlite-query "SELECT ..."` | — | -| SQL writes | `db/connectors/sqlite-exec "UPDATE ..."` | — | -| Decisions | `db/connectors/decision next`, `claim`, `check-dupes` | — | -| Doc search | `db/connectors/qdrant-search "query"` | `/docs-search` skill | -| Doc index | `db/connectors/qdrant-index path/to/file.md` | `/docs-search` skill | +| Tickets | `tooling/db/ticket list`, `show`, `create`, `assign` | `/ticket` skill | +| Sprints | `tooling/db/sprint status`, `start-work`, `prepare` | `/sprint-start` skill | +| SQL queries | `tooling/db/sqlite-query "SELECT ..."` | — | +| SQL writes | `tooling/db/sqlite-exec "UPDATE ..."` | — | +| Decisions | `tooling/db/decision next`, `claim`, `check-dupes` | — | +| Doc search | `tooling/db/qdrant-search "query"` | `/docs-search` skill | +| Doc index | `tooling/db/qdrant-index path/to/file.md` | `/docs-search` skill | ### File conventions - Decisions: domain files in `decisions/` (see `decisions/README.md` for index) - Decision IDs: `D-NNN` (confirmed), `Q-NNN` (open questions), `R-NNN` (rejected) -- **Claim IDs before writing:** `db/connectors/decision claim D <domain> "title"` — prevents ID collisions across worktrees +- **Claim IDs before writing:** `tooling/db/decision claim D <domain> "title"` — prevents ID collisions across worktrees - Diagrams: `.d2` source + `.png` renders in `docs/diagrams/{category}/`. Create or update diagrams via `/d2-diagram` when D-records are added or modified. - Discussion rounds: numbered sequentially, archived to `docs/discussions/` when complete - Briefings: one per agent, updated after decision-producing rounds -- Tickets: managed via `db/connectors/ticket` CLI or `/ticket` skill +- Tickets: managed via `tooling/db/ticket` CLI or `/ticket` skill diff --git a/Makefile b/Makefile index 95294d5ee..772b8ffb0 100644 --- a/Makefile +++ b/Makefile @@ -284,16 +284,16 @@ db-install: # --- Decisions --- decisions-sync: - @db/connectors/decisions-sync + @tooling/db/decisions-sync decisions-coverage: - @db/connectors/sqlite-query "SELECT d.domain, COUNT(DISTINCT d.id) as decisions, COUNT(DISTINCT t.decision_ref) as with_tickets FROM decisions d LEFT JOIN tickets t ON d.id = t.decision_ref WHERE d.status='active' AND d.type='confirmed' GROUP BY d.domain" + @tooling/db/sqlite-query "SELECT d.domain, COUNT(DISTINCT d.id) as decisions, COUNT(DISTINCT t.decision_ref) as with_tickets FROM decisions d LEFT JOIN tickets t ON d.id = t.decision_ref WHERE d.status='active' AND d.type='confirmed' GROUP BY d.domain" decisions-active: - @db/connectors/sqlite-query "SELECT id, domain, title FROM decisions WHERE status='active' AND type='confirmed' ORDER BY domain, id" + @tooling/db/sqlite-query "SELECT id, domain, title FROM decisions WHERE status='active' AND type='confirmed' ORDER BY domain, id" decisions-orphan: - @db/connectors/sqlite-query "SELECT id, title FROM decisions WHERE type='confirmed' AND status='active' AND id NOT IN (SELECT DISTINCT decision_ref FROM tickets WHERE decision_ref IS NOT NULL)" + @tooling/db/sqlite-query "SELECT id, title FROM decisions WHERE type='confirmed' AND status='active' AND id NOT IN (SELECT DISTINCT decision_ref FROM tickets WHERE decision_ref IS NOT NULL)" # --- Content Validation --- diff --git a/db/connectors b/db/connectors new file mode 120000 index 000000000..d424fdf7f --- /dev/null +++ b/db/connectors @@ -0,0 +1 @@ +../tooling/db \ No newline at end of file diff --git a/db/schema.sql b/db/schema.sql index d202f85d2..249f19012 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -1,5 +1,5 @@ -- Commonwealth Project Ticketing Database Schema --- Access via: python3 db/connectors/sqlite_connector.py <command> +-- Access via: python3 tooling/db/sqlite_connector.py <command> -- DO NOT use sqlite3 CLI (crashes in Claude Code due to std::bad_alloc bug) PRAGMA journal_mode=WAL; @@ -64,7 +64,7 @@ CREATE INDEX IF NOT EXISTS idx_history_ticket ON ticket_history(ticket_id); -- --------------------------------------------------------------------------- -- Decision Sync Tables --- Populated by: python3 db/connectors/decisions_sync.py +-- Populated by: python3 tooling/db/decisions_sync.py -- Source: decisions/*.md domain files -- --------------------------------------------------------------------------- diff --git a/decisions/README.md b/decisions/README.md index ecbaad7fa..d589e5eec 100644 --- a/decisions/README.md +++ b/decisions/README.md @@ -24,7 +24,7 @@ The SQLite database contains a `decisions` table synced from these files. Common ```bash # All active architecture decisions -db/connectors/sqlite-query "SELECT id, title FROM decisions WHERE domain='architecture' AND status='active'" +tooling/db/sqlite-query "SELECT id, title FROM decisions WHERE domain='architecture' AND status='active'" # Decisions without implementing tickets make decisions-orphan diff --git a/docs/DEVOPS.md b/docs/DEVOPS.md index 1e3659119..ef4aeb7dd 100644 --- a/docs/DEVOPS.md +++ b/docs/DEVOPS.md @@ -269,17 +269,17 @@ Key components: Use wrapper scripts: ```bash -db/connectors/sqlite-query "SELECT * FROM tickets WHERE status='open'" -db/connectors/sqlite-exec "UPDATE tickets SET status='done' WHERE id=1" +tooling/db/sqlite-query "SELECT * FROM tickets WHERE status='open'" +tooling/db/sqlite-exec "UPDATE tickets SET status='done' WHERE id=1" ``` ## Qdrant / Document Search ```bash -db/connectors/qdrant-search "asymmetric information design" -db/connectors/qdrant-index docs/briefings/tyre.md -db/connectors/qdrant-health -db/connectors/qdrant-count +tooling/db/qdrant-search "asymmetric information design" +tooling/db/qdrant-index docs/briefings/tyre.md +tooling/db/qdrant-health +tooling/db/qdrant-count ``` ## Decisions System diff --git a/docs/sprints/sprint-21/client.md b/docs/sprints/sprint-21/client.md index 591e7eebf..fb5d7f688 100644 --- a/docs/sprints/sprint-21/client.md +++ b/docs/sprints/sprint-21/client.md @@ -12,7 +12,7 @@ | #257 | Save/load game flow | — (#256 done) | | #561 | Housekeeping: move debug_overlay.gd to ui/ directory | — | -Use `db/connectors/ticket show <id>` for full details on any ticket. +Use `tooling/db/ticket show <id>` for full details on any ticket. ## Key Decisions diff --git a/docs/sprints/sprint-21/server.md b/docs/sprints/sprint-21/server.md index a8b7c9da2..a030f1b07 100644 --- a/docs/sprints/sprint-21/server.md +++ b/docs/sprints/sprint-21/server.md @@ -17,7 +17,7 @@ | #85 | Error handling & recovery | — | | #246 | Basic environmental interaction | — | -Use `db/connectors/ticket show <id>` for full details on any ticket. +Use `tooling/db/ticket show <id>` for full details on any ticket. ## Key Decisions diff --git a/docs/sprints/sprint-21/visual.md b/docs/sprints/sprint-21/visual.md index 8a75bf53e..388d1291a 100644 --- a/docs/sprints/sprint-21/visual.md +++ b/docs/sprints/sprint-21/visual.md @@ -11,7 +11,7 @@ |---|-------|------------| | #564 | Fog shader too opaque — tune alpha for semi-transparent layers per D-059 | — | -Use `db/connectors/ticket show <id>` for full details. +Use `tooling/db/ticket show <id>` for full details. ## Key Decisions diff --git a/tooling/check-decision-ids b/tooling/check-decision-ids index 14c59c2f3..298d011a8 100755 --- a/tooling/check-decision-ids +++ b/tooling/check-decision-ids @@ -7,7 +7,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" REPO_ROOT="$(dirname "$SCRIPT_DIR")" # Use the decisions_sync.py check-dupes command -RESULT=$(python3 "$REPO_ROOT/db/connectors/decisions_sync.py" check-dupes 2>&1) +RESULT=$(python3 "$REPO_ROOT/tooling/db/decisions_sync.py" check-dupes 2>&1) # Parse the JSON result DUPES=$(echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('duplicates',0))" 2>/dev/null || echo "0") diff --git a/db/connectors/audio-batch b/tooling/db/audio-batch similarity index 100% rename from db/connectors/audio-batch rename to tooling/db/audio-batch diff --git a/db/connectors/audio-generate b/tooling/db/audio-generate similarity index 100% rename from db/connectors/audio-generate rename to tooling/db/audio-generate diff --git a/db/connectors/audio-health b/tooling/db/audio-health similarity index 100% rename from db/connectors/audio-health rename to tooling/db/audio-health diff --git a/db/connectors/audio-post b/tooling/db/audio-post similarity index 100% rename from db/connectors/audio-post rename to tooling/db/audio-post diff --git a/db/connectors/audio_batch.py b/tooling/db/audio_batch.py similarity index 100% rename from db/connectors/audio_batch.py rename to tooling/db/audio_batch.py diff --git a/db/connectors/audio_connector.py b/tooling/db/audio_connector.py similarity index 100% rename from db/connectors/audio_connector.py rename to tooling/db/audio_connector.py diff --git a/db/connectors/audio_post.py b/tooling/db/audio_post.py similarity index 100% rename from db/connectors/audio_post.py rename to tooling/db/audio_post.py diff --git a/db/connectors/config.json b/tooling/db/config.json similarity index 100% rename from db/connectors/config.json rename to tooling/db/config.json diff --git a/db/connectors/decision b/tooling/db/decision similarity index 100% rename from db/connectors/decision rename to tooling/db/decision diff --git a/db/connectors/decisions-sync b/tooling/db/decisions-sync similarity index 100% rename from db/connectors/decisions-sync rename to tooling/db/decisions-sync diff --git a/db/connectors/decisions_sync.py b/tooling/db/decisions_sync.py similarity index 98% rename from db/connectors/decisions_sync.py rename to tooling/db/decisions_sync.py index d03d304b4..1e24bc23c 100644 --- a/db/connectors/decisions_sync.py +++ b/tooling/db/decisions_sync.py @@ -23,11 +23,11 @@ from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent CONFIG_PATH = SCRIPT_DIR / "config.json" -SCHEMA_PATH = SCRIPT_DIR.parent / "schema.sql" -WORKTREE_ROOT = SCRIPT_DIR.parent.parent +WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() +SCHEMA_PATH = WORKTREE_ROOT / "db" / "schema.sql" DECISIONS_DIR = WORKTREE_ROOT / "decisions" -# Shared database lives in the parent of all worktrees (three levels up from db/connectors/). -DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve() +# Shared database lives in the parent of all worktrees (three levels up from tooling/db/). +DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() # --------------------------------------------------------------------------- # Config / DB (same pattern as sqlite_connector.py) diff --git a/db/connectors/qdrant-count b/tooling/db/qdrant-count similarity index 100% rename from db/connectors/qdrant-count rename to tooling/db/qdrant-count diff --git a/db/connectors/qdrant-health b/tooling/db/qdrant-health similarity index 100% rename from db/connectors/qdrant-health rename to tooling/db/qdrant-health diff --git a/db/connectors/qdrant-index b/tooling/db/qdrant-index similarity index 100% rename from db/connectors/qdrant-index rename to tooling/db/qdrant-index diff --git a/db/connectors/qdrant-search b/tooling/db/qdrant-search similarity index 100% rename from db/connectors/qdrant-search rename to tooling/db/qdrant-search diff --git a/db/connectors/qdrant_connector.py b/tooling/db/qdrant_connector.py similarity index 100% rename from db/connectors/qdrant_connector.py rename to tooling/db/qdrant_connector.py diff --git a/db/connectors/sprint b/tooling/db/sprint similarity index 98% rename from db/connectors/sprint rename to tooling/db/sprint index ff91da9ae..0eae01517 100755 --- a/db/connectors/sprint +++ b/tooling/db/sprint @@ -23,13 +23,14 @@ from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent TICKET_CLI = str(SCRIPT_DIR / "ticket") -DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve() -PROJECT_ROOT = (SCRIPT_DIR / ".." / "..").resolve() +WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() +DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() +PROJECT_ROOT = WORKTREE_ROOT REMINDER = """--- Reminder: Keep ticket status up to date after finishing work. - db/connectors/ticket status <id> in_progress (when starting) - db/connectors/ticket status <id> done (when finished)""" + tooling/db/ticket status <id> in_progress (when starting) + tooling/db/ticket status <id> done (when finished)""" def run_ticket(*args): @@ -559,19 +560,19 @@ def cmd_sweep(args): issues.append({ "type": "unassigned_in_progress", "detail": f"#{t['id']} unassigned {t['status']}", - "fix": f"db/connectors/ticket assign {t['id']} <agent>", + "fix": f"tooling/db/ticket assign {t['id']} <agent>", }) if t["status"] == "backlog" and sprint["status"] == "active" and t["id"] not in blocked_by_map: issues.append({ "type": "stale_backlog", "detail": f"#{t['id']} stale backlog", - "fix": f"db/connectors/ticket status {t['id']} in_progress", + "fix": f"tooling/db/ticket status {t['id']} in_progress", }) if t["status"] == "done" and t.get("assigned_to"): issues.append({ "type": "assigned_but_done", "detail": f"#{t['id']} done, still assigned", - "fix": f"db/connectors/ticket unassign {t['id']}", + "fix": f"tooling/db/ticket unassign {t['id']}", }) # Progress diff --git a/db/connectors/sqlite-exec b/tooling/db/sqlite-exec similarity index 100% rename from db/connectors/sqlite-exec rename to tooling/db/sqlite-exec diff --git a/db/connectors/sqlite-init b/tooling/db/sqlite-init similarity index 100% rename from db/connectors/sqlite-init rename to tooling/db/sqlite-init diff --git a/db/connectors/sqlite-query b/tooling/db/sqlite-query similarity index 100% rename from db/connectors/sqlite-query rename to tooling/db/sqlite-query diff --git a/db/connectors/sqlite-seed b/tooling/db/sqlite-seed similarity index 100% rename from db/connectors/sqlite-seed rename to tooling/db/sqlite-seed diff --git a/db/connectors/sqlite_connector.py b/tooling/db/sqlite_connector.py similarity index 97% rename from db/connectors/sqlite_connector.py rename to tooling/db/sqlite_connector.py index d6f609f25..e943bb379 100755 --- a/db/connectors/sqlite_connector.py +++ b/tooling/db/sqlite_connector.py @@ -22,9 +22,10 @@ from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent CONFIG_PATH = SCRIPT_DIR / "config.json" -SCHEMA_PATH = SCRIPT_DIR.parent / "schema.sql" -# Shared database lives in the parent of all worktrees (three levels up from db/connectors/). -DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve() +WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() +SCHEMA_PATH = WORKTREE_ROOT / "db" / "schema.sql" +# Shared database lives in the parent of all worktrees (three levels up from tooling/db/). +DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() def load_config(): diff --git a/db/connectors/ticket b/tooling/db/ticket similarity index 99% rename from db/connectors/ticket rename to tooling/db/ticket index f9797b868..04028e02f 100755 --- a/db/connectors/ticket +++ b/tooling/db/ticket @@ -30,8 +30,9 @@ from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent CONFIG_PATH = SCRIPT_DIR / "config.json" -# Shared database lives in the parent of all worktrees (three levels up from db/connectors/). -DB_PATH = (SCRIPT_DIR / ".." / ".." / ".." / "settledreach.db").resolve() +WORKTREE_ROOT = (SCRIPT_DIR / ".." / "..").resolve() +# Shared database lives in the parent of all worktrees (three levels up from tooling/db/). +DB_PATH = (WORKTREE_ROOT / ".." / "settledreach.db").resolve() def load_config(): diff --git a/tooling/synth_ui_sounds.py b/tooling/synth_ui_sounds.py index 361bcab1f..80f0d1beb 100644 --- a/tooling/synth_ui_sounds.py +++ b/tooling/synth_ui_sounds.py @@ -203,4 +203,4 @@ if __name__ == "__main__": monologue_chime_urgent() print() - print("Done. Convert with: db/connectors/audio-post convert <file.wav>") + print("Done. Convert with: tooling/db/audio-post convert <file.wav>")