-
Notifications
You must be signed in to change notification settings - Fork 1
Add Claude Code maintainer workflow and reusable DB expertise templates #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
2428c11
ba0ef86
89cadc2
0f8f408
9525e7c
f63e7ae
607f5e8
f654886
aeb4eab
73b7c34
8437f21
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -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 // ""')" | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The command string should be trimmed of leading and trailing whitespace before pattern matching. An agent might accidentally include a leading space (e.g.,
Suggested change
|
||||||
| 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 '{ | ||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| hookSpecificOutput: { | ||||||
| hookEventName: "PreToolUse", | ||||||
| permissionDecision: "deny", | ||||||
| permissionDecisionReason: "Destructive git command blocked in dbdeployer. Use a non-destructive alternative." | ||||||
| } | ||||||
| }' | ||||||
| exit 0 | ||||||
| fi | ||||||
| done | ||||||
|
|
||||||
| exit 0 | ||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -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 | ||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
|
||||||
| 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:]]+$//')" | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In addition to trimming leading and trailing whitespace, it is safer to normalize internal whitespace sequences to a single space. This ensures that commands like
Suggested change
|
||||||
|
|
||||||
| 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" | ||||||
| ;; | ||||||
|
Comment on lines
+19
to
+42
|
||||||
| esac | ||||||
|
|
||||||
| exit 0 | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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 | ||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| 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 --) | ||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fallback logic using |
||||||||||||||||||||
|
|
||||||||||||||||||||
| 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") | ||||||||||||||||||||
|
Comment on lines
+104
to
+105
|
||||||||||||||||||||
| 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") | |
| if [[ "$requires_go_verification" -eq 1 ]]; then | |
| if ! has_logged_command "go test ./..."; then | |
| missing_verification+=("go test ./...") | |
| fi | |
| if ! has_logged_command "./test/go-unit-tests.sh"; then | |
| missing_verification+=("./test/go-unit-tests.sh") | |
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" | ||
| } | ||
| ] | ||
| } | ||
| ] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add required copyright header to unblock CI.
The pipeline reports this file fails the sanity copyright check, so merge is currently blocked.
🧩 Minimal fix
#!/usr/bin/env bash +# Copyright (c) ProxySQL. All rights reserved. set -euo pipefail📝 Committable suggestion
🧰 Tools
🪛 GitHub Actions: CI
[error] 1-1: Sanity check failed (copyright). File has no copyright.
🤖 Prompt for AI Agents