diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md new file mode 100644 index 0000000..b98d354 --- /dev/null +++ b/.claude/CLAUDE.md @@ -0,0 +1,21 @@ +# dbdeployer-maintainer + +## Project Identity +dbdeployer is a Go CLI for local MySQL, PostgreSQL, and ProxySQL sandboxes. + +## Working Mode +- Follow TDD and keep changes minimal. +- Do not overwrite or revert work you did not make. +- Treat high-risk work under `cmd/`, `providers/`, `sandbox/`, `ops/`, `.github/workflows/`, `test/`, and `docs/` as correctness-sensitive. +- Use the project instructions/workflows `/dbdeployer-maintainer`, `/db-correctness-review`, `/verification-matrix`, and `/docs-reference-sync` when those assets are present in this setup. + +## Verification Entry Points +- `go test ./...` +- `./test/go-unit-tests.sh` +- `./test/claude-agent-tests.sh` +- `.github/workflows/integration_tests.yml` +- `.github/workflows/proxysql_integration_tests.yml` + +## Completion Contract +Final responses must include the sections `Changed`, `Verification`, `Edge Cases`, and `Docs Updated`. +Do not claim completion unless the required checks have been run and their results are known. diff --git a/.claude/hooks/block-destructive-commands.sh b/.claude/hooks/block-destructive-commands.sh new file mode 100755 index 0000000..7175eb1 --- /dev/null +++ b/.claude/hooks/block-destructive-commands.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# DBDeployer - The MySQL Sandbox +# Copyright © 2006-2020 Giuseppe Maxia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +input="$(cat)" +command="$(printf '%s' "$input" | jq -r '.tool_input.command // ""')" +normalized_command="$(printf '%s' "$command" | sed -E 's/^[[:space:]]+//')" + +blocked_patterns=( + "git reset --hard" + "git checkout --" + "git clean -fd" + "git clean -ffd" +) + +while [[ "$normalized_command" =~ ^[A-Za-z_][A-Za-z0-9_]*=[^[:space:]]+[[:space:]]+ ]]; do + normalized_command="${normalized_command#${BASH_REMATCH[0]}}" + normalized_command="$(printf '%s' "$normalized_command" | sed -E 's/^[[:space:]]+//')" +done + +for pattern in "${blocked_patterns[@]}"; do + if [[ "$normalized_command" == "$pattern"* ]]; then + jq -n '{ + hookSpecificOutput: { + hookEventName: "PreToolUse", + permissionDecision: "deny", + permissionDecisionReason: "Destructive git command blocked in dbdeployer. Use a non-destructive alternative." + } + }' + exit 0 + fi +done + +exit 0 diff --git a/.claude/hooks/record-verification-command.sh b/.claude/hooks/record-verification-command.sh new file mode 100755 index 0000000..e0f1d5f --- /dev/null +++ b/.claude/hooks/record-verification-command.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# DBDeployer - The MySQL Sandbox +# Copyright © 2006-2020 Giuseppe Maxia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +input="$(cat)" +session_id="$(printf '%s' "$input" | jq -r '.session_id')" +cwd="$(printf '%s' "$input" | jq -r '.cwd')" +command="$(printf '%s' "$input" | jq -r '.tool_input.command // ""')" +project_dir="${CLAUDE_PROJECT_DIR:-$cwd}" +log_path="${CLAUDE_AGENT_VERIFICATION_LOG:-$project_dir/.claude/state/verification-log.jsonl}" +trimmed_command="$(printf '%s' "$command" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')" + +case "$trimmed_command" in + "go test ./..."|"go test ./... "*|\ + "./test/go-unit-tests.sh"|"./test/go-unit-tests.sh "*|\ + "./test/claude-agent-tests.sh"|"./test/claude-agent-tests.sh "*|\ + "./test/functional-test.sh"|"./test/functional-test.sh "*|\ + "./test/docker-test.sh"|"./test/docker-test.sh "*|\ + "./test/proxysql-integration-tests.sh"|"./test/proxysql-integration-tests.sh "*|\ + "./scripts/build.sh"|"./scripts/build.sh "*) + mkdir -p "$(dirname "$log_path")" + jq -cn \ + --arg session_id "$session_id" \ + --arg cwd "$cwd" \ + --arg command "$trimmed_command" \ + --arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + '{session_id: $session_id, cwd: $cwd, command: $command, timestamp: $timestamp}' >> "$log_path" + ;; +esac + +exit 0 diff --git a/.claude/hooks/stop-completion-gate.sh b/.claude/hooks/stop-completion-gate.sh new file mode 100755 index 0000000..98ea283 --- /dev/null +++ b/.claude/hooks/stop-completion-gate.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash +# DBDeployer - The MySQL Sandbox +# Copyright © 2006-2020 Giuseppe Maxia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +input="$(cat)" +session_id="$(printf '%s' "$input" | jq -r '.session_id')" +cwd="$(printf '%s' "$input" | jq -r '.cwd')" +message="$(printf '%s' "$input" | jq -r '.last_assistant_message // ""')" +stop_hook_active="$(printf '%s' "$input" | jq -r '.stop_hook_active // false')" +project_dir="${CLAUDE_PROJECT_DIR:-$cwd}" +log_path="${CLAUDE_AGENT_VERIFICATION_LOG:-$project_dir/.claude/state/verification-log.jsonl}" +changed_files="${CLAUDE_AGENT_CHANGED_FILES:-}" + +requires_claude_verification=0 +requires_go_verification=0 +requires_docs=0 +docs_updated=0 +saw_changed_file=0 + +classify_changed_file() { + local file="$1" + + [[ -z "$file" ]] && return 0 + + saw_changed_file=1 + + if [[ "$file" =~ ^(\.claude/|test/claude-agent/|test/claude-agent-tests\.sh$|tools/claude-skills/db-core-expertise/|scripts/install_claude_db_skills\.sh$) ]]; then + requires_claude_verification=1 + elif [[ "$file" =~ ^(common/|cmd/|ops/|providers/|sandbox/|test/|\.github/workflows/) ]]; then + requires_go_verification=1 + fi + + if [[ "$file" =~ ^(cmd/|providers/|sandbox/|ops/|common/) ]]; then + requires_docs=1 + fi + + if [[ "$file" =~ ^(docs/|README\.md|CONTRIBUTING\.md|\.claude/CLAUDE\.md|\.claude/rules/) ]]; then + docs_updated=1 + fi +} + +has_logged_command() { + local expected_command="$1" + + [[ -f "$log_path" ]] || return 1 + + jq -s -e \ + --arg session_id "$session_id" \ + --arg expected_command "$expected_command" \ + ' + map( + select( + .session_id == $session_id and ( + .command == $expected_command or + (.command | startswith($expected_command + " ")) + ) + ) + ) | length > 0 + ' "$log_path" >/dev/null 2>&1 +} + +if [[ "$stop_hook_active" == "true" ]]; then + exit 0 +fi + +if [[ -n "$changed_files" ]]; then + while IFS= read -r file; do + classify_changed_file "$file" + done <<< "$changed_files" +else + while IFS= read -r file; do + classify_changed_file "$file" + done < <(git -C "$project_dir" diff --name-only -M HEAD --) + + while IFS= read -r -d '' file; do + classify_changed_file "$file" + done < <(git -C "$project_dir" ls-files --others --exclude-standard -z) +fi + +if [[ "$saw_changed_file" -eq 0 ]]; then + exit 0 +fi + +missing_verification=() + +if [[ "$requires_claude_verification" -eq 1 ]] && ! has_logged_command "./test/claude-agent-tests.sh"; then + missing_verification+=("./test/claude-agent-tests.sh") +fi + +if [[ "$requires_go_verification" -eq 1 ]] && ! has_logged_command "go test ./..." && ! has_logged_command "./test/go-unit-tests.sh"; then + missing_verification+=("go test ./... or ./test/go-unit-tests.sh") +fi + +if [[ "${#missing_verification[@]}" -gt 0 ]]; then + reason_suffix="${missing_verification[*]}" + jq -n --arg reason "Run the required verification before finishing. Missing a successful command for: $reason_suffix." '{decision: "block", reason: $reason}' + exit 0 +fi + +if [[ "$requires_docs" -eq 1 && "$docs_updated" -eq 0 ]]; then + jq -n --arg reason "Behavior-sensitive files changed without a docs update. Add the relevant docs update before finishing." '{decision: "block", reason: $reason}' + exit 0 +fi + +for section in "Changed" "Verification" "Edge Cases" "Docs Updated"; do + if [[ "$message" != *"$section"* ]]; then + jq -n --arg reason "Final response must include '$section' so completion is auditable." '{decision: "block", reason: $reason}' + exit 0 + fi +done + +exit 0 diff --git a/.claude/rules/provider-surfaces.md b/.claude/rules/provider-surfaces.md new file mode 100644 index 0000000..a696c78 --- /dev/null +++ b/.claude/rules/provider-surfaces.md @@ -0,0 +1,18 @@ +--- +paths: + - cmd/**/* + - providers/**/* + - sandbox/**/* + - ops/**/* + - docs/**/* + - .github/workflows/**/* +--- + +## Provider Surface Guidance +Review MySQL, PostgreSQL, and ProxySQL behavior as correctness-sensitive. + +Check for version differences, package layout assumptions, startup ordering, auth defaults, port allocation, and replication semantics before changing behavior. + +For ProxySQL work, verify the admin port and MySQL port pairing and make sure configuration changes preserve the intended routing behavior. + +When behavior changes, update the relevant docs in `docs/`, `README.md`, and `CONTRIBUTING.md` alongside the code. diff --git a/.claude/rules/testing-and-completion.md b/.claude/rules/testing-and-completion.md new file mode 100644 index 0000000..ee5ddea --- /dev/null +++ b/.claude/rules/testing-and-completion.md @@ -0,0 +1,21 @@ +## Verification-Sensitive Paths +Treat these paths as verification-sensitive: +- `cmd/` +- `providers/` +- `sandbox/` +- `ops/` +- `common/` +- `test/` +- `.github/workflows/` +- `.claude/` +- `tools/claude-skills/db-core-expertise/` +- `scripts/install_claude_db_skills.sh` + +## Required Checks +- Changes under `.claude/**`, `tools/claude-skills/db-core-expertise/**`, and `scripts/install_claude_db_skills.sh` must be checked with `./test/claude-agent-tests.sh`. +- Go code changes must be checked with either `go test ./...` or `./test/go-unit-tests.sh`. +- Workflow-related changes must stay aligned with the matching jobs in `.github/workflows/integration_tests.yml` and `.github/workflows/proxysql_integration_tests.yml`. + +## Completion Language +Final responses must include the sections `Changed`, `Verification`, `Edge Cases`, and `Docs Updated`. +If required checks cannot run, the task must not be described as complete. diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..eb9101d --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,37 @@ +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "if": "Bash(*git *)", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-destructive-commands.sh" + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/record-verification-command.sh" + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-completion-gate.sh" + } + ] + } + ] + } +} diff --git a/.claude/skills/db-correctness-review/SKILL.md b/.claude/skills/db-correctness-review/SKILL.md new file mode 100644 index 0000000..7756baa --- /dev/null +++ b/.claude/skills/db-correctness-review/SKILL.md @@ -0,0 +1,23 @@ +--- +name: db-correctness-review +description: Adversarial MySQL/PostgreSQL/ProxySQL review for dbdeployer changes. +disable-model-invocation: true +--- + +# db correctness review + +Invoke `/db-core-expertise` first if it is available, then review the change for database correctness. + +## Checklist + +- Database semantics +- Lifecycle behavior +- Packaging and environment assumptions +- Topology and routing behavior +- Operator edge cases + +## Findings format + +- Correctness Risks +- Edge Cases Checked +- Recommended Follow-up diff --git a/.claude/skills/dbdeployer-maintainer/SKILL.md b/.claude/skills/dbdeployer-maintainer/SKILL.md new file mode 100644 index 0000000..24f8b20 --- /dev/null +++ b/.claude/skills/dbdeployer-maintainer/SKILL.md @@ -0,0 +1,26 @@ +--- +name: dbdeployer-maintainer +description: Primary maintainer workflow for dbdeployer; use for non-trivial feature work, bug fixes, provider changes, verification tasks, or docs sync. +--- + +# dbdeployer maintainer workflow + +Use this when the task can change behavior, provider support, verification, or reference docs. + +## Sequence + +1. Frame the task and restate the expected change surface. +2. Implement or investigate the requested change. +3. If `/db-core-expertise` is available, invoke it for MySQL, PostgreSQL, or ProxySQL questions before concluding. +4. If database behavior may have changed, invoke `/db-correctness-review`. +5. If behavior, flags, support statements, or examples changed, invoke `/docs-reference-sync`. +6. Before stopping, invoke `/verification-matrix` and use its strongest applicable checks. + +## Final response + +Close with these sections: + +- Changed +- Verification +- Edge Cases +- Docs Updated diff --git a/.claude/skills/docs-reference-sync/SKILL.md b/.claude/skills/docs-reference-sync/SKILL.md new file mode 100644 index 0000000..f72a098 --- /dev/null +++ b/.claude/skills/docs-reference-sync/SKILL.md @@ -0,0 +1,22 @@ +--- +name: docs-reference-sync +description: Syncs docs and reference material after dbdeployer behavior, flags, support statements, or examples change. +disable-model-invocation: true +--- + +# docs reference sync + +## Workflow + +1. List the changed doc surfaces, especially `docs/`, `README.md`, and `CONTRIBUTING.md`. +2. Update the smallest truthful set of files. +3. Prefer concrete commands and caveats over broad prose. +4. State limitations directly. + +## Supplemental Output + +These fields are supplemental only. They must not replace the required final response sections `Changed`, `Verification`, `Edge Cases`, and `Docs Updated` defined in `.claude/CLAUDE.md` and enforced by `test/claude-agent-tests.sh`. + +- Docs To Update +- Files Updated +- Open Caveats diff --git a/.claude/skills/verification-matrix/SKILL.md b/.claude/skills/verification-matrix/SKILL.md new file mode 100644 index 0000000..b16fbb6 --- /dev/null +++ b/.claude/skills/verification-matrix/SKILL.md @@ -0,0 +1,27 @@ +--- +name: verification-matrix +description: Chooses the strongest dbdeployer verification path for changed surfaces and environment. +disable-model-invocation: true +--- + +# verification matrix + +Map the changed surface to the strongest runnable checks. + +Treat `.claude/**`, `test/`, and `.github/workflows/` as verification-sensitive surfaces, not lightweight documentation-only edits. + +## Local Checks + +- `common/`, `cmd/`, `ops/`, `providers/`, `sandbox/`, or `test/` changes: run `go test ./...` or `./test/go-unit-tests.sh`. +- `.claude/**`, `test/claude-agent/**`, `test/claude-agent-tests.sh`, `tools/claude-skills/db-core-expertise/**`, or `scripts/install_claude_db_skills.sh` changes: run `./test/claude-agent-tests.sh`. + +## Linux Runner Checks + +- MySQL download and deploy behavior: verify against `.github/workflows/integration_tests.yml`. +- PostgreSQL provider behavior: verify against the PostgreSQL job in `.github/workflows/integration_tests.yml`. +- ProxySQL behavior: verify against `.github/workflows/proxysql_integration_tests.yml`. +- `.github/workflows/` changes should be cross-checked against the matching runner jobs before merging. + +## Unverified Risk + +- State what remains unverified if runner coverage is unavailable or too expensive. diff --git a/.gitignore b/.gitignore index 0dce521..da3afed 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ ts/testdata/ website/node_modules/ website/dist/ website/.astro/ +.claude/state/ +.claude/settings.local.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 552bbaa..2b2f1fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,14 @@ The following guidelines want to help and simplify the process of contributing t go build -o dbdeployer . ``` +## Claude Code Maintainer Workflow + +If you use Claude Code for maintenance work in this repo, read `docs/coding/claude-code-agent.md` first. It documents the repo-local `.claude/` skills, hook behavior, and required smoke tests. + +- The repo-local `.claude/` workflow is authoritative for Claude Code tasks in this repository. +- Run `./test/claude-agent-tests.sh` when you edit `.claude/`, `docs/coding/claude-code-agent.md`, `scripts/install_claude_db_skills.sh`, or `tools/claude-skills/db-core-expertise/`. +- If you update `tools/claude-skills/db-core-expertise/`, rerun `./scripts/install_claude_db_skills.sh` and `~/.claude/skills/db-core-expertise/scripts/smoke-test.sh` so the installed reusable skill stays in sync. + ## Principles 1. Contributions should follow the classic GitHub workflow, i.e. forking, cloning, then submitting a Pull Request (PR) diff --git a/docs/coding/claude-code-agent.md b/docs/coding/claude-code-agent.md new file mode 100644 index 0000000..7bb4b3f --- /dev/null +++ b/docs/coding/claude-code-agent.md @@ -0,0 +1,75 @@ +# Claude Code Maintainer Workflow + +This repo includes a project-local Claude Code operating layer under `.claude/`. + +## Project assets + +- `.claude/CLAUDE.md` defines the shared maintainer workflow for this repo. +- `.claude/rules/` keeps testing and provider-sensitive guidance concise. +- `.claude/skills/` provides the project workflows: + - `/dbdeployer-maintainer` + - `/db-correctness-review` + - `/verification-matrix` + - `/docs-reference-sync` +- `.claude/hooks/` enforces destructive-command blocking, verification tracking, and completion gates. + +## Local verification + +Run the project-local Claude asset smoke tests with: + +```bash +./test/claude-agent-tests.sh +``` + +These tests validate the repo-local Claude files, hook behavior, and completion policy. + +## Troubleshooting + +- If Claude blocks before a shell command runs, the pre-tool hook likely denied a destructive git command. Use a non-destructive alternative instead of trying to bypass the hook. +- If Claude blocks at completion time, read the reported missing verification or docs requirement, run the exact command it names, and include the required `Changed`, `Verification`, `Edge Cases`, and `Docs Updated` sections in the final response. +- Verification history is stored in `.claude/state/verification-log.jsonl`. If the log becomes stale during local experimentation, delete `.claude/state/` and rerun the relevant verification commands. +- If you change `tools/claude-skills/db-core-expertise/` or `scripts/install_claude_db_skills.sh`, rerun the installer and the installed smoke test so the user-level copy stays aligned with the repo. + +## Expected maintainer flow + +1. Start non-trivial tasks with `/dbdeployer-maintainer`. +2. Use `/db-correctness-review` when behavior, packaging, replication, or ProxySQL wiring may have changed. +3. Use `/verification-matrix` before stopping so the strongest feasible checks run. +4. Use `/docs-reference-sync` when behavior, flags, support statements, or examples change. + +## Reusable database expertise + +Install the reusable MySQL/PostgreSQL/ProxySQL reference skill with: + +```bash +./scripts/install_claude_db_skills.sh +~/.claude/skills/db-core-expertise/scripts/smoke-test.sh +``` + +The installed user-level skill is named `/db-core-expertise`. Use it when the task depends on DB semantics, packaging assumptions, replication edge cases, or live upstream verification. + +## Repo-local vs reusable + +- Update `.claude/`, `.claude/rules/`, `.claude/hooks/`, or this guide when the change is specific to `dbdeployer` workflow, completion policy, verification gates, or maintainer behavior inside this repo. +- Update `tools/claude-skills/db-core-expertise/` when the change is generic DB knowledge that should remain reusable across repositories, such as MySQL/PostgreSQL/ProxySQL semantics, verification heuristics, or documentation style. +- Keep repo-specific policy out of the reusable skill. If you change the reusable layer, rerun the installer with `./scripts/install_claude_db_skills.sh` and then run `~/.claude/skills/db-core-expertise/scripts/smoke-test.sh` so the installed copy matches the repo. + +## Task recipes + +- Provider or CLI behavior change: + Start with `/dbdeployer-maintainer`, use `/db-correctness-review` before finishing, run `go test ./...` or `./test/go-unit-tests.sh`, and update the relevant docs if user-visible behavior changed. +- Docs-only or reference-only change: + Update the smallest truthful docs surface, use `/docs-reference-sync`, and avoid claiming behavior changes unless you also verified the underlying code path. +- Claude workflow or reusable skill change: + Run `./test/claude-agent-tests.sh`. If the change touched `tools/claude-skills/db-core-expertise/` or the installer, rerun the installer and the installed smoke test before finishing. + +## Completion requirements + +Final responses should include: + +- `Changed` +- `Verification` +- `Edge Cases` +- `Docs Updated` + +If a relevant check cannot run locally, report the exact Linux-runner gap instead of claiming full completion. diff --git a/docs/superpowers/plans/2026-03-31-dbdeployer-specialized-agent-implementation.md b/docs/superpowers/plans/2026-03-31-dbdeployer-specialized-agent-implementation.md new file mode 100644 index 0000000..3c974d2 --- /dev/null +++ b/docs/superpowers/plans/2026-03-31-dbdeployer-specialized-agent-implementation.md @@ -0,0 +1,1374 @@ +# dbdeployer Specialized Claude Code Agent Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Build a specialized Claude Code operating layer for `dbdeployer` that enforces strict verification and DB-correctness review, plus installable reusable MySQL/PostgreSQL/ProxySQL expertise for future projects. + +**Architecture:** Keep shared project behavior in `~/dbdeployer/.claude/` using a concise project `CLAUDE.md`, path-scoped rules, project skills, and hook scripts backed by shell tests. Keep reusable database knowledge installable into `~/.claude/skills/` from versioned templates in the repo so the first implementation is testable and repeatable before extracting it to a dedicated knowledge repo later. + +**Tech Stack:** Markdown, JSON, Bash, `jq`, Claude Code `CLAUDE.md`/rules/skills/hooks, existing `dbdeployer` shell test conventions. + +--- + +## File Structure + +- Create: `.claude/CLAUDE.md` + - Main project memory for Claude Code in this repo. +- Create: `.claude/rules/testing-and-completion.md` + - Always-on verification and completion policy. +- Create: `.claude/rules/provider-surfaces.md` + - Path-scoped guidance for provider, CLI, topology, docs, and workflow changes. +- Create: `.claude/skills/dbdeployer-maintainer/SKILL.md` + - Main project workflow skill with enforced phases. +- Create: `.claude/skills/db-correctness-review/SKILL.md` + - Adversarial provider/DB behavior review workflow. +- Create: `.claude/skills/verification-matrix/SKILL.md` + - Maps changed surfaces to required local and Linux-runner checks. +- Create: `.claude/skills/docs-reference-sync/SKILL.md` + - Forces docs/manual updates when behavior changes. +- Create: `.claude/settings.json` + - Project hook registration. +- Create: `.claude/hooks/block-destructive-commands.sh` + - Blocks destructive git commands. +- Create: `.claude/hooks/record-verification-command.sh` + - Records successful verification commands for the current session. +- Create: `.claude/hooks/stop-completion-gate.sh` + - Blocks completion when verification or docs sync is missing. +- Modify: `.gitignore` + - Ignore local Claude state and local-only settings. +- Create: `test/claude-agent-tests.sh` + - Repo-local smoke tests for `.claude/` assets and hooks. +- Create: `test/claude-agent/fixtures/pretool-git-reset-hard.json` + - Fixture for destructive-command denial. +- Create: `test/claude-agent/fixtures/pretool-git-status.json` + - Fixture for safe git command. +- Create: `test/claude-agent/fixtures/posttool-go-test.json` + - Fixture for verification-command recording. +- Create: `test/claude-agent/fixtures/posttool-echo.json` + - Fixture for non-verification bash command. +- Create: `test/claude-agent/fixtures/stop-sections-missing.json` + - Fixture for missing completion sections. +- Create: `test/claude-agent/fixtures/stop-sections-complete.json` + - Fixture for valid completion report. +- Create: `docs/coding/claude-code-agent.md` + - Maintainer guide for the agent system. +- Modify: `CONTRIBUTING.md` + - Link maintainers to the Claude Code workflow guide. +- Create: `tools/claude-skills/db-core-expertise/SKILL.md` + - Reusable user-level DB expertise skill template. +- Create: `tools/claude-skills/db-core-expertise/mysql.md` + - MySQL-specific reference notes. +- Create: `tools/claude-skills/db-core-expertise/postgresql.md` + - PostgreSQL-specific reference notes. +- Create: `tools/claude-skills/db-core-expertise/proxysql.md` + - ProxySQL-specific reference notes. +- Create: `tools/claude-skills/db-core-expertise/verification-playbook.md` + - Reusable validation heuristics. +- Create: `tools/claude-skills/db-core-expertise/docs-style.md` + - Documentation/reference writing guidance. +- Create: `tools/claude-skills/db-core-expertise/scripts/smoke-test.sh` + - Verifies the reusable skill package is structurally complete. +- Create: `scripts/install_claude_db_skills.sh` + - Copies the reusable skill package into `~/.claude/skills/db-core-expertise`. + +### Task 1: Add Project Claude Memory And Rules + +**Files:** +- Create: `.claude/CLAUDE.md` +- Create: `.claude/rules/testing-and-completion.md` +- Create: `.claude/rules/provider-surfaces.md` +- Create: `test/claude-agent-tests.sh` + +- [ ] **Step 1: Write the failing test** + +```bash +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +require_file() { + local file="$1" + local label="$2" + if [[ ! -f "$ROOT/$file" ]]; then + echo "FAIL: $label ($file missing)" >&2 + exit 1 + fi +} + +require_contains() { + local file="$1" + local needle="$2" + local label="$3" + if ! grep -Fq "$needle" "$ROOT/$file"; then + echo "FAIL: $label ($needle missing from $file)" >&2 + exit 1 + fi +} + +require_file ".claude/CLAUDE.md" "project CLAUDE.md exists" +require_file ".claude/rules/testing-and-completion.md" "testing rule exists" +require_file ".claude/rules/provider-surfaces.md" "provider rule exists" + +require_contains ".claude/CLAUDE.md" "dbdeployer-maintainer" "project memory names the maintainer workflow" +require_contains ".claude/rules/testing-and-completion.md" "./test/go-unit-tests.sh" "testing rule references Go unit tests" +require_contains ".claude/rules/provider-surfaces.md" "ProxySQL" "provider rule covers ProxySQL" + +echo "PASS: project Claude memory and rules" +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: FAIL because `.claude/CLAUDE.md` and the rules files do not exist yet. + +- [ ] **Step 3: Write minimal implementation** + +`.claude/CLAUDE.md` + +```md +# dbdeployer Claude Code Instructions + +## Project identity + +- `dbdeployer` is a Go CLI for local MySQL, PostgreSQL, and ProxySQL sandboxes. +- The highest-risk work happens under `cmd/`, `providers/`, `sandbox/`, `ops/`, `.github/workflows/`, `test/`, and `docs/`. + +## Working mode + +- For non-trivial work, use `/dbdeployer-maintainer`. +- If the task touches DB behavior, provider code, replication, packaging, or ProxySQL wiring, invoke `/db-correctness-review` before finishing. +- If the task changes behavior or tests, invoke `/verification-matrix` before finishing. +- If behavior, flags, support statements, or examples change, invoke `/docs-reference-sync`. + +## Verification entrypoints + +- Fast checks: + - `go test ./...` + - `./test/go-unit-tests.sh` + - `./test/claude-agent-tests.sh` +- Linux-runner references: + - `.github/workflows/integration_tests.yml` + - `.github/workflows/proxysql_integration_tests.yml` + +## Completion contract + +- Do not claim completion without reporting: + - `Changed` + - `Verification` + - `Edge Cases` + - `Docs Updated` +- If verification could not run, say so explicitly and stop short of claiming completion. +``` + +`.claude/rules/testing-and-completion.md` + +```md +# Testing And Completion + +- Treat changes in `cmd/`, `providers/`, `sandbox/`, `ops/`, `common/`, `test/`, `.github/workflows/`, and `.claude/` as verification-sensitive. +- Run the strongest relevant checks before finishing: + - `.claude/**` => `./test/claude-agent-tests.sh` + - Go code => `go test ./...` or `./test/go-unit-tests.sh` + - Provider and topology behavior => the matching jobs in `.github/workflows/integration_tests.yml` and `.github/workflows/proxysql_integration_tests.yml` +- Final responses must include `Changed`, `Verification`, `Edge Cases`, and `Docs Updated`. +- If a required check cannot run in the current environment, state the gap explicitly and do not describe the task as complete. +``` + +`.claude/rules/provider-surfaces.md` + +```md +--- +paths: + - "cmd/**/*" + - "providers/**/*" + - "sandbox/**/*" + - "ops/**/*" + - "docs/**/*" + - ".github/workflows/**/*" +--- + +# Provider-Sensitive Surfaces + +- Review MySQL, PostgreSQL, and ProxySQL behavior as correctness-sensitive, not style-sensitive. +- Check version differences, package layout assumptions, startup ordering, auth defaults, port allocation, replication semantics, and ProxySQL admin/mysql port pairing. +- If behavior changes, update the affected docs in `docs/`, `README.md`, or `CONTRIBUTING.md` in the same task. +- Prefer targeted validation commands over abstract confidence statements. +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: `PASS: project Claude memory and rules` + +- [ ] **Step 5: Commit** + +```bash +git add .claude/CLAUDE.md .claude/rules/testing-and-completion.md .claude/rules/provider-surfaces.md test/claude-agent-tests.sh +git commit -m "chore: add Claude project memory and rules" +``` + +### Task 2: Add Repo-Local Workflow Skills + +**Files:** +- Modify: `test/claude-agent-tests.sh` +- Create: `.claude/skills/dbdeployer-maintainer/SKILL.md` +- Create: `.claude/skills/db-correctness-review/SKILL.md` +- Create: `.claude/skills/verification-matrix/SKILL.md` +- Create: `.claude/skills/docs-reference-sync/SKILL.md` + +- [ ] **Step 1: Extend the failing test** + +Replace `test/claude-agent-tests.sh` with: + +```bash +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +require_file() { + local file="$1" + local label="$2" + if [[ ! -f "$ROOT/$file" ]]; then + echo "FAIL: $label ($file missing)" >&2 + exit 1 + fi +} + +require_contains() { + local file="$1" + local needle="$2" + local label="$3" + if ! grep -Fq "$needle" "$ROOT/$file"; then + echo "FAIL: $label ($needle missing from $file)" >&2 + exit 1 + fi +} + +require_file ".claude/CLAUDE.md" "project CLAUDE.md exists" +require_file ".claude/rules/testing-and-completion.md" "testing rule exists" +require_file ".claude/rules/provider-surfaces.md" "provider rule exists" +require_file ".claude/skills/dbdeployer-maintainer/SKILL.md" "maintainer skill exists" +require_file ".claude/skills/db-correctness-review/SKILL.md" "correctness review skill exists" +require_file ".claude/skills/verification-matrix/SKILL.md" "verification skill exists" +require_file ".claude/skills/docs-reference-sync/SKILL.md" "docs sync skill exists" + +require_contains ".claude/CLAUDE.md" "dbdeployer-maintainer" "project memory names the maintainer workflow" +require_contains ".claude/rules/testing-and-completion.md" "./test/go-unit-tests.sh" "testing rule references Go unit tests" +require_contains ".claude/rules/provider-surfaces.md" "ProxySQL" "provider rule covers ProxySQL" +require_contains ".claude/skills/dbdeployer-maintainer/SKILL.md" "Changed" "maintainer skill requires final change summary" +require_contains ".claude/skills/db-correctness-review/SKILL.md" "Correctness Risks" "correctness skill names its findings section" +require_contains ".claude/skills/verification-matrix/SKILL.md" "Linux Runner Checks" "verification skill requires Linux runner reporting" +require_contains ".claude/skills/docs-reference-sync/SKILL.md" "Docs To Update" "docs skill defines doc update output" + +echo "PASS: project Claude memory, rules, and skills" +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: FAIL because the four project skill files do not exist yet. + +- [ ] **Step 3: Write minimal implementation** + +`.claude/skills/dbdeployer-maintainer/SKILL.md` + +```md +--- +name: dbdeployer-maintainer +description: Primary maintainer workflow for dbdeployer. Use for non-trivial feature work, bug fixes, provider changes, verification tasks, or docs sync in this repo. +--- + +Follow this sequence: + +1. Frame the task: + - classify it as feature, bug, provider behavior, test-only, docs-only, or mixed + - list affected surfaces: MySQL, PostgreSQL, ProxySQL, CLI, sandbox templates, tests, docs +2. Implement or investigate. +3. If database behavior may have changed, invoke `/db-correctness-review`. +4. Invoke `/verification-matrix` before you stop. +5. If behavior, flags, support statements, or examples changed, invoke `/docs-reference-sync`. +6. Final response must include sections titled `Changed`, `Verification`, `Edge Cases`, and `Docs Updated`. +7. If the user-level skill `/db-core-expertise` is available, invoke it for MySQL/PostgreSQL/ProxySQL questions before concluding. +``` + +`.claude/skills/db-correctness-review/SKILL.md` + +```md +--- +name: db-correctness-review +description: Adversarial MySQL/PostgreSQL/ProxySQL review for dbdeployer changes. Use after implementation or when auditing provider behavior, replication, packaging, or topology semantics. +disable-model-invocation: true +--- + +Review the change as if the implementation is probably wrong. + +Work through this checklist: + +1. Database semantics + - Does the behavior match MySQL, PostgreSQL, or ProxySQL reality? + - Are version-specific differences ignored? +2. Lifecycle + - Are bootstrap, start, stop, restart, cleanup, and port allocation ordered safely? +3. Packaging and environment + - Are binary paths, share dirs, client tools, and OS packaging assumptions valid? +4. Topology and routing + - Are replication roles, ProxySQL admin/mysql ports, backend registration, and auth assumptions correct? +5. Operator edge cases + - missing binaries + - partial setup + - stale sockets + - port collisions + - cleanup after failure + +Report findings as: +- `Correctness Risks` +- `Edge Cases Checked` +- `Recommended Follow-up` + +If `/db-core-expertise` is available, invoke it first. +``` + +`.claude/skills/verification-matrix/SKILL.md` + +```md +--- +name: verification-matrix +description: Chooses the strongest dbdeployer verification path for the changed surfaces and environment. Use before completing any code or behavior change. +disable-model-invocation: true +--- + +Build the verification plan from changed files: + +- `.claude/**` or `test/claude-agent/**`: + - run `./test/claude-agent-tests.sh` +- `common/`, `cmd/`, `ops/`, `providers/`, `sandbox/`: + - run `go test ./...` + - run `./test/go-unit-tests.sh` +- MySQL download or deploy behavior: + - compare against `.github/workflows/integration_tests.yml` +- PostgreSQL provider behavior: + - compare against the PostgreSQL job in `.github/workflows/integration_tests.yml` +- ProxySQL behavior: + - compare against `.github/workflows/proxysql_integration_tests.yml` + +When the local machine cannot run the strongest check, say exactly which Linux-runner job remains required. + +Report output as: +- `Local Checks` +- `Linux Runner Checks` +- `Unverified Risk` +``` + +`.claude/skills/docs-reference-sync/SKILL.md` + +```md +--- +name: docs-reference-sync +description: Syncs docs and reference material after dbdeployer behavior, flags, support statements, or examples change. +disable-model-invocation: true +--- + +Use this workflow when code or tests change behavior: + +1. List which surfaces changed: README, quickstarts, provider guides, reference pages, contributor docs. +2. Update the smallest truthful set of docs. +3. Prefer concrete commands and caveats over marketing language. +4. If behavior is still experimental, state the limitation directly. + +Report output as: +- `Docs To Update` +- `Files Updated` +- `Open Caveats` +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: `PASS: project Claude memory, rules, and skills` + +- [ ] **Step 5: Commit** + +```bash +git add .claude/skills/dbdeployer-maintainer/SKILL.md .claude/skills/db-correctness-review/SKILL.md .claude/skills/verification-matrix/SKILL.md .claude/skills/docs-reference-sync/SKILL.md test/claude-agent-tests.sh +git commit -m "chore: add dbdeployer Claude workflow skills" +``` + +### Task 3: Add Hooks, Settings, And Hook Tests + +**Files:** +- Modify: `.gitignore` +- Create: `.claude/settings.json` +- Create: `.claude/hooks/block-destructive-commands.sh` +- Create: `.claude/hooks/record-verification-command.sh` +- Create: `.claude/hooks/stop-completion-gate.sh` +- Modify: `test/claude-agent-tests.sh` +- Create: `test/claude-agent/fixtures/pretool-git-reset-hard.json` +- Create: `test/claude-agent/fixtures/pretool-git-status.json` +- Create: `test/claude-agent/fixtures/posttool-go-test.json` +- Create: `test/claude-agent/fixtures/posttool-echo.json` +- Create: `test/claude-agent/fixtures/stop-sections-missing.json` +- Create: `test/claude-agent/fixtures/stop-sections-complete.json` + +- [ ] **Step 1: Extend the failing test and add fixtures** + +Replace `test/claude-agent-tests.sh` with: + +```bash +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +FIXTURES="$ROOT/test/claude-agent/fixtures" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +require_file() { + local file="$1" + local label="$2" + if [[ ! -f "$ROOT/$file" ]]; then + echo "FAIL: $label ($file missing)" >&2 + exit 1 + fi +} + +require_contains() { + local file="$1" + local needle="$2" + local label="$3" + if ! grep -Fq "$needle" "$ROOT/$file"; then + echo "FAIL: $label ($needle missing from $file)" >&2 + exit 1 + fi +} + +assert_empty_output() { + local output="$1" + local label="$2" + if [[ -n "$output" ]]; then + echo "FAIL: $label (expected no output)" >&2 + printf '%s\n' "$output" >&2 + exit 1 + fi +} + +require_file ".claude/CLAUDE.md" "project CLAUDE.md exists" +require_file ".claude/rules/testing-and-completion.md" "testing rule exists" +require_file ".claude/rules/provider-surfaces.md" "provider rule exists" +require_file ".claude/skills/dbdeployer-maintainer/SKILL.md" "maintainer skill exists" +require_file ".claude/skills/db-correctness-review/SKILL.md" "correctness review skill exists" +require_file ".claude/skills/verification-matrix/SKILL.md" "verification skill exists" +require_file ".claude/skills/docs-reference-sync/SKILL.md" "docs sync skill exists" +require_file ".claude/settings.json" "project settings exist" +require_file ".claude/hooks/block-destructive-commands.sh" "destructive command hook exists" +require_file ".claude/hooks/record-verification-command.sh" "verification recording hook exists" +require_file ".claude/hooks/stop-completion-gate.sh" "completion gate hook exists" + +require_contains ".claude/CLAUDE.md" "dbdeployer-maintainer" "project memory names the maintainer workflow" +require_contains ".claude/rules/testing-and-completion.md" "./test/go-unit-tests.sh" "testing rule references Go unit tests" +require_contains ".claude/rules/provider-surfaces.md" "ProxySQL" "provider rule covers ProxySQL" +require_contains ".claude/skills/dbdeployer-maintainer/SKILL.md" "Changed" "maintainer skill requires final change summary" +require_contains ".claude/skills/db-correctness-review/SKILL.md" "Correctness Risks" "correctness skill names its findings section" +require_contains ".claude/skills/verification-matrix/SKILL.md" "Linux Runner Checks" "verification skill requires Linux runner reporting" +require_contains ".claude/skills/docs-reference-sync/SKILL.md" "Docs To Update" "docs skill defines doc update output" + +jq empty "$ROOT/.claude/settings.json" >/dev/null + +block_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-reset-hard.json")" +printf '%s' "$block_output" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null + +safe_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-status.json")" +assert_empty_output "$safe_output" "safe git command allowed" + +log_path="$TMPDIR/verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-go-test.json" +grep -Fq "go test ./..." "$log_path" + +log_path="$TMPDIR/non-verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-echo.json" +[[ ! -f "$log_path" ]] + +missing_verification_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/missing-log.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_verification_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_verification_output" | jq -e '.reason | contains("Run the relevant verification")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_docs_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_docs_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_docs_output" | jq -e '.reason | contains("docs update")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_sections_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-missing.json" +)" +printf '%s' "$missing_sections_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_sections_output" | jq -e '.reason | contains("Docs Updated")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +complete_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +assert_empty_output "$complete_output" "completion gate allows verified and documented changes" + +echo "PASS: Claude hooks and tests" +``` + +Create the fixtures: + +`test/claude-agent/fixtures/pretool-git-reset-hard.json` + +```json +{ + "session_id": "sess-pretool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PreToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "git reset --hard HEAD" + } +} +``` + +`test/claude-agent/fixtures/pretool-git-status.json` + +```json +{ + "session_id": "sess-pretool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PreToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "git status --short" + } +} +``` + +`test/claude-agent/fixtures/posttool-go-test.json` + +```json +{ + "session_id": "sess-posttool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PostToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "go test ./..." + } +} +``` + +`test/claude-agent/fixtures/posttool-echo.json` + +```json +{ + "session_id": "sess-posttool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PostToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "echo not-a-test" + } +} +``` + +`test/claude-agent/fixtures/stop-sections-missing.json` + +```json +{ + "session_id": "sess-stop", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "Stop", + "stop_hook_active": false, + "last_assistant_message": "Changed\n- updated PostgreSQL deployment flow\nVerification\n- ./test/go-unit-tests.sh\nEdge Cases\n- checked package layout" +} +``` + +`test/claude-agent/fixtures/stop-sections-complete.json` + +```json +{ + "session_id": "sess-stop", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "Stop", + "stop_hook_active": false, + "last_assistant_message": "Changed\n- updated PostgreSQL deployment flow\nVerification\n- ./test/go-unit-tests.sh\nEdge Cases\n- checked package layout and port collisions\nDocs Updated\n- docs/wiki/main-operations.md" +} +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: FAIL because `.claude/settings.json` and the three hook scripts do not exist yet. + +- [ ] **Step 3: Write minimal implementation** + +Append these lines to `.gitignore`: + +```gitignore +.claude/state/ +.claude/settings.local.json +``` + +`.claude/settings.json` + +```json +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "if": "Bash(git *)", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-destructive-commands.sh" + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/record-verification-command.sh" + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-completion-gate.sh" + } + ] + } + ] + } +} +``` + +`.claude/hooks/block-destructive-commands.sh` + +```bash +#!/usr/bin/env bash +set -euo pipefail + +input="$(cat)" +command="$(printf '%s' "$input" | jq -r '.tool_input.command // ""')" + +blocked_patterns=( + "git reset --hard" + "git checkout --" + "git clean -fd" + "git clean -ffd" +) + +for pattern in "${blocked_patterns[@]}"; do + if [[ "$command" == "$pattern"* ]]; then + jq -n '{ + hookSpecificOutput: { + hookEventName: "PreToolUse", + permissionDecision: "deny", + permissionDecisionReason: "Destructive git command blocked in dbdeployer. Use a non-destructive alternative." + } + }' + exit 0 + fi +done + +exit 0 +``` + +`.claude/hooks/record-verification-command.sh` + +```bash +#!/usr/bin/env bash +set -euo pipefail + +input="$(cat)" +session_id="$(printf '%s' "$input" | jq -r '.session_id')" +cwd="$(printf '%s' "$input" | jq -r '.cwd')" +command="$(printf '%s' "$input" | jq -r '.tool_input.command // ""')" +project_dir="${CLAUDE_PROJECT_DIR:-$cwd}" +log_path="${CLAUDE_AGENT_VERIFICATION_LOG:-$project_dir/.claude/state/verification-log.jsonl}" + +if [[ "$command" =~ (^|[[:space:]])(go[[:space:]]+test|\.\/test\/go-unit-tests\.sh|\.\/test\/claude-agent-tests\.sh|\.\/test\/functional-test\.sh|\.\/test\/docker-test\.sh|\.\/test\/proxysql-integration-tests\.sh|\.\/scripts\/build\.sh) ]]; then + mkdir -p "$(dirname "$log_path")" + jq -cn \ + --arg session_id "$session_id" \ + --arg cwd "$cwd" \ + --arg command "$command" \ + --arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + '{session_id: $session_id, cwd: $cwd, command: $command, timestamp: $timestamp}' >> "$log_path" +fi + +exit 0 +``` + +`.claude/hooks/stop-completion-gate.sh` + +```bash +#!/usr/bin/env bash +set -euo pipefail + +input="$(cat)" +session_id="$(printf '%s' "$input" | jq -r '.session_id')" +cwd="$(printf '%s' "$input" | jq -r '.cwd')" +message="$(printf '%s' "$input" | jq -r '.last_assistant_message // ""')" +project_dir="${CLAUDE_PROJECT_DIR:-$cwd}" +log_path="${CLAUDE_AGENT_VERIFICATION_LOG:-$project_dir/.claude/state/verification-log.jsonl}" +changed_files="${CLAUDE_AGENT_CHANGED_FILES:-}" + +if [[ -z "$changed_files" ]]; then + changed_files="$(git -C "$project_dir" status --short | awk '{print $2}')" +fi + +if [[ -z "$changed_files" ]]; then + exit 0 +fi + +requires_verification=0 +requires_docs=0 +docs_updated=0 + +while IFS= read -r file; do + [[ -z "$file" ]] && continue + if [[ "$file" =~ ^(cmd/|providers/|sandbox/|ops/|common/|test/|\.github/workflows/|\.claude/) ]]; then + requires_verification=1 + fi + if [[ "$file" =~ ^(cmd/|providers/|sandbox/|ops/|common/) ]]; then + requires_docs=1 + fi + if [[ "$file" =~ ^(docs/|README\.md|CONTRIBUTING\.md|\.claude/CLAUDE\.md|\.claude/rules/) ]]; then + docs_updated=1 + fi +done <<< "$changed_files" + +if [[ "$requires_verification" -eq 1 ]]; then + if [[ ! -f "$log_path" ]] || ! jq -e --arg session_id "$session_id" 'select(.session_id == $session_id)' "$log_path" >/dev/null 2>&1; then + jq -n --arg reason "Run the relevant verification before finishing. Expected at least one successful test or build command recorded for this session." '{decision: "block", reason: $reason}' + exit 0 + fi +fi + +if [[ "$requires_docs" -eq 1 && "$docs_updated" -eq 0 ]]; then + jq -n --arg reason "Behavior-sensitive files changed without a docs update. Add the relevant docs update before finishing." '{decision: "block", reason: $reason}' + exit 0 +fi + +for section in "Changed" "Verification" "Edge Cases" "Docs Updated"; do + if [[ "$message" != *"$section"* ]]; then + jq -n --arg reason "Final response must include '$section' so completion is auditable." '{decision: "block", reason: $reason}' + exit 0 + fi +done + +exit 0 +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: `PASS: Claude hooks and tests` + +- [ ] **Step 5: Commit** + +```bash +chmod +x .claude/hooks/block-destructive-commands.sh .claude/hooks/record-verification-command.sh .claude/hooks/stop-completion-gate.sh +git add .gitignore .claude/settings.json .claude/hooks/block-destructive-commands.sh .claude/hooks/record-verification-command.sh .claude/hooks/stop-completion-gate.sh test/claude-agent-tests.sh test/claude-agent/fixtures +git commit -m "chore: add Claude hooks and smoke tests" +``` + +### Task 4: Add Maintainer Documentation + +**Files:** +- Modify: `test/claude-agent-tests.sh` +- Create: `docs/coding/claude-code-agent.md` +- Modify: `CONTRIBUTING.md` + +- [ ] **Step 1: Extend the failing test** + +Replace `test/claude-agent-tests.sh` with: + +```bash +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +FIXTURES="$ROOT/test/claude-agent/fixtures" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +require_file() { + local file="$1" + local label="$2" + if [[ ! -f "$ROOT/$file" ]]; then + echo "FAIL: $label ($file missing)" >&2 + exit 1 + fi +} + +require_contains() { + local file="$1" + local needle="$2" + local label="$3" + if ! grep -Fq "$needle" "$ROOT/$file"; then + echo "FAIL: $label ($needle missing from $file)" >&2 + exit 1 + fi +} + +assert_empty_output() { + local output="$1" + local label="$2" + if [[ -n "$output" ]]; then + echo "FAIL: $label (expected no output)" >&2 + printf '%s\n' "$output" >&2 + exit 1 + fi +} + +require_file ".claude/CLAUDE.md" "project CLAUDE.md exists" +require_file ".claude/rules/testing-and-completion.md" "testing rule exists" +require_file ".claude/rules/provider-surfaces.md" "provider rule exists" +require_file ".claude/skills/dbdeployer-maintainer/SKILL.md" "maintainer skill exists" +require_file ".claude/skills/db-correctness-review/SKILL.md" "correctness review skill exists" +require_file ".claude/skills/verification-matrix/SKILL.md" "verification skill exists" +require_file ".claude/skills/docs-reference-sync/SKILL.md" "docs sync skill exists" +require_file ".claude/settings.json" "project settings exist" +require_file ".claude/hooks/block-destructive-commands.sh" "destructive command hook exists" +require_file ".claude/hooks/record-verification-command.sh" "verification recording hook exists" +require_file ".claude/hooks/stop-completion-gate.sh" "completion gate hook exists" +require_file "docs/coding/claude-code-agent.md" "Claude maintainer guide exists" + +require_contains ".claude/CLAUDE.md" "dbdeployer-maintainer" "project memory names the maintainer workflow" +require_contains ".claude/rules/testing-and-completion.md" "./test/go-unit-tests.sh" "testing rule references Go unit tests" +require_contains ".claude/rules/provider-surfaces.md" "ProxySQL" "provider rule covers ProxySQL" +require_contains ".claude/skills/dbdeployer-maintainer/SKILL.md" "Changed" "maintainer skill requires final change summary" +require_contains ".claude/skills/db-correctness-review/SKILL.md" "Correctness Risks" "correctness skill names its findings section" +require_contains ".claude/skills/verification-matrix/SKILL.md" "Linux Runner Checks" "verification skill requires Linux runner reporting" +require_contains ".claude/skills/docs-reference-sync/SKILL.md" "Docs To Update" "docs skill defines doc update output" +require_contains "docs/coding/claude-code-agent.md" "./test/claude-agent-tests.sh" "maintainer guide references the Claude smoke tests" +require_contains "CONTRIBUTING.md" "docs/coding/claude-code-agent.md" "contributing guide links to the Claude maintainer guide" + +jq empty "$ROOT/.claude/settings.json" >/dev/null + +block_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-reset-hard.json")" +printf '%s' "$block_output" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null + +safe_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-status.json")" +assert_empty_output "$safe_output" "safe git command allowed" + +log_path="$TMPDIR/verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-go-test.json" +grep -Fq "go test ./..." "$log_path" + +log_path="$TMPDIR/non-verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-echo.json" +[[ ! -f "$log_path" ]] + +missing_verification_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/missing-log.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_verification_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_verification_output" | jq -e '.reason | contains("Run the relevant verification")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_docs_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_docs_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_docs_output" | jq -e '.reason | contains("docs update")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_sections_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-missing.json" +)" +printf '%s' "$missing_sections_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_sections_output" | jq -e '.reason | contains("Docs Updated")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +complete_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +assert_empty_output "$complete_output" "completion gate allows verified and documented changes" + +echo "PASS: Claude repo assets, docs, and hooks" +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: FAIL because `docs/coding/claude-code-agent.md` does not exist and `CONTRIBUTING.md` does not link to it. + +- [ ] **Step 3: Write minimal implementation** + +`docs/coding/claude-code-agent.md` + +```md +# Claude Code Maintainer Workflow + +This repo includes a project-local Claude Code operating layer under `.claude/`. + +## Project assets + +- `.claude/CLAUDE.md` defines the shared maintainer workflow. +- `.claude/rules/` keeps always-on testing and provider-sensitive guidance concise. +- `.claude/skills/` provides the project workflows: + - `/dbdeployer-maintainer` + - `/db-correctness-review` + - `/verification-matrix` + - `/docs-reference-sync` +- `.claude/hooks/` enforces destructive-command blocking, verification tracking, and completion gates. + +## Local verification + +Run the project-local Claude asset smoke tests with: + + ./test/claude-agent-tests.sh + +These tests validate the repo-local Claude files, hook behavior, and completion policy. + +## Expected maintainer flow + +1. Start non-trivial tasks with `/dbdeployer-maintainer`. +2. Use `/db-correctness-review` when behavior, packaging, replication, or ProxySQL wiring may have changed. +3. Use `/verification-matrix` before stopping so the strongest feasible checks run. +4. Use `/docs-reference-sync` when behavior, flags, support statements, or examples change. + +## Completion requirements + +Final responses should include: + +- `Changed` +- `Verification` +- `Edge Cases` +- `Docs Updated` + +If a relevant check could not run locally, report the exact Linux-runner gap instead of claiming full completion. +``` + +`CONTRIBUTING.md` + +```md +## Claude Code Maintainer Workflow + +If you use Claude Code for maintenance work in this repo, read `docs/coding/claude-code-agent.md` first. It documents the repo-local `.claude/` skills, hook behavior, and required smoke tests. +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: `PASS: Claude repo assets, docs, and hooks` + +- [ ] **Step 5: Commit** + +```bash +git add docs/coding/claude-code-agent.md CONTRIBUTING.md test/claude-agent-tests.sh +git commit -m "docs: add Claude maintainer workflow guide" +``` + +### Task 5: Add Reusable DB Expertise Templates And Installer + +**Files:** +- Modify: `test/claude-agent-tests.sh` +- Modify: `docs/coding/claude-code-agent.md` +- Create: `tools/claude-skills/db-core-expertise/SKILL.md` +- Create: `tools/claude-skills/db-core-expertise/mysql.md` +- Create: `tools/claude-skills/db-core-expertise/postgresql.md` +- Create: `tools/claude-skills/db-core-expertise/proxysql.md` +- Create: `tools/claude-skills/db-core-expertise/verification-playbook.md` +- Create: `tools/claude-skills/db-core-expertise/docs-style.md` +- Create: `tools/claude-skills/db-core-expertise/scripts/smoke-test.sh` +- Create: `scripts/install_claude_db_skills.sh` + +- [ ] **Step 1: Extend the failing test** + +Replace `test/claude-agent-tests.sh` with: + +```bash +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +FIXTURES="$ROOT/test/claude-agent/fixtures" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +require_file() { + local file="$1" + local label="$2" + if [[ ! -f "$ROOT/$file" ]]; then + echo "FAIL: $label ($file missing)" >&2 + exit 1 + fi +} + +require_contains() { + local file="$1" + local needle="$2" + local label="$3" + if ! grep -Fq "$needle" "$ROOT/$file"; then + echo "FAIL: $label ($needle missing from $file)" >&2 + exit 1 + fi +} + +assert_empty_output() { + local output="$1" + local label="$2" + if [[ -n "$output" ]]; then + echo "FAIL: $label (expected no output)" >&2 + printf '%s\n' "$output" >&2 + exit 1 + fi +} + +require_file ".claude/CLAUDE.md" "project CLAUDE.md exists" +require_file ".claude/rules/testing-and-completion.md" "testing rule exists" +require_file ".claude/rules/provider-surfaces.md" "provider rule exists" +require_file ".claude/skills/dbdeployer-maintainer/SKILL.md" "maintainer skill exists" +require_file ".claude/skills/db-correctness-review/SKILL.md" "correctness review skill exists" +require_file ".claude/skills/verification-matrix/SKILL.md" "verification skill exists" +require_file ".claude/skills/docs-reference-sync/SKILL.md" "docs sync skill exists" +require_file ".claude/settings.json" "project settings exist" +require_file ".claude/hooks/block-destructive-commands.sh" "destructive command hook exists" +require_file ".claude/hooks/record-verification-command.sh" "verification recording hook exists" +require_file ".claude/hooks/stop-completion-gate.sh" "completion gate hook exists" +require_file "docs/coding/claude-code-agent.md" "Claude maintainer guide exists" +require_file "tools/claude-skills/db-core-expertise/SKILL.md" "reusable DB skill template exists" +require_file "tools/claude-skills/db-core-expertise/mysql.md" "MySQL reference exists" +require_file "tools/claude-skills/db-core-expertise/postgresql.md" "PostgreSQL reference exists" +require_file "tools/claude-skills/db-core-expertise/proxysql.md" "ProxySQL reference exists" +require_file "tools/claude-skills/db-core-expertise/verification-playbook.md" "verification playbook exists" +require_file "tools/claude-skills/db-core-expertise/docs-style.md" "docs style note exists" +require_file "tools/claude-skills/db-core-expertise/scripts/smoke-test.sh" "reusable DB skill smoke test exists" +require_file "scripts/install_claude_db_skills.sh" "installer script exists" + +require_contains ".claude/CLAUDE.md" "dbdeployer-maintainer" "project memory names the maintainer workflow" +require_contains ".claude/rules/testing-and-completion.md" "./test/go-unit-tests.sh" "testing rule references Go unit tests" +require_contains ".claude/rules/provider-surfaces.md" "ProxySQL" "provider rule covers ProxySQL" +require_contains ".claude/skills/dbdeployer-maintainer/SKILL.md" "Changed" "maintainer skill requires final change summary" +require_contains ".claude/skills/db-correctness-review/SKILL.md" "Correctness Risks" "correctness skill names its findings section" +require_contains ".claude/skills/verification-matrix/SKILL.md" "Linux Runner Checks" "verification skill requires Linux runner reporting" +require_contains ".claude/skills/docs-reference-sync/SKILL.md" "Docs To Update" "docs skill defines doc update output" +require_contains "docs/coding/claude-code-agent.md" "./scripts/install_claude_db_skills.sh" "maintainer guide references the reusable skill installer" +require_contains "CONTRIBUTING.md" "docs/coding/claude-code-agent.md" "contributing guide links to the Claude maintainer guide" +require_contains "tools/claude-skills/db-core-expertise/SKILL.md" "db-core-expertise" "reusable skill has the expected name" + +jq empty "$ROOT/.claude/settings.json" >/dev/null + +block_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-reset-hard.json")" +printf '%s' "$block_output" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null + +safe_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-status.json")" +assert_empty_output "$safe_output" "safe git command allowed" + +log_path="$TMPDIR/verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-go-test.json" +grep -Fq "go test ./..." "$log_path" + +log_path="$TMPDIR/non-verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-echo.json" +[[ ! -f "$log_path" ]] + +missing_verification_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/missing-log.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_verification_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_verification_output" | jq -e '.reason | contains("Run the relevant verification")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_docs_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_docs_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_docs_output" | jq -e '.reason | contains("docs update")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_sections_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-missing.json" +)" +printf '%s' "$missing_sections_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_sections_output" | jq -e '.reason | contains("Docs Updated")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +complete_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +assert_empty_output "$complete_output" "completion gate allows verified and documented changes" + +bash "$ROOT/tools/claude-skills/db-core-expertise/scripts/smoke-test.sh" + +echo "PASS: Claude repo assets, docs, hooks, and reusable DB skill templates" +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `bash ./test/claude-agent-tests.sh` +Expected: FAIL because the reusable DB expertise template files and installer script do not exist yet. + +- [ ] **Step 3: Write minimal implementation** + +`tools/claude-skills/db-core-expertise/SKILL.md` + +```md +--- +name: db-core-expertise +description: MySQL, PostgreSQL, ProxySQL, packaging, replication, and topology reference for database tooling. Use when reviewing DB behavior, version differences, edge cases, verification strategy, or docs accuracy. +--- + +When this skill is active: + +1. Read only the supporting files you need from this directory: + - `mysql.md` + - `postgresql.md` + - `proxysql.md` + - `verification-playbook.md` + - `docs-style.md` +2. Treat behavior questions as correctness-sensitive. +3. Surface version and packaging assumptions explicitly. +4. If facts may have changed, verify against official upstream docs or release notes before concluding. +5. Prefer short reproducible checks over broad statements. +6. Return findings under: + - `Relevant Facts` + - `Risks` + - `Suggested Validation` +``` + +`tools/claude-skills/db-core-expertise/mysql.md` + +```md +# MySQL Notes + +- `dbdeployer` commonly manages tarball-based MySQL layouts under `~/opt/mysql/`. +- Watch for version differences across 8.0, 8.4, and 9.x. +- Verify defaults that changed across releases: auth plugin, mysqlx behavior, packaging names, startup scripts, and server flags. +- Edge cases: + - missing shared libs on Linux + - stale socket files + - port collisions across mysql/mysqlx/admin ports + - replication role ordering +- Good validation: + - `~/sandboxes/.../use -e "SELECT VERSION();"` + - `~/sandboxes/rsandbox_*/check_slaves` + - `~/sandboxes/rsandbox_*/test_replication` +``` + +`tools/claude-skills/db-core-expertise/postgresql.md` + +```md +# PostgreSQL Notes + +- `dbdeployer` expects user-space PostgreSQL binaries laid out as `bin/`, `lib/`, and `share/`. +- Debian and apt extraction plus share-dir wiring are common failure points. +- Validate initdb share paths, stop/start scripts, socket/config paths, and primary/replica setup. +- Edge cases: + - wrong `-L` share dir for `initdb` + - missing timezone or extension files + - stale `postmaster.pid` + - replica recovery config drift +- Good validation: + - `~/sandboxes/pg_sandbox_*/use -c "SELECT version();"` + - `bash ~/sandboxes/postgresql_repl_*/check_replication` + - write on primary, read on replicas +``` + +`tools/claude-skills/db-core-expertise/proxysql.md` + +```md +# ProxySQL Notes + +- Track the admin and mysql listener pair together. +- Distinguish standalone deployment from topology-attached deployment. +- Validate backend registration, credentials, hostgroup wiring, and start/stop scripts. +- Edge cases: + - admin port collision with listener pair + - binary present but runtime dirs missing + - backend auth mismatch + - PostgreSQL proxy support gaps or work-in-progress behavior +- Good validation: + - `~/sandboxes/*/proxysql/status` + - `~/sandboxes/*/proxysql/use -e "SELECT * FROM mysql_servers;"` + - `~/sandboxes/*/proxysql/use_proxy -e "SELECT 1;"` +``` + +`tools/claude-skills/db-core-expertise/verification-playbook.md` + +```md +# Verification Playbook + +- Start with the smallest truthful local check. +- Escalate to Linux-runner coverage when the change affects packaging, downloads, provider startup, replication, or ProxySQL integration. +- Map surfaces to checks: + - `.claude/**` => `./test/claude-agent-tests.sh` + - Go code => `go test ./...` and `./test/go-unit-tests.sh` + - MySQL deployment => `.github/workflows/integration_tests.yml` + - PostgreSQL provider => the PostgreSQL job in `.github/workflows/integration_tests.yml` + - ProxySQL => `.github/workflows/proxysql_integration_tests.yml` +- If a check did not run, call it residual risk, not completed coverage. +``` + +`tools/claude-skills/db-core-expertise/docs-style.md` + +```md +# Documentation Style + +- Prefer exact commands over general prose. +- State limitations directly. +- When behavior is provider-specific, name the provider in the heading or paragraph. +- If verification is partial, say what ran and what did not. +- Reference the actual script or workflow name when pointing maintainers to further validation. +``` + +`tools/claude-skills/db-core-expertise/scripts/smoke-test.sh` + +```bash +#!/usr/bin/env bash +set -euo pipefail + +SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +for file in SKILL.md mysql.md postgresql.md proxysql.md verification-playbook.md docs-style.md; do + [[ -f "$SKILL_DIR/$file" ]] || { echo "Missing $file" >&2; exit 1; } +done + +grep -Fq "db-core-expertise" "$SKILL_DIR/SKILL.md" +grep -Fq "MySQL" "$SKILL_DIR/mysql.md" +grep -Fq "PostgreSQL" "$SKILL_DIR/postgresql.md" +grep -Fq "ProxySQL" "$SKILL_DIR/proxysql.md" + +echo "db-core-expertise skill looks complete" +``` + +`scripts/install_claude_db_skills.sh` + +```bash +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SRC="$ROOT/tools/claude-skills/db-core-expertise" +DEST="${HOME}/.claude/skills/db-core-expertise" + +mkdir -p "$(dirname "$DEST")" +rm -rf "$DEST" +mkdir -p "$DEST" +cp -R "$SRC"/. "$DEST"/ +chmod +x "$DEST/scripts/smoke-test.sh" + +echo "Installed db-core-expertise to $DEST" +``` + +Update `docs/coding/claude-code-agent.md` by adding: + +```md +## Reusable database expertise + +Install the reusable MySQL/PostgreSQL/ProxySQL reference skill with: + + ./scripts/install_claude_db_skills.sh + ~/.claude/skills/db-core-expertise/scripts/smoke-test.sh + +The installed user-level skill is named `/db-core-expertise`. Use it when the task depends on DB semantics, packaging assumptions, replication edge cases, or live upstream verification. +``` + +- [ ] **Step 4: Run tests and install smoke checks** + +Run: `chmod +x tools/claude-skills/db-core-expertise/scripts/smoke-test.sh scripts/install_claude_db_skills.sh && bash ./test/claude-agent-tests.sh && ./scripts/install_claude_db_skills.sh && ~/.claude/skills/db-core-expertise/scripts/smoke-test.sh` +Expected: +- `PASS: Claude repo assets, docs, hooks, and reusable DB skill templates` +- `Installed db-core-expertise to ~/.claude/skills/db-core-expertise` +- `db-core-expertise skill looks complete` + +- [ ] **Step 5: Commit** + +```bash +git add docs/coding/claude-code-agent.md tools/claude-skills/db-core-expertise scripts/install_claude_db_skills.sh test/claude-agent-tests.sh +git commit -m "feat: add reusable Claude DB expertise skill templates" +``` + +## Self-Review Checklist + +- Spec coverage: + - Two-layer design: Tasks 1-5 + - Enforced role-based repo workflow: Tasks 1-2 + - Strict verification and completion gate: Task 3 + - Docs/manual sync discipline: Tasks 2 and 4 + - Reusable DB expertise layer: Task 5 +- Placeholder scan: + - No `TODO`, `TBD`, or “implement later” steps remain. + - Every file path and command is explicit. +- Type and naming consistency: + - Project skill names match the names referenced in `.claude/CLAUDE.md`. + - Hook filenames match `.claude/settings.json`. + - The reusable user-level skill name matches the installer destination and the maintainer guide. diff --git a/docs/superpowers/specs/2026-03-31-dbdeployer-specialized-agent-design.md b/docs/superpowers/specs/2026-03-31-dbdeployer-specialized-agent-design.md new file mode 100644 index 0000000..0c2db82 --- /dev/null +++ b/docs/superpowers/specs/2026-03-31-dbdeployer-specialized-agent-design.md @@ -0,0 +1,286 @@ +# dbdeployer Specialized Claude Code Agent Design + +Date: 2026-03-31 +Status: Approved for implementation planning +Primary host: Claude Code +Scope: `dbdeployer` reference implementation plus a reusable database-expertise layer + +## Summary + +This design defines a specialized Claude Code agent for `dbdeployer` that is execution-oriented, highly autonomous, and optimized first for: + +1. test matrix design and execution +2. database correctness review and edge-case discovery + +The system should help with feature development, end-to-end review, testing, documentation, and reference-manual work related to `dbdeployer`, while remaining reusable across other database-oriented projects later. + +The recommended design is a two-layer system: + +- a reusable database-expertise layer outside the `dbdeployer` repo +- a `dbdeployer` operating layer inside `~/dbdeployer/.claude/` + +The agent is presented to the user as one primary maintainer agent, but internally it must follow enforced role-based phases rather than behaving like a free-form generic coding assistant. + +## Goals + +- Create a Claude Code setup that behaves like a disciplined `dbdeployer` maintainer. +- Allow high-autonomy execution inside `~/dbdeployer`. +- Prioritize verification and DB-correctness review over rapid but weak completion. +- Support both local developer-machine execution and stronger Linux-runner verification. +- Keep domain knowledge portable beyond `dbdeployer`. +- Ensure docs and reference material stay aligned with behavior changes. + +## Non-Goals + +- Building a large multi-agent swarm. +- Building a plugin or MCP-heavy platform in v1. +- Encoding every database fact into a single giant prompt or handbook. +- Treating live web access as the primary knowledge source. + +## Requirements Chosen During Brainstorming + +- Primary host: Claude Code +- Expertise source: repo + curated knowledge + live web +- Autonomy: high +- Operating model: small agent system implemented as one agent with enforced role-based phases +- Deliverable strategy: both repo-local and reusable, with repo-local value first +- Initial optimization priorities: + 1. test execution and matrix design + 2. DB correctness review and edge-case hunting +- Verification environments: both mixed local machines and a dedicated Linux runner path +- Completion policy: strict +- Knowledge placement: split between reusable external knowledge and `dbdeployer`-specific repo knowledge + +## Architecture + +### Layer 1: Reusable Database Expertise + +This layer lives outside `~/dbdeployer`, ideally in a separate repository or managed knowledge directory, and is exposed to Claude Code through user-level assets under `~/.claude/`. + +It should contain concise, maintainable knowledge files and workflows for: + +- MySQL operational behavior +- PostgreSQL packaging and runtime behavior +- ProxySQL routing, admin, and runtime behavior +- cross-provider comparison notes +- version-specific pitfalls +- replication and topology edge cases +- testing heuristics and verification playbooks +- documentation and reference-writing standards + +This layer is reusable across projects and should avoid `dbdeployer`-specific implementation details. + +### Layer 2: dbdeployer Operating Layer + +This layer lives in `~/dbdeployer/.claude/` and is versioned with the project. + +It should contain: + +- `CLAUDE.md` with project memory, architecture summary, command surfaces, test entrypoints, and completion rules +- focused skills for maintainer workflows +- slash commands for frequent review and verification tasks +- hooks that enforce verification and documentation discipline + +This layer captures `dbdeployer` architecture and operating conventions, including provider boundaries, relevant scripts, doc locations, and repo-specific risk points. + +## Execution Model + +The user interacts with one primary `dbdeployer maintainer` agent. Internally, the agent must pass through fixed phases before it can declare a task complete. + +The phases are: + +1. task framing +2. implementation +3. DB correctness review +4. verification review +5. docs/manual sync +6. completion gate + +This structure is intentional. The same agent may implement and review, but it must switch roles explicitly so that implementation assumptions are challenged before completion. + +## Phase Definitions + +### 1. Task Framing + +The agent classifies the task before touching code: + +- feature +- bug +- provider behavior change +- test-only change +- docs/manual change +- mixed change + +It must also identify affected surfaces, such as: + +- MySQL +- PostgreSQL +- ProxySQL +- provider registry +- CLI and flags +- sandbox templates +- docs and reference manual +- test matrix + +### 2. Implementation + +The agent may design and edit freely, but it must make assumptions explicit: + +- version assumptions +- OS and package assumptions +- provider behavior assumptions +- expected existing test coverage + +### 3. DB Correctness Review + +The agent must switch from builder to adversarial reviewer and ask whether the change matches actual database behavior. + +The review must explicitly check for: + +- MySQL, PostgreSQL, or ProxySQL behavior mismatches +- version-specific differences +- startup and lifecycle ordering issues +- replication, authentication, routing, and packaging differences +- operator-facing edge cases such as missing binaries, port collisions, config-path differences, and partial setup failures + +### 4. Verification Review + +The agent selects and runs the strongest required verification path: + +- fast local checks for quick iteration +- full Linux-runner validation for strict confirmation + +Under the chosen strict policy, the agent may not claim completion without running the relevant checks for the change it made. If the environment prevents full verification, it must stop short of claiming completion and report the exact gap. + +### 5. Docs/Manual Sync + +If behavior, flags, support statements, installation flows, examples, or failure modes changed, documentation must be updated in the same task. + +This includes, when relevant: + +- quickstarts +- provider guides +- reference/manual pages +- examples +- caveats and operator notes + +### 6. Completion Gate + +Before completion, the agent must report: + +- what changed +- what was verified +- what edge cases were checked +- what documentation was updated +- what residual risk remains, if any + +## v1 Deliverables + +Version 1 should stay narrow and operationally useful. + +### Repo-Local Deliverables in `~/dbdeployer/.claude/` + +- `CLAUDE.md` +- 3-4 focused skills, likely including: + - `dbdeployer-maintainer` + - `db-correctness-review` + - `verification-matrix` + - `docs-reference-sync` +- a small set of slash commands for recurring workflows +- hooks for: + - verification-completion discipline + - docs-update reminders on behavior-sensitive changes + - warnings around destructive cleanup or reset actions + +### Reusable Knowledge Deliverables + +- MySQL notes +- PostgreSQL notes +- ProxySQL notes +- cross-provider notes +- edge-case checklists +- verification playbooks +- documentation/reference-writing guidance + +The knowledge should be concise and structured. The goal is retrieval and disciplined execution, not bulk accumulation. + +## Live Web Policy + +Live web access is allowed and useful, but only as a supplemental source. + +It should be used when facts may have changed or require verification, such as: + +- upstream release behavior +- package names and installation flows +- official MySQL, PostgreSQL, or ProxySQL documentation +- issue trackers or release notes directly relevant to the task + +The agent should prefer repo knowledge and curated knowledge first, then consult the web when temporal instability or missing context requires it. + +## Recommended Path + +### Stage 1: Repo-Local Operating System + +Build the `~/dbdeployer/.claude/` layer first so Claude Code becomes a disciplined `dbdeployer` maintainer immediately. + +Deliverables: + +- `CLAUDE.md` +- focused skills +- a few slash commands +- basic hooks for verification and docs/test guardrails + +### Stage 2: Reusable Database Expertise Layer + +Extract or author the reusable cross-project database knowledge in a separate repo or managed knowledge directory and connect it to Claude Code at the user level. + +Deliverables: + +- concise DB notes +- edge-case checklists +- verification heuristics +- docs/reference standards + +### Stage 3: Selective Automation + +Only after the workflow proves useful in practice, add targeted automation such as: + +- helper scripts for choosing verification paths +- stronger hooks on risky file classes +- a local retrieval helper or MCP service if a real need emerges +- automation that suggests documentation updates from changed surfaces + +## Trade-Offs Considered + +### Lean Repo-Local Specialist + +Fastest to build and easiest to evolve, but weaker portability and weaker separation between reusable expertise and `dbdeployer`-specific rules. + +### Full Multi-Agent System + +Potentially stronger coverage, but too much coordination cost for v1 and too easy to over-engineer. + +### Recommended Hybrid + +The chosen design captures most of the practical benefit of specialization while keeping the system maintainable and reusable. + +## Success Criteria + +The design is successful if the resulting Claude Code setup: + +- consistently runs stronger verification than a generic coding agent would +- catches DB-behavior and topology edge cases before completion +- updates docs when behavior changes +- remains usable on both local machines and a Linux verification runner +- can be extended into other DB-oriented projects without being rewritten from scratch + +## Open Implementation Questions + +These are implementation questions, not design blockers: + +- the exact file layout under `~/dbdeployer/.claude/` +- the exact hook triggers and severity levels +- whether slash commands, skills, or both should own each workflow +- how the reusable knowledge repo is physically synchronized into the Claude user environment + +These will be resolved during implementation planning. diff --git a/scripts/install_claude_db_skills.sh b/scripts/install_claude_db_skills.sh new file mode 100755 index 0000000..e5a821b --- /dev/null +++ b/scripts/install_claude_db_skills.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# DBDeployer - The MySQL Sandbox +# Copyright © 2006-2020 Giuseppe Maxia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +SRC="$ROOT/tools/claude-skills/db-core-expertise" +DEST="${HOME}/.claude/skills/db-core-expertise" +PARENT_DIR="$(dirname "$DEST")" + +cleanup() { + rm -rf "$TMP_DEST" "$BACKUP_DEST" +} + +mkdir -p "$PARENT_DIR" +TMP_DEST="$(mktemp -d "$PARENT_DIR/.db-core-expertise.XXXXXX")" +BACKUP_DEST="$PARENT_DIR/.db-core-expertise.backup.$$" +trap cleanup EXIT + +cp -R "$SRC"/. "$TMP_DEST"/ +chmod +x "$TMP_DEST/scripts/smoke-test.sh" + +if [[ -e "$DEST" ]]; then + mv "$DEST" "$BACKUP_DEST" +fi + +mv "$TMP_DEST" "$DEST" +rm -rf "$BACKUP_DEST" +trap - EXIT + +echo "Installed db-core-expertise to $DEST" diff --git a/test/claude-agent-tests.sh b/test/claude-agent-tests.sh new file mode 100755 index 0000000..d47ca07 --- /dev/null +++ b/test/claude-agent-tests.sh @@ -0,0 +1,343 @@ +#!/usr/bin/env bash +# DBDeployer - The MySQL Sandbox +# Copyright © 2006-2020 Giuseppe Maxia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +FIXTURES="$ROOT/test/claude-agent/fixtures" +TMPDIR="$(mktemp -d)" +trap 'rm -rf "$TMPDIR"' EXIT + +fail() { + echo "FAIL: $1" >&2 + exit 1 +} + +resolve_path() { + local path="$1" + if [[ "$path" != /* ]]; then + path="$ROOT/$path" + fi + printf '%s\n' "$path" +} + +require_file() { + local path="$1" + path="$(resolve_path "$path")" + [[ -f "$path" ]] || fail "missing $path" +} + +require_string() { + local path="$1" + local needle="$2" + path="$(resolve_path "$path")" + grep -Fq -- "$needle" "$path" || fail "$path missing substring: $needle" +} + +require_script_header() { + local path="$1" + require_string "$path" "# DBDeployer - The MySQL Sandbox" + require_string "$path" "# Copyright" +} + +assert_empty_output() { + local output="$1" + local label="$2" + if [[ -n "$output" ]]; then + fail "$label (expected no output)" + fi +} + +require_jq_true() { + local path="$1" + local expression="$2" + local label="$3" + jq -e "$expression" "$path" >/dev/null || fail "$label" +} + +require_final_sections() { + local path="$1" + for section in Changed Verification "Edge Cases" "Docs Updated"; do + require_string "$path" "$section" + done +} + +require_file .claude/CLAUDE.md +require_file .claude/rules/testing-and-completion.md +require_file .claude/rules/provider-surfaces.md +require_file .claude/skills/dbdeployer-maintainer/SKILL.md +require_file .claude/skills/db-correctness-review/SKILL.md +require_file .claude/skills/verification-matrix/SKILL.md +require_file .claude/skills/docs-reference-sync/SKILL.md +require_file .claude/settings.json +require_file .claude/hooks/block-destructive-commands.sh +require_file .claude/hooks/record-verification-command.sh +require_file .claude/hooks/stop-completion-gate.sh +require_file docs/coding/claude-code-agent.md +require_file tools/claude-skills/db-core-expertise/SKILL.md +require_file tools/claude-skills/db-core-expertise/mysql.md +require_file tools/claude-skills/db-core-expertise/postgresql.md +require_file tools/claude-skills/db-core-expertise/proxysql.md +require_file tools/claude-skills/db-core-expertise/verification-playbook.md +require_file tools/claude-skills/db-core-expertise/docs-style.md +require_file tools/claude-skills/db-core-expertise/scripts/smoke-test.sh +require_file scripts/install_claude_db_skills.sh + +require_script_header .claude/hooks/block-destructive-commands.sh +require_script_header .claude/hooks/record-verification-command.sh +require_script_header .claude/hooks/stop-completion-gate.sh +require_script_header scripts/install_claude_db_skills.sh +require_script_header test/claude-agent-tests.sh +require_script_header tools/claude-skills/db-core-expertise/scripts/smoke-test.sh + +require_string .claude/CLAUDE.md dbdeployer-maintainer +require_final_sections .claude/CLAUDE.md + +require_string .claude/rules/testing-and-completion.md ./test/go-unit-tests.sh +require_final_sections .claude/rules/testing-and-completion.md +require_string .claude/rules/testing-and-completion.md 'go test ./...' +require_string .claude/rules/testing-and-completion.md '`go test ./...` or `./test/go-unit-tests.sh`' +require_string .claude/rules/testing-and-completion.md './test/claude-agent-tests.sh' + +require_string .claude/rules/provider-surfaces.md ProxySQL +require_string .claude/rules/provider-surfaces.md 'relevant docs' +require_string .claude/rules/provider-surfaces.md docs/ +require_string .claude/rules/provider-surfaces.md README.md +require_string .claude/rules/provider-surfaces.md CONTRIBUTING.md + +require_string .claude/skills/dbdeployer-maintainer/SKILL.md Changed +require_string .claude/skills/dbdeployer-maintainer/SKILL.md Verification +require_string .claude/skills/dbdeployer-maintainer/SKILL.md 'Edge Cases' +require_string .claude/skills/dbdeployer-maintainer/SKILL.md 'Docs Updated' +require_string .claude/skills/dbdeployer-maintainer/SKILL.md '/db-correctness-review' +require_string .claude/skills/dbdeployer-maintainer/SKILL.md '/verification-matrix' +require_string .claude/skills/dbdeployer-maintainer/SKILL.md '/docs-reference-sync' +require_string .claude/skills/dbdeployer-maintainer/SKILL.md '/db-core-expertise' +require_string .claude/skills/db-correctness-review/SKILL.md 'Correctness Risks' +require_string .claude/skills/db-correctness-review/SKILL.md 'Edge Cases Checked' +require_string .claude/skills/db-correctness-review/SKILL.md 'Recommended Follow-up' +require_string .claude/skills/db-correctness-review/SKILL.md '/db-core-expertise' +require_string .claude/skills/db-correctness-review/SKILL.md 'Database semantics' +require_string .claude/skills/db-correctness-review/SKILL.md 'Lifecycle behavior' +require_string .claude/skills/db-correctness-review/SKILL.md 'Packaging and environment assumptions' +require_string .claude/skills/db-correctness-review/SKILL.md 'Topology and routing behavior' +require_string .claude/skills/db-correctness-review/SKILL.md 'Operator edge cases' +require_string .claude/skills/verification-matrix/SKILL.md 'Linux Runner Checks' +require_string .claude/skills/verification-matrix/SKILL.md 'Local Checks' +require_string .claude/skills/verification-matrix/SKILL.md 'Unverified Risk' +require_string .claude/skills/verification-matrix/SKILL.md 'test/' +require_string .claude/skills/verification-matrix/SKILL.md '.github/workflows/' +require_string .claude/skills/verification-matrix/SKILL.md 'go test ./...' +require_string .claude/skills/verification-matrix/SKILL.md './test/go-unit-tests.sh' +require_string .claude/skills/verification-matrix/SKILL.md './test/claude-agent-tests.sh' +require_string .claude/skills/verification-matrix/SKILL.md 'tools/claude-skills/db-core-expertise/**' +require_string .claude/skills/verification-matrix/SKILL.md 'scripts/install_claude_db_skills.sh' +require_string .claude/skills/verification-matrix/SKILL.md 'integration_tests.yml' +require_string .claude/skills/verification-matrix/SKILL.md 'proxysql_integration_tests.yml' +require_string .claude/skills/docs-reference-sync/SKILL.md 'Docs To Update' +require_string .claude/skills/docs-reference-sync/SKILL.md 'Files Updated' +require_string .claude/skills/docs-reference-sync/SKILL.md 'Open Caveats' +require_string .claude/skills/docs-reference-sync/SKILL.md 'Supplemental Output' +require_string .claude/skills/docs-reference-sync/SKILL.md 'must not replace' +require_string .claude/skills/docs-reference-sync/SKILL.md '.claude/CLAUDE.md' +require_string .claude/skills/docs-reference-sync/SKILL.md docs/ +require_string .claude/skills/docs-reference-sync/SKILL.md README.md +require_string .claude/skills/docs-reference-sync/SKILL.md CONTRIBUTING.md +require_string docs/coding/claude-code-agent.md ./test/claude-agent-tests.sh +require_string docs/coding/claude-code-agent.md ./scripts/install_claude_db_skills.sh +require_string docs/coding/claude-code-agent.md 'Troubleshooting' +require_string docs/coding/claude-code-agent.md 'verification-log.jsonl' +require_string docs/coding/claude-code-agent.md 'Task recipes' +require_string docs/coding/claude-code-agent.md 'Provider or CLI behavior change' +require_string docs/coding/claude-code-agent.md 'Docs-only or reference-only change' +require_string docs/coding/claude-code-agent.md 'Repo-local vs reusable' +require_string docs/coding/claude-code-agent.md 'tools/claude-skills/db-core-expertise/' +require_string docs/coding/claude-code-agent.md 'rerun the installer' +require_string CONTRIBUTING.md docs/coding/claude-code-agent.md +require_string CONTRIBUTING.md 'repo-local `.claude/` workflow' +require_string CONTRIBUTING.md 'If you update `tools/claude-skills/db-core-expertise/`' +require_string tools/claude-skills/db-core-expertise/SKILL.md db-core-expertise +require_string tools/claude-skills/db-core-expertise/verification-playbook.md '`go test ./...` or `./test/go-unit-tests.sh`' +require_string tools/claude-skills/db-core-expertise/verification-playbook.md 'sandbox-test' +require_string tools/claude-skills/db-core-expertise/verification-playbook.md 'postgresql-test' +require_string tools/claude-skills/db-core-expertise/verification-playbook.md 'proxysql-test' +require_string tools/claude-skills/db-core-expertise/verification-playbook.md 'proxysql-postgresql' +require_string docs/superpowers/plans/2026-03-31-dbdeployer-specialized-agent-implementation.md 'Final responses must include `Changed`, `Verification`, `Edge Cases`, and `Docs Updated`.' +require_string docs/superpowers/plans/2026-03-31-dbdeployer-specialized-agent-implementation.md 'for section in "Changed" "Verification" "Edge Cases" "Docs Updated"; do' + +jq empty "$ROOT/.claude/settings.json" >/dev/null +require_jq_true "$ROOT/.claude/settings.json" ' + .hooks.PreToolUse + | any( + .matcher == "Bash" and + (.hooks | any( + .type == "command" and + .if == "Bash(*git *)" and + .command == "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-destructive-commands.sh" + )) + ) +' "settings.json must register the git-only PreToolUse Bash hook" +require_jq_true "$ROOT/.claude/settings.json" ' + .hooks.PostToolUse + | any( + .matcher == "Bash" and + (.hooks | any( + .type == "command" and + .command == "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/record-verification-command.sh" + )) + ) +' "settings.json must register the PostToolUse Bash hook" +require_jq_true "$ROOT/.claude/settings.json" ' + .hooks.Stop + | any( + .hooks | any( + .type == "command" and + .command == "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/stop-completion-gate.sh" + ) + ) +' "settings.json must register the Stop hook command path" + +block_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-reset-hard.json")" +printf '%s' "$block_output" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null + +env_block_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-env-git-reset-hard.json")" +printf '%s' "$env_block_output" | jq -e '.hookSpecificOutput.permissionDecision == "deny"' >/dev/null + +safe_output="$("$ROOT/.claude/hooks/block-destructive-commands.sh" < "$FIXTURES/pretool-git-status.json")" +assert_empty_output "$safe_output" "safe git command allowed" + +log_path="$TMPDIR/verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-go-test.json" +grep -Fq "go test ./..." "$log_path" + +log_path="$TMPDIR/verification-log-trimmed.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-go-test-leading-space.json" +require_jq_true "$log_path" 'select(.command == "go test ./...") | true' "verification log should store trimmed commands" + +log_path="$TMPDIR/non-verification-log.jsonl" +CLAUDE_AGENT_VERIFICATION_LOG="$log_path" CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/record-verification-command.sh" < "$FIXTURES/posttool-echo.json" +[[ ! -f "$log_path" ]] + +cat > "$TMPDIR/go-only.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +wrong_verification_class_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'.claude/settings.json' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/go-only.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$wrong_verification_class_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$wrong_verification_class_output" | jq -e '.reason | contains("./test/claude-agent-tests.sh")' >/dev/null + +skill_verification_class_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'tools/claude-skills/db-core-expertise/verification-playbook.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/go-only.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$skill_verification_class_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$skill_verification_class_output" | jq -e '.reason | contains("./test/claude-agent-tests.sh")' >/dev/null + +installer_verification_class_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'scripts/install_claude_db_skills.sh' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/go-only.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$installer_verification_class_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$installer_verification_class_output" | jq -e '.reason | contains("./test/claude-agent-tests.sh")' >/dev/null + +missing_verification_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/missing-log.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_verification_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_verification_output" | jq -e '.reason | contains("go test ./...")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_docs_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$missing_docs_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_docs_output" | jq -e '.reason | contains("docs update")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +missing_sections_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-missing.json" +)" +printf '%s' "$missing_sections_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$missing_sections_output" | jq -e '.reason | contains("Docs Updated")' >/dev/null + +cat > "$TMPDIR/verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +JSON +complete_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'providers/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +assert_empty_output "$complete_output" "completion gate allows verified and documented changes" + +cat > "$TMPDIR/both-verified.jsonl" <<'JSON' +{"session_id":"sess-stop","command":"./test/go-unit-tests.sh","timestamp":"2026-03-31T00:00:00Z"} +{"session_id":"sess-stop","command":"./test/claude-agent-tests.sh","timestamp":"2026-03-31T00:00:01Z"} +JSON +complete_both_classes_output="$( + CLAUDE_AGENT_CHANGED_FILES=$'.claude/settings.json\nproviders/postgresql/provider.go\ndocs/wiki/main-operations.md' \ + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/both-verified.jsonl" \ + CLAUDE_PROJECT_DIR="$ROOT" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +assert_empty_output "$complete_both_classes_output" "completion gate requires both verification classes when both surfaces change" + +git_repo="$TMPDIR/changed-files-repo" +mkdir -p "$git_repo/.claude" +git -C "$git_repo" init -q +git -C "$git_repo" config user.email test@example.com +git -C "$git_repo" config user.name test +printf '{}\n' > "$git_repo/.claude/original settings.json" +git -C "$git_repo" add ".claude/original settings.json" +git -C "$git_repo" commit -qm "initial" +git -C "$git_repo" mv ".claude/original settings.json" ".claude/renamed settings.json" + +fallback_changed_files_output="$( + CLAUDE_AGENT_VERIFICATION_LOG="$TMPDIR/fallback-log.jsonl" \ + CLAUDE_PROJECT_DIR="$git_repo" \ + "$ROOT/.claude/hooks/stop-completion-gate.sh" < "$FIXTURES/stop-sections-complete.json" +)" +printf '%s' "$fallback_changed_files_output" | jq -e '.decision == "block"' >/dev/null +printf '%s' "$fallback_changed_files_output" | jq -e '.reason | contains("./test/claude-agent-tests.sh")' >/dev/null + +bash "$ROOT/tools/claude-skills/db-core-expertise/scripts/smoke-test.sh" + +printf 'PASS: Claude repo assets, docs, hooks, and reusable DB skill templates\n' diff --git a/test/claude-agent/fixtures/posttool-echo.json b/test/claude-agent/fixtures/posttool-echo.json new file mode 100644 index 0000000..a45ed44 --- /dev/null +++ b/test/claude-agent/fixtures/posttool-echo.json @@ -0,0 +1,9 @@ +{ + "session_id": "sess-posttool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PostToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "echo go test ./..." + } +} diff --git a/test/claude-agent/fixtures/posttool-go-test-leading-space.json b/test/claude-agent/fixtures/posttool-go-test-leading-space.json new file mode 100644 index 0000000..42795de --- /dev/null +++ b/test/claude-agent/fixtures/posttool-go-test-leading-space.json @@ -0,0 +1,9 @@ +{ + "session_id": "sess-posttool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PostToolUse", + "tool_name": "Bash", + "tool_input": { + "command": " go test ./... " + } +} diff --git a/test/claude-agent/fixtures/posttool-go-test.json b/test/claude-agent/fixtures/posttool-go-test.json new file mode 100644 index 0000000..dea774a --- /dev/null +++ b/test/claude-agent/fixtures/posttool-go-test.json @@ -0,0 +1,9 @@ +{ + "session_id": "sess-posttool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PostToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "go test ./..." + } +} diff --git a/test/claude-agent/fixtures/pretool-env-git-reset-hard.json b/test/claude-agent/fixtures/pretool-env-git-reset-hard.json new file mode 100644 index 0000000..1c2180b --- /dev/null +++ b/test/claude-agent/fixtures/pretool-env-git-reset-hard.json @@ -0,0 +1,9 @@ +{ + "session_id": "sess-pretool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PreToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "VAR=1 git reset --hard HEAD" + } +} diff --git a/test/claude-agent/fixtures/pretool-git-reset-hard.json b/test/claude-agent/fixtures/pretool-git-reset-hard.json new file mode 100644 index 0000000..f9477ed --- /dev/null +++ b/test/claude-agent/fixtures/pretool-git-reset-hard.json @@ -0,0 +1,9 @@ +{ + "session_id": "sess-pretool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PreToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "git reset --hard HEAD" + } +} diff --git a/test/claude-agent/fixtures/pretool-git-status.json b/test/claude-agent/fixtures/pretool-git-status.json new file mode 100644 index 0000000..4492610 --- /dev/null +++ b/test/claude-agent/fixtures/pretool-git-status.json @@ -0,0 +1,9 @@ +{ + "session_id": "sess-pretool", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "PreToolUse", + "tool_name": "Bash", + "tool_input": { + "command": "git status --short" + } +} diff --git a/test/claude-agent/fixtures/stop-sections-complete.json b/test/claude-agent/fixtures/stop-sections-complete.json new file mode 100644 index 0000000..e0bd821 --- /dev/null +++ b/test/claude-agent/fixtures/stop-sections-complete.json @@ -0,0 +1,7 @@ +{ + "session_id": "sess-stop", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "Stop", + "stop_hook_active": false, + "last_assistant_message": "Changed\n- updated PostgreSQL deployment flow\nVerification\n- ./test/go-unit-tests.sh\nEdge Cases\n- checked package layout and port collisions\nDocs Updated\n- docs/wiki/main-operations.md" +} diff --git a/test/claude-agent/fixtures/stop-sections-missing.json b/test/claude-agent/fixtures/stop-sections-missing.json new file mode 100644 index 0000000..335f5d8 --- /dev/null +++ b/test/claude-agent/fixtures/stop-sections-missing.json @@ -0,0 +1,7 @@ +{ + "session_id": "sess-stop", + "cwd": "/tmp/dbdeployer", + "hook_event_name": "Stop", + "stop_hook_active": false, + "last_assistant_message": "Changed\n- updated PostgreSQL deployment flow\nVerification\n- ./test/go-unit-tests.sh\nEdge Cases\n- checked package layout" +} diff --git a/tools/claude-skills/db-core-expertise/SKILL.md b/tools/claude-skills/db-core-expertise/SKILL.md new file mode 100644 index 0000000..08c03b9 --- /dev/null +++ b/tools/claude-skills/db-core-expertise/SKILL.md @@ -0,0 +1,21 @@ +--- +name: db-core-expertise +description: MySQL, PostgreSQL, ProxySQL, packaging, replication, and topology reference for database tooling. Use when reviewing DB behavior, version differences, edge cases, verification strategy, or docs accuracy. +--- + +When this skill is active: + +1. Read only the supporting files you need from this directory: + - `mysql.md` + - `postgresql.md` + - `proxysql.md` + - `verification-playbook.md` + - `docs-style.md` +2. Treat behavior questions as correctness-sensitive. +3. Surface version and packaging assumptions explicitly. +4. If facts may have changed, verify against official upstream docs or release notes before concluding. +5. Prefer short reproducible checks over broad statements. +6. Return findings under: + - `Relevant Facts` + - `Risks` + - `Suggested Validation` diff --git a/tools/claude-skills/db-core-expertise/docs-style.md b/tools/claude-skills/db-core-expertise/docs-style.md new file mode 100644 index 0000000..bc4091d --- /dev/null +++ b/tools/claude-skills/db-core-expertise/docs-style.md @@ -0,0 +1,7 @@ +# Documentation Style + +- Prefer exact commands over general prose. +- State limitations directly. +- When behavior is provider-specific, name the provider in the heading or paragraph. +- If verification is partial, say what ran and what did not. +- Reference the actual script or workflow name when pointing maintainers to further validation. diff --git a/tools/claude-skills/db-core-expertise/mysql.md b/tools/claude-skills/db-core-expertise/mysql.md new file mode 100644 index 0000000..082e990 --- /dev/null +++ b/tools/claude-skills/db-core-expertise/mysql.md @@ -0,0 +1,14 @@ +# MySQL Notes + +- `dbdeployer` commonly manages tarball-based MySQL layouts under `~/opt/mysql/`. +- Watch for version differences across 8.0, 8.4, and 9.x. +- Verify defaults that changed across releases: auth plugin, mysqlx behavior, packaging names, startup scripts, and server flags. +- Edge cases: + - missing shared libs on Linux + - stale socket files + - port collisions across mysql/mysqlx/admin ports + - replication role ordering +- Good validation: + - `~/sandboxes/.../use -e "SELECT VERSION();"` + - `~/sandboxes/rsandbox_*/check_slaves` + - `~/sandboxes/rsandbox_*/test_replication` diff --git a/tools/claude-skills/db-core-expertise/postgresql.md b/tools/claude-skills/db-core-expertise/postgresql.md new file mode 100644 index 0000000..21ea5e2 --- /dev/null +++ b/tools/claude-skills/db-core-expertise/postgresql.md @@ -0,0 +1,14 @@ +# PostgreSQL Notes + +- `dbdeployer` expects user-space PostgreSQL binaries laid out as `bin/`, `lib/`, and `share/`. +- Debian and apt extraction plus share-dir wiring are common failure points. +- Validate `initdb` share paths, stop/start scripts, socket/config paths, and primary/replica setup. +- Edge cases: + - wrong `-L` share dir for `initdb` + - missing timezone or extension files + - stale `postmaster.pid` + - replica recovery config drift +- Good validation: + - `~/sandboxes/pg_sandbox_*/use -c "SELECT version();"` + - `bash ~/sandboxes/postgresql_repl_*/check_replication` + - write on primary, read on replicas diff --git a/tools/claude-skills/db-core-expertise/proxysql.md b/tools/claude-skills/db-core-expertise/proxysql.md new file mode 100644 index 0000000..b071a33 --- /dev/null +++ b/tools/claude-skills/db-core-expertise/proxysql.md @@ -0,0 +1,14 @@ +# ProxySQL Notes + +- Track the admin and mysql listener pair together. +- Distinguish standalone deployment from topology-attached deployment. +- Validate backend registration, credentials, hostgroup wiring, and start/stop scripts. +- Edge cases: + - admin port collision with listener pair + - binary present but runtime dirs missing + - backend auth mismatch + - PostgreSQL proxy support gaps or work-in-progress behavior +- Good validation: + - `~/sandboxes/*/proxysql/status` + - `~/sandboxes/*/proxysql/use -e "SELECT * FROM mysql_servers;"` + - `~/sandboxes/*/proxysql/use_proxy -e "SELECT 1;"` diff --git a/tools/claude-skills/db-core-expertise/scripts/smoke-test.sh b/tools/claude-skills/db-core-expertise/scripts/smoke-test.sh new file mode 100755 index 0000000..3a04ed5 --- /dev/null +++ b/tools/claude-skills/db-core-expertise/scripts/smoke-test.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# DBDeployer - The MySQL Sandbox +# Copyright © 2006-2020 Giuseppe Maxia +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +for file in SKILL.md mysql.md postgresql.md proxysql.md verification-playbook.md docs-style.md; do + [[ -f "$SKILL_DIR/$file" ]] || { echo "Missing $file" >&2; exit 1; } +done + +grep -Fq "db-core-expertise" "$SKILL_DIR/SKILL.md" +grep -Fq "MySQL" "$SKILL_DIR/mysql.md" +grep -Fq "PostgreSQL" "$SKILL_DIR/postgresql.md" +grep -Fq "ProxySQL" "$SKILL_DIR/proxysql.md" + +echo "db-core-expertise skill looks complete" diff --git a/tools/claude-skills/db-core-expertise/verification-playbook.md b/tools/claude-skills/db-core-expertise/verification-playbook.md new file mode 100644 index 0000000..383c10e --- /dev/null +++ b/tools/claude-skills/db-core-expertise/verification-playbook.md @@ -0,0 +1,11 @@ +# Verification Playbook + +- Start with the smallest truthful local check. +- Escalate to Linux-runner coverage when the change affects packaging, downloads, provider startup, replication, or ProxySQL integration. +- Map surfaces to checks: + - `.claude/**`, `tools/claude-skills/db-core-expertise/**`, and `scripts/install_claude_db_skills.sh` => `./test/claude-agent-tests.sh` + - Go code => `go test ./...` or `./test/go-unit-tests.sh` + - MySQL deployment => `.github/workflows/integration_tests.yml` job `sandbox-test` + - PostgreSQL provider => `.github/workflows/integration_tests.yml` job `postgresql-test` + - ProxySQL => `.github/workflows/proxysql_integration_tests.yml` jobs `proxysql-test` and `proxysql-postgresql` +- If a check did not run, call it residual risk, not completed coverage.