{"owner":"sysown","repo":"proxysql","hasSkills":true,"totalSkillsCount":31,"totalTokensCount":14163,"categories":["claude-rule","anthropic-skill","root-instruction","cursor-rule","windsurf-rule","cline-rule","roo-rule","mcp-config","marketplace","plugin-manifest","copilot-instructions","subagent-persona"],"hasMcp":true,"mcpConfig":{"mcpServers":{"proxysql":{"command":"npx","args":["-y","@modelcontextprotocol/server-proxysql"]}}},"found":["CLAUDE.md","test/infra/SKILL.md","INSTRUCTIONS.md","RULES.md","PROMPT.md","PROMPTS.md","SYSTEM.md","ROUTING.md","SKILLS.md",".cursorrules",".windsurfrules",".clinerules",".roorules",".aideprules",".roomodes","llms.txt","llms-full.txt","mcp.json","marketplace.json","plugin.json",".github/copilot-instructions.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json","doc/agents/README.md","doc/agents/common-mistakes.md","doc/agents/project-conventions.md","doc/agents/task-assignment-template.md","plugins/genai/README.md","scripts/release-tools/README.md","tools/pgsql_user_sync/README.md"],"skills":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nProxySQL is a high-performance, protocol-aware proxy for MySQL (and forks like MariaDB, Percona Server) and PostgreSQL. Written in C++17, it provides connection pooling, query routing, caching, and monitoring. Licensed under GPL.\n\n## Build Commands\n\nThe build system is GNU Make-based with a three-stage pipeline: `deps` → `lib` → `src`.\n\n```bash\n# Full release build (auto-detects -j based on nproc/hw.ncpu)\nmake\n\n# Debug build (-O0, -ggdb, -DDEBUG)\nmake debug\n\n# Build with ASAN (requires no jemalloc)\nNOJEMALLOC=1 WITHASAN=1 make build_deps_debug && make debug && make build_tap_test_debug\n\n# Build TAP tests (requires proxysql binary built first)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n\n# Clean\nmake clean                    # clean src/lib\nmake cleanall                 # clean everything including deps\n\n# Build packages\nmake packages\n```\n\n### Feature Tiers\n\nThe same codebase produces three product tiers via feature flags:\n\n| Tier | Flag | Version | Adds |\n|------|------|---------|------|\n| Stable | (default) | v3.0.x | Core proxy |\n| Innovative | `PROXYSQL31=1` | v3.1.x | FFTO, TSDB |\n| Plugin Chassis | `PROXYSQL40=1` | v4.0.x | Plugin loader + ABI (4-phase lifecycle, query-hook, shared Prometheus); builds and packages all v4.0 plugins including mysqlx and genai/MCP |\n\n**`PROXYSQL40=1` implies `PROXYSQL31=1` which implies `PROXYSQLFFTO=1` and `PROXYSQLTSDB=1`.**\nThere is no separate `PROXYSQLGENAI` flag — `PROXYSQL40=1` builds and packages all v4.0 plugins (mysqlx, genai/MCP, anomaly detection). All AI/MCP/RAG/LLM features live in `plugins/genai/` and load as a `.so` at runtime.\n\n### Building a tier — pass the flag on EVERY make, and clean when switching (IMPORTANT)\n\n**CI never builds the bare default.** Every CI package/test build sets a tier flag: `PROXYSQL31=1` (v3.1) or `PROXYSQL40=1` (v4.0/genai) — see `.github/workflows/CI-*.yml`. Build with the tier you are targeting. **Bare `make` compiles the Stable tier with FFTO and TSDB left OUT** (`MySQLFFTO.cpp`/`PgSQLFFTO.cpp` are excluded and the `#ifdef PROXYSQLFFTO` symbols like `*_thread___ffto_max_buffer_size` are not defined). For most work, build `PROXYSQL31=1` (or `PROXYSQL40=1` if touching plugins/genai).\n\n**The Makefile does NOT track the tier flag between invocations.** Object files and `lib/libproxysql.a` produced under one tier are silently reused when you next build under a different tier (or against a tree someone else built under a different tier). The classic symptom is a link failure:\n\n```\nundefined reference to `mysql_thread___ffto_max_buffer_size'\nundefined reference to `pgsql_thread___ffto_max_buffer_size'\n```\n\nThis is **not** a real breakage and **not** a bug in the default build — it is a stale-object *tier mismatch* (e.g. an FFTO-enabled `libproxysql.a` linked against a `main.o` compiled without `PROXYSQLFFTO`). Do **not** \"fix\" it by dropping the tier flag.\n\nFix / avoid it by cleaning when the tier changes, and by passing the SAME tier flag on every make in a session:\n\n```bash\n# Switching tiers (or unsure what the tree was last built with): clean first.\nmake clean                       # clears lib/ + src/ objects and libproxysql.a\nPROXYSQL31=1 make -j$(nproc)      # then build the tier you want, consistently\n# If deps were built under a different tier, also: make cleanall  (rebuilds deps — slow)\n```\n\n### Build Flags\n\n- `NOJEMALLOC=1` — disable jemalloc\n- `WITHASAN=1` — enable AddressSanitizer (requires `NOJEMALLOC=1`)\n- `WITHGCOV=1` — enable code coverage\n- `PROXYSQLCLICKHOUSE=1` — enabled by default in current builds\n\n## Testing\n\nTests use TAP (Test Anything Protocol) with Docker-based backend infrastructure.\n\n### Running TAP tests — DO NOT manually set up Docker containers\n\n**ALWAYS use `run-tests-isolated.bash`**. It handles infrastructure setup, ProxySQL start, test execution, and cleanup. Never manually create Docker networks, start containers, or run init scripts — the runner does all of that.\n\n**The proxysql binary under test must be a DEBUG build.** The isolated harness (`proxysql-tester.py`) issues debug-only admin commands (`LOAD DEBUG FROM DISK`, the `admin-debug` variable — both `#ifdef DEBUG`), so a release binary fails to (re)configure with errors like `Unknown global variable: 'admin-debug'` or `near \"LOAD\": syntax error`. Build with `make debug`, and pass the tier flag consistently (e.g. `PROXYSQL31=1 make debug`). The ProxySQL container runs the workspace-built binary, so after rebuilding, re-run `test/infra/control/start-proxysql-isolated.bash` to recreate **only** the ProxySQL container on the new binary (it leaves the backends up). A plain `ensure-infras.bash` will NOT pick up a rebuilt binary if ProxySQL is already running, and `docker restart` is not the supported mechanism.\n\n```bash\n# Set up infrastructure (backends + ProxySQL container)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/ensure-infras.bash\n\n# Run all tests for a TAP group\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/run-tests-isolated.bash\n\n# Run a SINGLE test within a group — use the TEST_PY_TAP_INCL regex filter.\n# DO NOT create a throwaway group to isolate one test; the test still lives in its\n# real group and you just filter. (See test/infra/SKILL.md and test/infra/README.md.)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=legacy-g4 \\\n  TEST_PY_TAP_INCL=\"pgsql-reg_test_5866_result_format-t\" \\\n  test/infra/control/run-tests-isolated.bash\n\n# Swap in a rebuilt binary without tearing down backends\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/start-proxysql-isolated.bash\n\n# Build test binaries first (requires proxysql binary)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n```\n\nAvailable TAP groups are defined in `test/tap/groups/groups.json`. Group names follow the pattern `<infra>-g<N>` (e.g., `mysql84-g1`, `legacy-g2`, `pgsql16-g1`). `TEST_PY_TAP_INCL` is a regex matched against test names in the group — the documented way to run one test.\n\n### DO NOT\n\n- **DO NOT** manually create Docker networks (`docker network create`)\n- **DO NOT** manually start containers (`docker start`, `docker run`)\n- **DO NOT** run `docker-compose-init.bash` directly — use `ensure-infras.bash`\n- **DO NOT** symlink build artifacts between worktrees — build in each worktree separately\n- **DO NOT** copy source files between worktrees or repos\n- **DO NOT** run `cd test/tap/tests && make` and expect tests to pass without infrastructure\n\n### Test file conventions\n\nTest files follow the naming pattern `test_*.cpp` or `*-t.cpp` in `test/tap/tests/`.\n\nTest binaries are built via a pattern rule in `test/tap/tests/Makefile`: `make <testname>-t` compiles `<testname>-t.cpp` into `<testname>-t`. No special Makefile target is needed for new tests — just add the `.cpp` file and register it in `groups.json`.\n\n### Reporting CI/test failures\n\n**Test quality is paramount on this project. Never dismiss a CI failure as \"pre-existing\" or \"flaky\".** Those words are observations, not analyses, and using them as a conclusion lets real bugs survive.\n\nWhen CI fails on a branch or PR:\n\n1. **Read the actual failure.** Open the failing test log, the proxysql server log it produced, and the test source. Identify the specific assertion, timeout, crash, or non-zero exit. Quote the relevant lines in your report.\n2. **State the root cause, not the symptom.** \"Test X failed\" is a symptom. The root cause is *why* — a race condition, a stale fixture, a resource leak, a protocol regression, an env mismatch, etc.\n3. **Separate two distinct questions** and answer both with evidence:\n   - *Did the current change cause this failure?* — answer via commit-by-commit reasoning and code-path analysis, not just by comparing baseline pass/fail rates.\n   - *Is this test broken regardless of the current change?* — independent question. A failure that pre-dates the change is still a problem to fix or file, not a reason to merge over.\n4. **If the root cause cannot be determined within the session**, say so explicitly and recommend the next investigation step (re-run with logs, instrument the test, file a tracking issue). Do not paper over uncertainty with \"flaky\".\n5. **A repeatedly failing test is a higher-priority bug, not a lower one.** Recurrence is evidence that the failure mode is reproducible — that is exactly what makes it fixable.\n\n## Architecture\n\n### Build Pipeline\n\n```\ndeps/          → builds 25+ vendored dependencies as static libraries\nlib/           → compiles ~121 .cpp files into libproxysql.a\nsrc/main.cpp   → links against libproxysql.a to produce the proxysql binary\n```\n\n### Dual-Protocol Design\n\nMySQL and PostgreSQL share parallel class hierarchies with the same architecture but protocol-specific implementations:\n\n| Layer | MySQL | PostgreSQL |\n|-------|-------|------------|\n| Protocol | `MySQL_Protocol` | `PgSQL_Protocol` |\n| Session | `MySQL_Session` | `PgSQL_Session` |\n| Thread | `MySQL_Thread` | `PgSQL_Thread` |\n| HostGroups | `MySQL_HostGroups_Manager` | `PgSQL_HostGroups_Manager` |\n| Monitor | `MySQL_Monitor` | `PgSQL_Monitor` |\n| Query Processor | `MySQL_Query_Processor` | `PgSQL_Query_Processor` |\n| Logger | `MySQL_Logger` | `PgSQL_Logger` |\n\n### Core Components\n\n- **Admin Interface** (`ProxySQL_Admin.cpp`, `Admin_Handler.cpp`) — SQL-based configuration via SQLite3 backend. Supports runtime config changes without restart. Schema versions tracked in `ProxySQL_Admin_Tables_Definitions.h`.\n- **HostGroups Manager** — Routes connections based on hostgroup assignments. Supports master-slave, Galera, Group Replication, and Aurora topologies.\n- **Query Processor** — Parses queries, matches against routing rules, handles query caching via `Query_Cache`.\n- **Monitor** — Health-checks backends for replication lag, read-only status, and connectivity.\n- **Threading** — Event-based I/O using libev. `Base_Thread` base class with protocol-specific thread managers.\n- **HTTP/REST** (`ProxySQL_HTTP_Server`, `ProxySQL_RESTAPI_Server`) — Metrics and management endpoints.\n\n### Key Dependencies (in deps/)\n\n- `jemalloc` — memory allocator\n- `sqlite3` — admin config storage\n- `mariadb-client-library` — MySQL protocol\n- `postgresql` — PostgreSQL protocol\n- `re2`, `pcre` — regex engines\n- `libev` — event loop\n- `libinjection` — SQL injection detection\n- `lz4`, `zstd` — compression\n- `curl`, `libmicrohttpd`, `libhttpserver` — HTTP\n- `prometheus-cpp` — metrics\n- `libscram` — SCRAM authentication\n\n### Conditional Components\n\n- **FFTO** (Fast Forward Traffic Observer) — `MySQLFFTO.cpp`, `PgSQLFFTO.cpp`\n- **TSDB** — Time-series metrics with embedded dashboard\n- **ClickHouse** — Native ClickHouse protocol support\n- **GenAI / MCP / RAG / LLM** — Lives entirely in `plugins/genai/`\n  as of the carve-out completed in Step 7.  Loaded via `dlopen` when\n  `plugins = (genai)` is configured in `proxysql.cnf`; not part of\n  `libproxysql.a` or the `proxysql` binary.\n\n## Code Layout\n\n- `include/` — All headers (.h/.hpp). Include guards use `#ifndef __CLASS_*_H`.\n- `lib/` — Core library sources (~121 files). One class per file typically.\n- `src/main.cpp` — Entry point, daemon init, thread spawning (~95K lines).\n- `test/tap/` — TAP test framework and tests.\n- `test/infra/` — Docker-based test environments.\n- `.github/workflows/` — CI/CD pipelines (selftests, TAP tests, package builds, CodeQL). **See `doc/GH-Actions/README.md` for the architecture overview** — ProxySQL uses a two-branch caller/reusable split (`CI-*.yml` on `v3.0`, `ci-*.yml` on the `GH-Actions` branch) and the doc is the authoritative reference for how it fits together.\n\n## Agent Guidelines\n\nSee `doc/agents/` for detailed guidance on working with AI coding agents:\n- `doc/agents/project-conventions.md` — ProxySQL-specific rules (directories, build, test harness, git workflow)\n- `doc/agents/task-assignment-template.md` — Template for writing issues assignable to AI agents\n- `doc/agents/common-mistakes.md` — Known agent failure patterns with prevention and detection\n\n### Unit Test Harness\n\nUnit tests live in `test/tap/tests/unit/` and link against `libproxysql.a` via a custom test harness. Tests must use `test_globals.h` and `test_init.h` — see `doc/agents/project-conventions.md` for the full pattern.\n\n## Coding Conventions\n\n- Class names: `PascalCase` with protocol prefixes (`MySQL_`, `PgSQL_`, `ProxySQL_`)\n- Member variables: `snake_case`\n- Constants/macros: `UPPER_SNAKE_CASE`\n- C++17 required; conditional compilation via `#ifdef PROXYSQL31`, `#ifdef PROXYSQL40`, `#ifdef PROXYSQLFFTO`, `#ifdef PROXYSQLTSDB`, `#ifdef PROXYSQLCLICKHOUSE`. (`PROXYSQLGENAI` no longer guards any core code as of Step 7 of the GenAI plugin carve-out — it lives only inside `plugins/genai/` now.)\n- Performance-critical code — consider implications of changes to hot paths\n- RAII for resource management; jemalloc for allocation\n- Pthread mutexes for synchronization; `std::atomic<>` for counters\n","test/infra/SKILL.md":"# ProxySQL Test Infrastructure - Agent Skill Guide\n\nThis guide provides step-by-step instructions for agents to run ProxySQL tests using the Unified CI infrastructure.\n\n## Prerequisites\n\nBefore running tests, ensure:\n1. Docker is installed and running\n2. The `proxysql-ci-base` image is built (see README.md section 0)\n3. You have sudo access for log directory management\n\n## Quick Start - Run a Specific Test Group\n\n```bash\n# 1. Set required environment variables\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"  # or your target group\nexport INFRA_TYPE=\"infra-mysql57-binlog\"  # optional, inferred from group\n\n# 2. Run the full pipeline (starts infra + runs tests)\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Step-by-Step Manual Execution\n\nUse this approach when you need more control or want to debug infrastructure issues.\n\n### Step 1: Environment Setup\n\n```bash\nexport WORKSPACE=$(pwd)\nexport INFRA_ID=\"dev-$USER\"  # Unique namespace for isolation\nexport TAP_GROUP=\"legacy-binlog-g1\"\nsource test/infra/common/env.sh\n```\n\n**Critical Environment Variables:**\n- `INFRA_ID` - **Required**. Unique namespace for containers/networks\n- `TAP_GROUP` - The test group from `test/tap/groups/groups.json`\n- `ROOT_PASSWORD` - Auto-derived from INFRA_ID hash if not set\n\n### Step 2: Start Infrastructure\n\n```bash\n# Option A: Use the helper (recommended)\n./test/infra/control/ensure-infras.bash\n\n# Option B: Manual per-infrastructure startup\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-init.bash\ncd ../../../\n```\n\n### Step 3: Start ProxySQL\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\n./test/infra/control/start-proxysql-isolated.bash\n```\n\nWait for \"Ready.\" message. If it crashes, check logs:\n```bash\ndocker logs proxysql.${INFRA_ID}\n```\n\n### Step 4: Configure ProxySQL Backend\n\n```bash\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./bin/docker-proxy-post.bash\n```\n\n**Verify configuration:**\n```bash\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT hostgroup_id, hostname, port, gtid_port, status FROM mysql_servers;\"\n```\n\n### Step 5: Run Tests\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n**Run only specific tests:**\n```bash\nexport TEST_PY_TAP_INCL=\"test_binlog.*\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Common Issues and Solutions\n\n### Issue: \"Directory Not Empty\" Error\n\n**Cause:** Previous infrastructure data exists.\n\n**Solution:**\n```bash\n# Destroy existing infrastructure first\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\nsudo rm -rf ./logs/infra-mysql57-binlog-${INFRA_ID}\nsudo rm -rf ../../ci_infra_logs/${INFRA_ID}\n```\n\n### Issue: \"Access denied for user 'root'\"\n\n**Cause:** ROOT_PASSWORD not set or empty in ProxySQL.\n\n**Solution:**\n1. Ensure `.env` defines ROOT_PASSWORD:\n   ```\n   ROOT_PASSWORD=${ROOT_PASSWORD:-$(echo -n \"${INFRA_ID:-dev}\" | sha256sum | head -c 10)}\n   ```\n2. Re-run `docker-proxy-post.bash` after setting INFRA_ID\n3. Verify: `docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e \"SELECT username, password FROM mysql_users;\"`\n\n### Issue: \"Max connect timeout reached while reaching hostgroup\"\n\n**Cause:** MySQL containers not running or misconfigured.\n\n**Solution:**\n```bash\n# Check container status\ndocker ps --format \"table {{.Names}}\\t{{.Status}}\" | grep infra-mysql57-binlog\n\n# Check network aliases\ndocker network inspect ${INFRA_ID}_backend\n\n# Restart infrastructure if needed\n```\n\n### Issue: \"GTID: failed to connect to ProxySQL binlog reader on port 6020\"\n\n**Cause:** Reader containers not running or gtid_port misconfigured.\n\n**Solution:**\n1. Verify reader containers are running:\n   ```bash\n   docker ps | grep reader\n   ```\n2. Check mysql_servers has gtid_port set:\n   ```bash\n   docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n     -e \"SELECT hostname, gtid_port FROM mysql_servers;\"\n   ```\n\n### Issue: Test runs but no queries executed (act_queries: 0)\n\n**Cause:** Connection pool not initialized or query routing issue.\n\n**Solution:**\n1. Check mysql_users exist\n2. Verify mysql_query_rules loaded\n3. Check stats_mysql_connection_pool for connections\n4. Try running test individually after infrastructure warms up\n\n## Test Results Location\n\nAfter tests complete, logs are in:\n```\nci_infra_logs/${INFRA_ID}/\n├── proxysql/                    # ProxySQL logs\n│   ├── proxysql.log\n│   └── proxysql.db\n└── tests/proxysql-tester.py/\n    ├── tap_tests.log            # Test runner log\n    └── tests/\n        ├── test_name-t.log      # Individual test output\n        └── test_name-t.proxysql.log  # ProxySQL log during test\n```\n\n**Check test results:**\n```bash\n# Find test exit code\ngrep \"RC:\" ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log\n\n# View compressed logs\nzcat ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log.gz\n```\n\n## Debugging Tips\n\n### 1. Check Container Connectivity\n\n```bash\n# From ProxySQL container, test MySQL connection\ndocker exec -it proxysql.${INFRA_ID} bash\nmysql -h mysql1.infra-mysql57-binlog -P 3306 -u root -p\n\n# Test reader connection\ntelnet mysql1.infra-mysql57-binlog 6020\n```\n\n### 2. Monitor ProxySQL Runtime\n\n```bash\n# Watch connection pool\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_connection_pool;\" -t\n\n# Watch query stats\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_query_digest;\" -t | head -20\n```\n\n### 3. Infrastructure Verification Script\n\n```bash\n# Check all required containers are running\ndocker ps --format \"{{.Names}}\" | grep ${INFRA_ID}\n\n# Verify network\ndocker network ls | grep ${INFRA_ID}\n\n# Check logs for errors\ndocker logs proxysql.${INFRA_ID} 2>&1 | grep -i error | tail -20\n```\n\n## Cleanup\n\n```bash\n# Stop test runner (if still running)\ndocker rm -f test-runner.${INFRA_ID}\n\n# Stop ProxySQL\n./test/infra/control/stop-proxysql-isolated.bash\n\n# Destroy infrastructure\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\n\n# Clean up logs (optional)\nsudo rm -rf ci_infra_logs/${INFRA_ID}\n```\n\n## Testing Different Configurations\n\n### Run a Single Test\n```bash\nexport INFRA_ID=\"single-test\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\nexport TEST_PY_TAP_INCL=\"test_binlog_reader-t\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n### Test with Different INFRA_ID (parallel runs)\n```bash\n# Terminal 1\nexport INFRA_ID=\"test-a\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n\n# Terminal 2 (completely isolated)\nexport INFRA_ID=\"test-b\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Agent Checklist\n\nBefore asking user about test failures:\n\n- [ ] `INFRA_ID` is set and consistent across all commands\n- [ ] `TAP_GROUP` is defined in `test/tap/groups/groups.json`\n- [ ] Infrastructure containers are running (`docker ps`)\n- [ ] ProxySQL container is running and healthy\n- [ ] MySQL servers registered in ProxySQL (`SELECT * FROM mysql_servers`)\n- [ ] mysql_users exist with correct passwords\n- [ ] Test logs exist in `ci_infra_logs/${INFRA_ID}/tests/`\n- [ ] Checked test log for specific error messages\n- [ ] Checked ProxySQL log for crashes or errors\n","INSTRUCTIONS.md":"# Project Instructions & Agent Workflow\n\nPath: `INSTRUCTIONS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/INSTRUCTIONS.md)","RULES.md":"# Development & Architecture Rules\n\nPath: `RULES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/RULES.md)","PROMPT.md":"# Core System Prompt & Persona\n\nPath: `PROMPT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPT.md)","PROMPTS.md":"# Agent Prompts Catalog\n\nPath: `PROMPTS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPTS.md)","SYSTEM.md":"# System Architecture & Agent Directives\n\nPath: `SYSTEM.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SYSTEM.md)","ROUTING.md":"# Multi-Agent Routing & Delegation Matrix\n\nPath: `ROUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/ROUTING.md)","SKILLS.md":"# Workspace Skills & Capabilities Index\n\nPath: `SKILLS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SKILLS.md)",".cursorrules":"# Cursor IDE Native Rules\n\nPath: `.cursorrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursorrules)",".windsurfrules":"# Windsurf Cascade Agent Rules\n\nPath: `.windsurfrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.windsurfrules)",".clinerules":"# Cline Extension Native Directives\n\nPath: `.clinerules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.clinerules)",".roorules":"# Roo Code Autonomous Agent Rules\n\nPath: `.roorules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roorules)",".aideprules":"# Aider Coding Assistant Guidelines\n\nPath: `.aideprules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.aideprules)",".roomodes":"# Roo Code Custom Persona Modes\n\nPath: `.roomodes`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roomodes)","llms.txt":"# LLM Index & Context Digest\n\nPath: `llms.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms.txt)","llms-full.txt":"# LLM Full Documentation Context\n\nPath: `llms-full.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms-full.txt)","mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/mcp.json)","marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/marketplace.json)","plugin.json":"# Plugin Plugin Manifest\n\nPath: `plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugin.json)",".github/copilot-instructions.md":"# GitHub Copilot Instructions\n\nPath: `.github/copilot-instructions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.github/copilot-instructions.md)",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/plugin.json)","doc/agents/README.md":"# Subagent: readme\n\nPath: `doc/agents/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/README.md)","doc/agents/common-mistakes.md":"# Subagent: common-mistakes\n\nPath: `doc/agents/common-mistakes.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/common-mistakes.md)","doc/agents/project-conventions.md":"# Subagent: project-conventions\n\nPath: `doc/agents/project-conventions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/project-conventions.md)","doc/agents/task-assignment-template.md":"# Subagent: task-assignment-template\n\nPath: `doc/agents/task-assignment-template.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/task-assignment-template.md)","plugins/genai/README.md":"# genai Documentation\n\nPath: `plugins/genai/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugins/genai/README.md)","scripts/release-tools/README.md":"# release-tools Documentation\n\nPath: `scripts/release-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/scripts/release-tools/README.md)","tools/pgsql_user_sync/README.md":"# pgsql_user_sync Documentation\n\nPath: `tools/pgsql_user_sync/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/tools/pgsql_user_sync/README.md)"},"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nProxySQL is a high-performance, protocol-aware proxy for MySQL (and forks like MariaDB, Percona Server) and PostgreSQL. Written in C++17, it provides connection pooling, query routing, caching, and monitoring. Licensed under GPL.\n\n## Build Commands\n\nThe build system is GNU Make-based with a three-stage pipeline: `deps` → `lib` → `src`.\n\n```bash\n# Full release build (auto-detects -j based on nproc/hw.ncpu)\nmake\n\n# Debug build (-O0, -ggdb, -DDEBUG)\nmake debug\n\n# Build with ASAN (requires no jemalloc)\nNOJEMALLOC=1 WITHASAN=1 make build_deps_debug && make debug && make build_tap_test_debug\n\n# Build TAP tests (requires proxysql binary built first)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n\n# Clean\nmake clean                    # clean src/lib\nmake cleanall                 # clean everything including deps\n\n# Build packages\nmake packages\n```\n\n### Feature Tiers\n\nThe same codebase produces three product tiers via feature flags:\n\n| Tier | Flag | Version | Adds |\n|------|------|---------|------|\n| Stable | (default) | v3.0.x | Core proxy |\n| Innovative | `PROXYSQL31=1` | v3.1.x | FFTO, TSDB |\n| Plugin Chassis | `PROXYSQL40=1` | v4.0.x | Plugin loader + ABI (4-phase lifecycle, query-hook, shared Prometheus); builds and packages all v4.0 plugins including mysqlx and genai/MCP |\n\n**`PROXYSQL40=1` implies `PROXYSQL31=1` which implies `PROXYSQLFFTO=1` and `PROXYSQLTSDB=1`.**\nThere is no separate `PROXYSQLGENAI` flag — `PROXYSQL40=1` builds and packages all v4.0 plugins (mysqlx, genai/MCP, anomaly detection). All AI/MCP/RAG/LLM features live in `plugins/genai/` and load as a `.so` at runtime.\n\n### Building a tier — pass the flag on EVERY make, and clean when switching (IMPORTANT)\n\n**CI never builds the bare default.** Every CI package/test build sets a tier flag: `PROXYSQL31=1` (v3.1) or `PROXYSQL40=1` (v4.0/genai) — see `.github/workflows/CI-*.yml`. Build with the tier you are targeting. **Bare `make` compiles the Stable tier with FFTO and TSDB left OUT** (`MySQLFFTO.cpp`/`PgSQLFFTO.cpp` are excluded and the `#ifdef PROXYSQLFFTO` symbols like `*_thread___ffto_max_buffer_size` are not defined). For most work, build `PROXYSQL31=1` (or `PROXYSQL40=1` if touching plugins/genai).\n\n**The Makefile does NOT track the tier flag between invocations.** Object files and `lib/libproxysql.a` produced under one tier are silently reused when you next build under a different tier (or against a tree someone else built under a different tier). The classic symptom is a link failure:\n\n```\nundefined reference to `mysql_thread___ffto_max_buffer_size'\nundefined reference to `pgsql_thread___ffto_max_buffer_size'\n```\n\nThis is **not** a real breakage and **not** a bug in the default build — it is a stale-object *tier mismatch* (e.g. an FFTO-enabled `libproxysql.a` linked against a `main.o` compiled without `PROXYSQLFFTO`). Do **not** \"fix\" it by dropping the tier flag.\n\nFix / avoid it by cleaning when the tier changes, and by passing the SAME tier flag on every make in a session:\n\n```bash\n# Switching tiers (or unsure what the tree was last built with): clean first.\nmake clean                       # clears lib/ + src/ objects and libproxysql.a\nPROXYSQL31=1 make -j$(nproc)      # then build the tier you want, consistently\n# If deps were built under a different tier, also: make cleanall  (rebuilds deps — slow)\n```\n\n### Build Flags\n\n- `NOJEMALLOC=1` — disable jemalloc\n- `WITHASAN=1` — enable AddressSanitizer (requires `NOJEMALLOC=1`)\n- `WITHGCOV=1` — enable code coverage\n- `PROXYSQLCLICKHOUSE=1` — enabled by default in current builds\n\n## Testing\n\nTests use TAP (Test Anything Protocol) with Docker-based backend infrastructure.\n\n### Running TAP tests — DO NOT manually set up Docker containers\n\n**ALWAYS use `run-tests-isolated.bash`**. It handles infrastructure setup, ProxySQL start, test execution, and cleanup. Never manually create Docker networks, start containers, or run init scripts — the runner does all of that.\n\n**The proxysql binary under test must be a DEBUG build.** The isolated harness (`proxysql-tester.py`) issues debug-only admin commands (`LOAD DEBUG FROM DISK`, the `admin-debug` variable — both `#ifdef DEBUG`), so a release binary fails to (re)configure with errors like `Unknown global variable: 'admin-debug'` or `near \"LOAD\": syntax error`. Build with `make debug`, and pass the tier flag consistently (e.g. `PROXYSQL31=1 make debug`). The ProxySQL container runs the workspace-built binary, so after rebuilding, re-run `test/infra/control/start-proxysql-isolated.bash` to recreate **only** the ProxySQL container on the new binary (it leaves the backends up). A plain `ensure-infras.bash` will NOT pick up a rebuilt binary if ProxySQL is already running, and `docker restart` is not the supported mechanism.\n\n```bash\n# Set up infrastructure (backends + ProxySQL container)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/ensure-infras.bash\n\n# Run all tests for a TAP group\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/run-tests-isolated.bash\n\n# Run a SINGLE test within a group — use the TEST_PY_TAP_INCL regex filter.\n# DO NOT create a throwaway group to isolate one test; the test still lives in its\n# real group and you just filter. (See test/infra/SKILL.md and test/infra/README.md.)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=legacy-g4 \\\n  TEST_PY_TAP_INCL=\"pgsql-reg_test_5866_result_format-t\" \\\n  test/infra/control/run-tests-isolated.bash\n\n# Swap in a rebuilt binary without tearing down backends\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/start-proxysql-isolated.bash\n\n# Build test binaries first (requires proxysql binary)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n```\n\nAvailable TAP groups are defined in `test/tap/groups/groups.json`. Group names follow the pattern `<infra>-g<N>` (e.g., `mysql84-g1`, `legacy-g2`, `pgsql16-g1`). `TEST_PY_TAP_INCL` is a regex matched against test names in the group — the documented way to run one test.\n\n### DO NOT\n\n- **DO NOT** manually create Docker networks (`docker network create`)\n- **DO NOT** manually start containers (`docker start`, `docker run`)\n- **DO NOT** run `docker-compose-init.bash` directly — use `ensure-infras.bash`\n- **DO NOT** symlink build artifacts between worktrees — build in each worktree separately\n- **DO NOT** copy source files between worktrees or repos\n- **DO NOT** run `cd test/tap/tests && make` and expect tests to pass without infrastructure\n\n### Test file conventions\n\nTest files follow the naming pattern `test_*.cpp` or `*-t.cpp` in `test/tap/tests/`.\n\nTest binaries are built via a pattern rule in `test/tap/tests/Makefile`: `make <testname>-t` compiles `<testname>-t.cpp` into `<testname>-t`. No special Makefile target is needed for new tests — just add the `.cpp` file and register it in `groups.json`.\n\n### Reporting CI/test failures\n\n**Test quality is paramount on this project. Never dismiss a CI failure as \"pre-existing\" or \"flaky\".** Those words are observations, not analyses, and using them as a conclusion lets real bugs survive.\n\nWhen CI fails on a branch or PR:\n\n1. **Read the actual failure.** Open the failing test log, the proxysql server log it produced, and the test source. Identify the specific assertion, timeout, crash, or non-zero exit. Quote the relevant lines in your report.\n2. **State the root cause, not the symptom.** \"Test X failed\" is a symptom. The root cause is *why* — a race condition, a stale fixture, a resource leak, a protocol regression, an env mismatch, etc.\n3. **Separate two distinct questions** and answer both with evidence:\n   - *Did the current change cause this failure?* — answer via commit-by-commit reasoning and code-path analysis, not just by comparing baseline pass/fail rates.\n   - *Is this test broken regardless of the current change?* — independent question. A failure that pre-dates the change is still a problem to fix or file, not a reason to merge over.\n4. **If the root cause cannot be determined within the session**, say so explicitly and recommend the next investigation step (re-run with logs, instrument the test, file a tracking issue). Do not paper over uncertainty with \"flaky\".\n5. **A repeatedly failing test is a higher-priority bug, not a lower one.** Recurrence is evidence that the failure mode is reproducible — that is exactly what makes it fixable.\n\n## Architecture\n\n### Build Pipeline\n\n```\ndeps/          → builds 25+ vendored dependencies as static libraries\nlib/           → compiles ~121 .cpp files into libproxysql.a\nsrc/main.cpp   → links against libproxysql.a to produce the proxysql binary\n```\n\n### Dual-Protocol Design\n\nMySQL and PostgreSQL share parallel class hierarchies with the same architecture but protocol-specific implementations:\n\n| Layer | MySQL | PostgreSQL |\n|-------|-------|------------|\n| Protocol | `MySQL_Protocol` | `PgSQL_Protocol` |\n| Session | `MySQL_Session` | `PgSQL_Session` |\n| Thread | `MySQL_Thread` | `PgSQL_Thread` |\n| HostGroups | `MySQL_HostGroups_Manager` | `PgSQL_HostGroups_Manager` |\n| Monitor | `MySQL_Monitor` | `PgSQL_Monitor` |\n| Query Processor | `MySQL_Query_Processor` | `PgSQL_Query_Processor` |\n| Logger | `MySQL_Logger` | `PgSQL_Logger` |\n\n### Core Components\n\n- **Admin Interface** (`ProxySQL_Admin.cpp`, `Admin_Handler.cpp`) — SQL-based configuration via SQLite3 backend. Supports runtime config changes without restart. Schema versions tracked in `ProxySQL_Admin_Tables_Definitions.h`.\n- **HostGroups Manager** — Routes connections based on hostgroup assignments. Supports master-slave, Galera, Group Replication, and Aurora topologies.\n- **Query Processor** — Parses queries, matches against routing rules, handles query caching via `Query_Cache`.\n- **Monitor** — Health-checks backends for replication lag, read-only status, and connectivity.\n- **Threading** — Event-based I/O using libev. `Base_Thread` base class with protocol-specific thread managers.\n- **HTTP/REST** (`ProxySQL_HTTP_Server`, `ProxySQL_RESTAPI_Server`) — Metrics and management endpoints.\n\n### Key Dependencies (in deps/)\n\n- `jemalloc` — memory allocator\n- `sqlite3` — admin config storage\n- `mariadb-client-library` — MySQL protocol\n- `postgresql` — PostgreSQL protocol\n- `re2`, `pcre` — regex engines\n- `libev` — event loop\n- `libinjection` — SQL injection detection\n- `lz4`, `zstd` — compression\n- `curl`, `libmicrohttpd`, `libhttpserver` — HTTP\n- `prometheus-cpp` — metrics\n- `libscram` — SCRAM authentication\n\n### Conditional Components\n\n- **FFTO** (Fast Forward Traffic Observer) — `MySQLFFTO.cpp`, `PgSQLFFTO.cpp`\n- **TSDB** — Time-series metrics with embedded dashboard\n- **ClickHouse** — Native ClickHouse protocol support\n- **GenAI / MCP / RAG / LLM** — Lives entirely in `plugins/genai/`\n  as of the carve-out completed in Step 7.  Loaded via `dlopen` when\n  `plugins = (genai)` is configured in `proxysql.cnf`; not part of\n  `libproxysql.a` or the `proxysql` binary.\n\n## Code Layout\n\n- `include/` — All headers (.h/.hpp). Include guards use `#ifndef __CLASS_*_H`.\n- `lib/` — Core library sources (~121 files). One class per file typically.\n- `src/main.cpp` — Entry point, daemon init, thread spawning (~95K lines).\n- `test/tap/` — TAP test framework and tests.\n- `test/infra/` — Docker-based test environments.\n- `.github/workflows/` — CI/CD pipelines (selftests, TAP tests, package builds, CodeQL). **See `doc/GH-Actions/README.md` for the architecture overview** — ProxySQL uses a two-branch caller/reusable split (`CI-*.yml` on `v3.0`, `ci-*.yml` on the `GH-Actions` branch) and the doc is the authoritative reference for how it fits together.\n\n## Agent Guidelines\n\nSee `doc/agents/` for detailed guidance on working with AI coding agents:\n- `doc/agents/project-conventions.md` — ProxySQL-specific rules (directories, build, test harness, git workflow)\n- `doc/agents/task-assignment-template.md` — Template for writing issues assignable to AI agents\n- `doc/agents/common-mistakes.md` — Known agent failure patterns with prevention and detection\n\n### Unit Test Harness\n\nUnit tests live in `test/tap/tests/unit/` and link against `libproxysql.a` via a custom test harness. Tests must use `test_globals.h` and `test_init.h` — see `doc/agents/project-conventions.md` for the full pattern.\n\n## Coding Conventions\n\n- Class names: `PascalCase` with protocol prefixes (`MySQL_`, `PgSQL_`, `ProxySQL_`)\n- Member variables: `snake_case`\n- Constants/macros: `UPPER_SNAKE_CASE`\n- C++17 required; conditional compilation via `#ifdef PROXYSQL31`, `#ifdef PROXYSQL40`, `#ifdef PROXYSQLFFTO`, `#ifdef PROXYSQLTSDB`, `#ifdef PROXYSQLCLICKHOUSE`. (`PROXYSQLGENAI` no longer guards any core code as of Step 7 of the GenAI plugin carve-out — it lives only inside `plugins/genai/` now.)\n- Performance-critical code — consider implications of changes to hot paths\n- RAII for resource management; jemalloc for allocation\n- Pthread mutexes for synchronization; `std::atomic<>` for counters\n","test/infra/SKILL.md":"# ProxySQL Test Infrastructure - Agent Skill Guide\n\nThis guide provides step-by-step instructions for agents to run ProxySQL tests using the Unified CI infrastructure.\n\n## Prerequisites\n\nBefore running tests, ensure:\n1. Docker is installed and running\n2. The `proxysql-ci-base` image is built (see README.md section 0)\n3. You have sudo access for log directory management\n\n## Quick Start - Run a Specific Test Group\n\n```bash\n# 1. Set required environment variables\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"  # or your target group\nexport INFRA_TYPE=\"infra-mysql57-binlog\"  # optional, inferred from group\n\n# 2. Run the full pipeline (starts infra + runs tests)\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Step-by-Step Manual Execution\n\nUse this approach when you need more control or want to debug infrastructure issues.\n\n### Step 1: Environment Setup\n\n```bash\nexport WORKSPACE=$(pwd)\nexport INFRA_ID=\"dev-$USER\"  # Unique namespace for isolation\nexport TAP_GROUP=\"legacy-binlog-g1\"\nsource test/infra/common/env.sh\n```\n\n**Critical Environment Variables:**\n- `INFRA_ID` - **Required**. Unique namespace for containers/networks\n- `TAP_GROUP` - The test group from `test/tap/groups/groups.json`\n- `ROOT_PASSWORD` - Auto-derived from INFRA_ID hash if not set\n\n### Step 2: Start Infrastructure\n\n```bash\n# Option A: Use the helper (recommended)\n./test/infra/control/ensure-infras.bash\n\n# Option B: Manual per-infrastructure startup\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-init.bash\ncd ../../../\n```\n\n### Step 3: Start ProxySQL\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\n./test/infra/control/start-proxysql-isolated.bash\n```\n\nWait for \"Ready.\" message. If it crashes, check logs:\n```bash\ndocker logs proxysql.${INFRA_ID}\n```\n\n### Step 4: Configure ProxySQL Backend\n\n```bash\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./bin/docker-proxy-post.bash\n```\n\n**Verify configuration:**\n```bash\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT hostgroup_id, hostname, port, gtid_port, status FROM mysql_servers;\"\n```\n\n### Step 5: Run Tests\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n**Run only specific tests:**\n```bash\nexport TEST_PY_TAP_INCL=\"test_binlog.*\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Common Issues and Solutions\n\n### Issue: \"Directory Not Empty\" Error\n\n**Cause:** Previous infrastructure data exists.\n\n**Solution:**\n```bash\n# Destroy existing infrastructure first\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\nsudo rm -rf ./logs/infra-mysql57-binlog-${INFRA_ID}\nsudo rm -rf ../../ci_infra_logs/${INFRA_ID}\n```\n\n### Issue: \"Access denied for user 'root'\"\n\n**Cause:** ROOT_PASSWORD not set or empty in ProxySQL.\n\n**Solution:**\n1. Ensure `.env` defines ROOT_PASSWORD:\n   ```\n   ROOT_PASSWORD=${ROOT_PASSWORD:-$(echo -n \"${INFRA_ID:-dev}\" | sha256sum | head -c 10)}\n   ```\n2. Re-run `docker-proxy-post.bash` after setting INFRA_ID\n3. Verify: `docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e \"SELECT username, password FROM mysql_users;\"`\n\n### Issue: \"Max connect timeout reached while reaching hostgroup\"\n\n**Cause:** MySQL containers not running or misconfigured.\n\n**Solution:**\n```bash\n# Check container status\ndocker ps --format \"table {{.Names}}\\t{{.Status}}\" | grep infra-mysql57-binlog\n\n# Check network aliases\ndocker network inspect ${INFRA_ID}_backend\n\n# Restart infrastructure if needed\n```\n\n### Issue: \"GTID: failed to connect to ProxySQL binlog reader on port 6020\"\n\n**Cause:** Reader containers not running or gtid_port misconfigured.\n\n**Solution:**\n1. Verify reader containers are running:\n   ```bash\n   docker ps | grep reader\n   ```\n2. Check mysql_servers has gtid_port set:\n   ```bash\n   docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n     -e \"SELECT hostname, gtid_port FROM mysql_servers;\"\n   ```\n\n### Issue: Test runs but no queries executed (act_queries: 0)\n\n**Cause:** Connection pool not initialized or query routing issue.\n\n**Solution:**\n1. Check mysql_users exist\n2. Verify mysql_query_rules loaded\n3. Check stats_mysql_connection_pool for connections\n4. Try running test individually after infrastructure warms up\n\n## Test Results Location\n\nAfter tests complete, logs are in:\n```\nci_infra_logs/${INFRA_ID}/\n├── proxysql/                    # ProxySQL logs\n│   ├── proxysql.log\n│   └── proxysql.db\n└── tests/proxysql-tester.py/\n    ├── tap_tests.log            # Test runner log\n    └── tests/\n        ├── test_name-t.log      # Individual test output\n        └── test_name-t.proxysql.log  # ProxySQL log during test\n```\n\n**Check test results:**\n```bash\n# Find test exit code\ngrep \"RC:\" ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log\n\n# View compressed logs\nzcat ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log.gz\n```\n\n## Debugging Tips\n\n### 1. Check Container Connectivity\n\n```bash\n# From ProxySQL container, test MySQL connection\ndocker exec -it proxysql.${INFRA_ID} bash\nmysql -h mysql1.infra-mysql57-binlog -P 3306 -u root -p\n\n# Test reader connection\ntelnet mysql1.infra-mysql57-binlog 6020\n```\n\n### 2. Monitor ProxySQL Runtime\n\n```bash\n# Watch connection pool\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_connection_pool;\" -t\n\n# Watch query stats\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_query_digest;\" -t | head -20\n```\n\n### 3. Infrastructure Verification Script\n\n```bash\n# Check all required containers are running\ndocker ps --format \"{{.Names}}\" | grep ${INFRA_ID}\n\n# Verify network\ndocker network ls | grep ${INFRA_ID}\n\n# Check logs for errors\ndocker logs proxysql.${INFRA_ID} 2>&1 | grep -i error | tail -20\n```\n\n## Cleanup\n\n```bash\n# Stop test runner (if still running)\ndocker rm -f test-runner.${INFRA_ID}\n\n# Stop ProxySQL\n./test/infra/control/stop-proxysql-isolated.bash\n\n# Destroy infrastructure\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\n\n# Clean up logs (optional)\nsudo rm -rf ci_infra_logs/${INFRA_ID}\n```\n\n## Testing Different Configurations\n\n### Run a Single Test\n```bash\nexport INFRA_ID=\"single-test\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\nexport TEST_PY_TAP_INCL=\"test_binlog_reader-t\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n### Test with Different INFRA_ID (parallel runs)\n```bash\n# Terminal 1\nexport INFRA_ID=\"test-a\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n\n# Terminal 2 (completely isolated)\nexport INFRA_ID=\"test-b\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Agent Checklist\n\nBefore asking user about test failures:\n\n- [ ] `INFRA_ID` is set and consistent across all commands\n- [ ] `TAP_GROUP` is defined in `test/tap/groups/groups.json`\n- [ ] Infrastructure containers are running (`docker ps`)\n- [ ] ProxySQL container is running and healthy\n- [ ] MySQL servers registered in ProxySQL (`SELECT * FROM mysql_servers`)\n- [ ] mysql_users exist with correct passwords\n- [ ] Test logs exist in `ci_infra_logs/${INFRA_ID}/tests/`\n- [ ] Checked test log for specific error messages\n- [ ] Checked ProxySQL log for crashes or errors\n","INSTRUCTIONS.md":"# Project Instructions & Agent Workflow\n\nPath: `INSTRUCTIONS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/INSTRUCTIONS.md)","RULES.md":"# Development & Architecture Rules\n\nPath: `RULES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/RULES.md)","PROMPT.md":"# Core System Prompt & Persona\n\nPath: `PROMPT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPT.md)","PROMPTS.md":"# Agent Prompts Catalog\n\nPath: `PROMPTS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPTS.md)","SYSTEM.md":"# System Architecture & Agent Directives\n\nPath: `SYSTEM.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SYSTEM.md)","ROUTING.md":"# Multi-Agent Routing & Delegation Matrix\n\nPath: `ROUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/ROUTING.md)","SKILLS.md":"# Workspace Skills & Capabilities Index\n\nPath: `SKILLS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SKILLS.md)",".cursorrules":"# Cursor IDE Native Rules\n\nPath: `.cursorrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursorrules)",".windsurfrules":"# Windsurf Cascade Agent Rules\n\nPath: `.windsurfrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.windsurfrules)",".clinerules":"# Cline Extension Native Directives\n\nPath: `.clinerules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.clinerules)",".roorules":"# Roo Code Autonomous Agent Rules\n\nPath: `.roorules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roorules)",".aideprules":"# Aider Coding Assistant Guidelines\n\nPath: `.aideprules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.aideprules)",".roomodes":"# Roo Code Custom Persona Modes\n\nPath: `.roomodes`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roomodes)","llms.txt":"# LLM Index & Context Digest\n\nPath: `llms.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms.txt)","llms-full.txt":"# LLM Full Documentation Context\n\nPath: `llms-full.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms-full.txt)","mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/mcp.json)","marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/marketplace.json)","plugin.json":"# Plugin Plugin Manifest\n\nPath: `plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugin.json)",".github/copilot-instructions.md":"# GitHub Copilot Instructions\n\nPath: `.github/copilot-instructions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.github/copilot-instructions.md)",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/plugin.json)","doc/agents/README.md":"# Subagent: readme\n\nPath: `doc/agents/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/README.md)","doc/agents/common-mistakes.md":"# Subagent: common-mistakes\n\nPath: `doc/agents/common-mistakes.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/common-mistakes.md)","doc/agents/project-conventions.md":"# Subagent: project-conventions\n\nPath: `doc/agents/project-conventions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/project-conventions.md)","doc/agents/task-assignment-template.md":"# Subagent: task-assignment-template\n\nPath: `doc/agents/task-assignment-template.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/task-assignment-template.md)","plugins/genai/README.md":"# genai Documentation\n\nPath: `plugins/genai/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugins/genai/README.md)","scripts/release-tools/README.md":"# release-tools Documentation\n\nPath: `scripts/release-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/scripts/release-tools/README.md)","tools/pgsql_user_sync/README.md":"# pgsql_user_sync Documentation\n\nPath: `tools/pgsql_user_sync/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/tools/pgsql_user_sync/README.md)"},"items":[{"name":".aideprules","path":".aideprules","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.aideprules","title":"Aider Coding Assistant Guidelines","category":"root-instruction","format":"markdown","content":"# Aider Coding Assistant Guidelines\n\nPath: `.aideprules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.aideprules)","tokens":300,"sizeBytes":154},{"name":"INSTRUCTIONS.md","path":"INSTRUCTIONS.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/INSTRUCTIONS.md","title":"Project Instructions & Agent Workflow","category":"root-instruction","format":"markdown","content":"# Project Instructions & Agent Workflow\n\nPath: `INSTRUCTIONS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/INSTRUCTIONS.md)","tokens":300,"sizeBytes":166},{"name":"llms-full.txt","path":"llms-full.txt","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms-full.txt","title":"LLM Full Documentation Context","category":"root-instruction","format":"text","content":"# LLM Full Documentation Context\n\nPath: `llms-full.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms-full.txt)","tokens":300,"sizeBytes":155},{"name":"llms.txt","path":"llms.txt","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms.txt","title":"LLM Index & Context Digest","category":"root-instruction","format":"text","content":"# LLM Index & Context Digest\n\nPath: `llms.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms.txt)","tokens":300,"sizeBytes":141},{"name":"PROMPT.md","path":"PROMPT.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPT.md","title":"Core System Prompt & Persona","category":"root-instruction","format":"markdown","content":"# Core System Prompt & Persona\n\nPath: `PROMPT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPT.md)","tokens":300,"sizeBytes":145},{"name":"PROMPTS.md","path":"PROMPTS.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPTS.md","title":"Agent Prompts Catalog","category":"root-instruction","format":"markdown","content":"# Agent Prompts Catalog\n\nPath: `PROMPTS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPTS.md)","tokens":300,"sizeBytes":140},{"name":"ROUTING.md","path":"ROUTING.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/ROUTING.md","title":"Multi-Agent Routing & Delegation Matrix","category":"root-instruction","format":"markdown","content":"# Multi-Agent Routing & Delegation Matrix\n\nPath: `ROUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/ROUTING.md)","tokens":300,"sizeBytes":158},{"name":"RULES.md","path":"RULES.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/RULES.md","title":"Development & Architecture Rules","category":"root-instruction","format":"markdown","content":"# Development & Architecture Rules\n\nPath: `RULES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/RULES.md)","tokens":300,"sizeBytes":147},{"name":"SKILLS.md","path":"SKILLS.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/SKILLS.md","title":"Workspace Skills & Capabilities Index","category":"root-instruction","format":"markdown","content":"# Workspace Skills & Capabilities Index\n\nPath: `SKILLS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SKILLS.md)","tokens":300,"sizeBytes":154},{"name":"SYSTEM.md","path":"SYSTEM.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/SYSTEM.md","title":"System Architecture & Agent Directives","category":"root-instruction","format":"markdown","content":"# System Architecture & Agent Directives\n\nPath: `SYSTEM.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SYSTEM.md)","tokens":300,"sizeBytes":155},{"name":"SKILL.md","path":"test/infra/SKILL.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/test/infra/SKILL.md","title":"infra","category":"anthropic-skill","format":"markdown","content":"# ProxySQL Test Infrastructure - Agent Skill Guide\n\nThis guide provides step-by-step instructions for agents to run ProxySQL tests using the Unified CI infrastructure.\n\n## Prerequisites\n\nBefore running tests, ensure:\n1. Docker is installed and running\n2. The `proxysql-ci-base` image is built (see README.md section 0)\n3. You have sudo access for log directory management\n\n## Quick Start - Run a Specific Test Group\n\n```bash\n# 1. Set required environment variables\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"  # or your target group\nexport INFRA_TYPE=\"infra-mysql57-binlog\"  # optional, inferred from group\n\n# 2. Run the full pipeline (starts infra + runs tests)\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Step-by-Step Manual Execution\n\nUse this approach when you need more control or want to debug infrastructure issues.\n\n### Step 1: Environment Setup\n\n```bash\nexport WORKSPACE=$(pwd)\nexport INFRA_ID=\"dev-$USER\"  # Unique namespace for isolation\nexport TAP_GROUP=\"legacy-binlog-g1\"\nsource test/infra/common/env.sh\n```\n\n**Critical Environment Variables:**\n- `INFRA_ID` - **Required**. Unique namespace for containers/networks\n- `TAP_GROUP` - The test group from `test/tap/groups/groups.json`\n- `ROOT_PASSWORD` - Auto-derived from INFRA_ID hash if not set\n\n### Step 2: Start Infrastructure\n\n```bash\n# Option A: Use the helper (recommended)\n./test/infra/control/ensure-infras.bash\n\n# Option B: Manual per-infrastructure startup\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-init.bash\ncd ../../../\n```\n\n### Step 3: Start ProxySQL\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\n./test/infra/control/start-proxysql-isolated.bash\n```\n\nWait for \"Ready.\" message. If it crashes, check logs:\n```bash\ndocker logs proxysql.${INFRA_ID}\n```\n\n### Step 4: Configure ProxySQL Backend\n\n```bash\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./bin/docker-proxy-post.bash\n```\n\n**Verify configuration:**\n```bash\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT hostgroup_id, hostname, port, gtid_port, status FROM mysql_servers;\"\n```\n\n### Step 5: Run Tests\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n**Run only specific tests:**\n```bash\nexport TEST_PY_TAP_INCL=\"test_binlog.*\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Common Issues and Solutions\n\n### Issue: \"Directory Not Empty\" Error\n\n**Cause:** Previous infrastructure data exists.\n\n**Solution:**\n```bash\n# Destroy existing infrastructure first\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\nsudo rm -rf ./logs/infra-mysql57-binlog-${INFRA_ID}\nsudo rm -rf ../../ci_infra_logs/${INFRA_ID}\n```\n\n### Issue: \"Access denied for user 'root'\"\n\n**Cause:** ROOT_PASSWORD not set or empty in ProxySQL.\n\n**Solution:**\n1. Ensure `.env` defines ROOT_PASSWORD:\n   ```\n   ROOT_PASSWORD=${ROOT_PASSWORD:-$(echo -n \"${INFRA_ID:-dev}\" | sha256sum | head -c 10)}\n   ```\n2. Re-run `docker-proxy-post.bash` after setting INFRA_ID\n3. Verify: `docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e \"SELECT username, password FROM mysql_users;\"`\n\n### Issue: \"Max connect timeout reached while reaching hostgroup\"\n\n**Cause:** MySQL containers not running or misconfigured.\n\n**Solution:**\n```bash\n# Check container status\ndocker ps --format \"table {{.Names}}\\t{{.Status}}\" | grep infra-mysql57-binlog\n\n# Check network aliases\ndocker network inspect ${INFRA_ID}_backend\n\n# Restart infrastructure if needed\n```\n\n### Issue: \"GTID: failed to connect to ProxySQL binlog reader on port 6020\"\n\n**Cause:** Reader containers not running or gtid_port misconfigured.\n\n**Solution:**\n1. Verify reader containers are running:\n   ```bash\n   docker ps | grep reader\n   ```\n2. Check mysql_servers has gtid_port set:\n   ```bash\n   docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n     -e \"SELECT hostname, gtid_port FROM mysql_servers;\"\n   ```\n\n### Issue: Test runs but no queries executed (act_queries: 0)\n\n**Cause:** Connection pool not initialized or query routing issue.\n\n**Solution:**\n1. Check mysql_users exist\n2. Verify mysql_query_rules loaded\n3. Check stats_mysql_connection_pool for connections\n4. Try running test individually after infrastructure warms up\n\n## Test Results Location\n\nAfter tests complete, logs are in:\n```\nci_infra_logs/${INFRA_ID}/\n├── proxysql/                    # ProxySQL logs\n│   ├── proxysql.log\n│   └── proxysql.db\n└── tests/proxysql-tester.py/\n    ├── tap_tests.log            # Test runner log\n    └── tests/\n        ├── test_name-t.log      # Individual test output\n        └── test_name-t.proxysql.log  # ProxySQL log during test\n```\n\n**Check test results:**\n```bash\n# Find test exit code\ngrep \"RC:\" ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log\n\n# View compressed logs\nzcat ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log.gz\n```\n\n## Debugging Tips\n\n### 1. Check Container Connectivity\n\n```bash\n# From ProxySQL container, test MySQL connection\ndocker exec -it proxysql.${INFRA_ID} bash\nmysql -h mysql1.infra-mysql57-binlog -P 3306 -u root -p\n\n# Test reader connection\ntelnet mysql1.infra-mysql57-binlog 6020\n```\n\n### 2. Monitor ProxySQL Runtime\n\n```bash\n# Watch connection pool\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_connection_pool;\" -t\n\n# Watch query stats\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_query_digest;\" -t | head -20\n```\n\n### 3. Infrastructure Verification Script\n\n```bash\n# Check all required containers are running\ndocker ps --format \"{{.Names}}\" | grep ${INFRA_ID}\n\n# Verify network\ndocker network ls | grep ${INFRA_ID}\n\n# Check logs for errors\ndocker logs proxysql.${INFRA_ID} 2>&1 | grep -i error | tail -20\n```\n\n## Cleanup\n\n```bash\n# Stop test runner (if still running)\ndocker rm -f test-runner.${INFRA_ID}\n\n# Stop ProxySQL\n./test/infra/control/stop-proxysql-isolated.bash\n\n# Destroy infrastructure\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\n\n# Clean up logs (optional)\nsudo rm -rf ci_infra_logs/${INFRA_ID}\n```\n\n## Testing Different Configurations\n\n### Run a Single Test\n```bash\nexport INFRA_ID=\"single-test\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\nexport TEST_PY_TAP_INCL=\"test_binlog_reader-t\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n### Test with Different INFRA_ID (parallel runs)\n```bash\n# Terminal 1\nexport INFRA_ID=\"test-a\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n\n# Terminal 2 (completely isolated)\nexport INFRA_ID=\"test-b\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Agent Checklist\n\nBefore asking user about test failures:\n\n- [ ] `INFRA_ID` is set and consistent across all commands\n- [ ] `TAP_GROUP` is defined in `test/tap/groups/groups.json`\n- [ ] Infrastructure containers are running (`docker ps`)\n- [ ] ProxySQL container is running and healthy\n- [ ] MySQL servers registered in ProxySQL (`SELECT * FROM mysql_servers`)\n- [ ] mysql_users exist with correct passwords\n- [ ] Test logs exist in `ci_infra_logs/${INFRA_ID}/tests/`\n- [ ] Checked test log for specific error messages\n- [ ] Checked ProxySQL log for crashes or errors\n","isInternal":false,"tokens":2068,"sizeBytes":7642},{"name":".cursorrules","path":".cursorrules","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursorrules","title":"Cursor IDE Native Rules","category":"cursor-rule","format":"markdown","content":"# Cursor IDE Native Rules\n\nPath: `.cursorrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursorrules)","tokens":300,"sizeBytes":146},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nProxySQL is a high-performance, protocol-aware proxy for MySQL (and forks like MariaDB, Percona Server) and PostgreSQL. Written in C++17, it provides connection pooling, query routing, caching, and monitoring. Licensed under GPL.\n\n## Build Commands\n\nThe build system is GNU Make-based with a three-stage pipeline: `deps` → `lib` → `src`.\n\n```bash\n# Full release build (auto-detects -j based on nproc/hw.ncpu)\nmake\n\n# Debug build (-O0, -ggdb, -DDEBUG)\nmake debug\n\n# Build with ASAN (requires no jemalloc)\nNOJEMALLOC=1 WITHASAN=1 make build_deps_debug && make debug && make build_tap_test_debug\n\n# Build TAP tests (requires proxysql binary built first)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n\n# Clean\nmake clean                    # clean src/lib\nmake cleanall                 # clean everything including deps\n\n# Build packages\nmake packages\n```\n\n### Feature Tiers\n\nThe same codebase produces three product tiers via feature flags:\n\n| Tier | Flag | Version | Adds |\n|------|------|---------|------|\n| Stable | (default) | v3.0.x | Core proxy |\n| Innovative | `PROXYSQL31=1` | v3.1.x | FFTO, TSDB |\n| Plugin Chassis | `PROXYSQL40=1` | v4.0.x | Plugin loader + ABI (4-phase lifecycle, query-hook, shared Prometheus); builds and packages all v4.0 plugins including mysqlx and genai/MCP |\n\n**`PROXYSQL40=1` implies `PROXYSQL31=1` which implies `PROXYSQLFFTO=1` and `PROXYSQLTSDB=1`.**\nThere is no separate `PROXYSQLGENAI` flag — `PROXYSQL40=1` builds and packages all v4.0 plugins (mysqlx, genai/MCP, anomaly detection). All AI/MCP/RAG/LLM features live in `plugins/genai/` and load as a `.so` at runtime.\n\n### Building a tier — pass the flag on EVERY make, and clean when switching (IMPORTANT)\n\n**CI never builds the bare default.** Every CI package/test build sets a tier flag: `PROXYSQL31=1` (v3.1) or `PROXYSQL40=1` (v4.0/genai) — see `.github/workflows/CI-*.yml`. Build with the tier you are targeting. **Bare `make` compiles the Stable tier with FFTO and TSDB left OUT** (`MySQLFFTO.cpp`/`PgSQLFFTO.cpp` are excluded and the `#ifdef PROXYSQLFFTO` symbols like `*_thread___ffto_max_buffer_size` are not defined). For most work, build `PROXYSQL31=1` (or `PROXYSQL40=1` if touching plugins/genai).\n\n**The Makefile does NOT track the tier flag between invocations.** Object files and `lib/libproxysql.a` produced under one tier are silently reused when you next build under a different tier (or against a tree someone else built under a different tier). The classic symptom is a link failure:\n\n```\nundefined reference to `mysql_thread___ffto_max_buffer_size'\nundefined reference to `pgsql_thread___ffto_max_buffer_size'\n```\n\nThis is **not** a real breakage and **not** a bug in the default build — it is a stale-object *tier mismatch* (e.g. an FFTO-enabled `libproxysql.a` linked against a `main.o` compiled without `PROXYSQLFFTO`). Do **not** \"fix\" it by dropping the tier flag.\n\nFix / avoid it by cleaning when the tier changes, and by passing the SAME tier flag on every make in a session:\n\n```bash\n# Switching tiers (or unsure what the tree was last built with): clean first.\nmake clean                       # clears lib/ + src/ objects and libproxysql.a\nPROXYSQL31=1 make -j$(nproc)      # then build the tier you want, consistently\n# If deps were built under a different tier, also: make cleanall  (rebuilds deps — slow)\n```\n\n### Build Flags\n\n- `NOJEMALLOC=1` — disable jemalloc\n- `WITHASAN=1` — enable AddressSanitizer (requires `NOJEMALLOC=1`)\n- `WITHGCOV=1` — enable code coverage\n- `PROXYSQLCLICKHOUSE=1` — enabled by default in current builds\n\n## Testing\n\nTests use TAP (Test Anything Protocol) with Docker-based backend infrastructure.\n\n### Running TAP tests — DO NOT manually set up Docker containers\n\n**ALWAYS use `run-tests-isolated.bash`**. It handles infrastructure setup, ProxySQL start, test execution, and cleanup. Never manually create Docker networks, start containers, or run init scripts — the runner does all of that.\n\n**The proxysql binary under test must be a DEBUG build.** The isolated harness (`proxysql-tester.py`) issues debug-only admin commands (`LOAD DEBUG FROM DISK`, the `admin-debug` variable — both `#ifdef DEBUG`), so a release binary fails to (re)configure with errors like `Unknown global variable: 'admin-debug'` or `near \"LOAD\": syntax error`. Build with `make debug`, and pass the tier flag consistently (e.g. `PROXYSQL31=1 make debug`). The ProxySQL container runs the workspace-built binary, so after rebuilding, re-run `test/infra/control/start-proxysql-isolated.bash` to recreate **only** the ProxySQL container on the new binary (it leaves the backends up). A plain `ensure-infras.bash` will NOT pick up a rebuilt binary if ProxySQL is already running, and `docker restart` is not the supported mechanism.\n\n```bash\n# Set up infrastructure (backends + ProxySQL container)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/ensure-infras.bash\n\n# Run all tests for a TAP group\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/run-tests-isolated.bash\n\n# Run a SINGLE test within a group — use the TEST_PY_TAP_INCL regex filter.\n# DO NOT create a throwaway group to isolate one test; the test still lives in its\n# real group and you just filter. (See test/infra/SKILL.md and test/infra/README.md.)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=legacy-g4 \\\n  TEST_PY_TAP_INCL=\"pgsql-reg_test_5866_result_format-t\" \\\n  test/infra/control/run-tests-isolated.bash\n\n# Swap in a rebuilt binary without tearing down backends\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/start-proxysql-isolated.bash\n\n# Build test binaries first (requires proxysql binary)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n```\n\nAvailable TAP groups are defined in `test/tap/groups/groups.json`. Group names follow the pattern `<infra>-g<N>` (e.g., `mysql84-g1`, `legacy-g2`, `pgsql16-g1`). `TEST_PY_TAP_INCL` is a regex matched against test names in the group — the documented way to run one test.\n\n### DO NOT\n\n- **DO NOT** manually create Docker networks (`docker network create`)\n- **DO NOT** manually start containers (`docker start`, `docker run`)\n- **DO NOT** run `docker-compose-init.bash` directly — use `ensure-infras.bash`\n- **DO NOT** symlink build artifacts between worktrees — build in each worktree separately\n- **DO NOT** copy source files between worktrees or repos\n- **DO NOT** run `cd test/tap/tests && make` and expect tests to pass without infrastructure\n\n### Test file conventions\n\nTest files follow the naming pattern `test_*.cpp` or `*-t.cpp` in `test/tap/tests/`.\n\nTest binaries are built via a pattern rule in `test/tap/tests/Makefile`: `make <testname>-t` compiles `<testname>-t.cpp` into `<testname>-t`. No special Makefile target is needed for new tests — just add the `.cpp` file and register it in `groups.json`.\n\n### Reporting CI/test failures\n\n**Test quality is paramount on this project. Never dismiss a CI failure as \"pre-existing\" or \"flaky\".** Those words are observations, not analyses, and using them as a conclusion lets real bugs survive.\n\nWhen CI fails on a branch or PR:\n\n1. **Read the actual failure.** Open the failing test log, the proxysql server log it produced, and the test source. Identify the specific assertion, timeout, crash, or non-zero exit. Quote the relevant lines in your report.\n2. **State the root cause, not the symptom.** \"Test X failed\" is a symptom. The root cause is *why* — a race condition, a stale fixture, a resource leak, a protocol regression, an env mismatch, etc.\n3. **Separate two distinct questions** and answer both with evidence:\n   - *Did the current change cause this failure?* — answer via commit-by-commit reasoning and code-path analysis, not just by comparing baseline pass/fail rates.\n   - *Is this test broken regardless of the current change?* — independent question. A failure that pre-dates the change is still a problem to fix or file, not a reason to merge over.\n4. **If the root cause cannot be determined within the session**, say so explicitly and recommend the next investigation step (re-run with logs, instrument the test, file a tracking issue). Do not paper over uncertainty with \"flaky\".\n5. **A repeatedly failing test is a higher-priority bug, not a lower one.** Recurrence is evidence that the failure mode is reproducible — that is exactly what makes it fixable.\n\n## Architecture\n\n### Build Pipeline\n\n```\ndeps/          → builds 25+ vendored dependencies as static libraries\nlib/           → compiles ~121 .cpp files into libproxysql.a\nsrc/main.cpp   → links against libproxysql.a to produce the proxysql binary\n```\n\n### Dual-Protocol Design\n\nMySQL and PostgreSQL share parallel class hierarchies with the same architecture but protocol-specific implementations:\n\n| Layer | MySQL | PostgreSQL |\n|-------|-------|------------|\n| Protocol | `MySQL_Protocol` | `PgSQL_Protocol` |\n| Session | `MySQL_Session` | `PgSQL_Session` |\n| Thread | `MySQL_Thread` | `PgSQL_Thread` |\n| HostGroups | `MySQL_HostGroups_Manager` | `PgSQL_HostGroups_Manager` |\n| Monitor | `MySQL_Monitor` | `PgSQL_Monitor` |\n| Query Processor | `MySQL_Query_Processor` | `PgSQL_Query_Processor` |\n| Logger | `MySQL_Logger` | `PgSQL_Logger` |\n\n### Core Components\n\n- **Admin Interface** (`ProxySQL_Admin.cpp`, `Admin_Handler.cpp`) — SQL-based configuration via SQLite3 backend. Supports runtime config changes without restart. Schema versions tracked in `ProxySQL_Admin_Tables_Definitions.h`.\n- **HostGroups Manager** — Routes connections based on hostgroup assignments. Supports master-slave, Galera, Group Replication, and Aurora topologies.\n- **Query Processor** — Parses queries, matches against routing rules, handles query caching via `Query_Cache`.\n- **Monitor** — Health-checks backends for replication lag, read-only status, and connectivity.\n- **Threading** — Event-based I/O using libev. `Base_Thread` base class with protocol-specific thread managers.\n- **HTTP/REST** (`ProxySQL_HTTP_Server`, `ProxySQL_RESTAPI_Server`) — Metrics and management endpoints.\n\n### Key Dependencies (in deps/)\n\n- `jemalloc` — memory allocator\n- `sqlite3` — admin config storage\n- `mariadb-client-library` — MySQL protocol\n- `postgresql` — PostgreSQL protocol\n- `re2`, `pcre` — regex engines\n- `libev` — event loop\n- `libinjection` — SQL injection detection\n- `lz4`, `zstd` — compression\n- `curl`, `libmicrohttpd`, `libhttpserver` — HTTP\n- `prometheus-cpp` — metrics\n- `libscram` — SCRAM authentication\n\n### Conditional Components\n\n- **FFTO** (Fast Forward Traffic Observer) — `MySQLFFTO.cpp`, `PgSQLFFTO.cpp`\n- **TSDB** — Time-series metrics with embedded dashboard\n- **ClickHouse** — Native ClickHouse protocol support\n- **GenAI / MCP / RAG / LLM** — Lives entirely in `plugins/genai/`\n  as of the carve-out completed in Step 7.  Loaded via `dlopen` when\n  `plugins = (genai)` is configured in `proxysql.cnf`; not part of\n  `libproxysql.a` or the `proxysql` binary.\n\n## Code Layout\n\n- `include/` — All headers (.h/.hpp). Include guards use `#ifndef __CLASS_*_H`.\n- `lib/` — Core library sources (~121 files). One class per file typically.\n- `src/main.cpp` — Entry point, daemon init, thread spawning (~95K lines).\n- `test/tap/` — TAP test framework and tests.\n- `test/infra/` — Docker-based test environments.\n- `.github/workflows/` — CI/CD pipelines (selftests, TAP tests, package builds, CodeQL). **See `doc/GH-Actions/README.md` for the architecture overview** — ProxySQL uses a two-branch caller/reusable split (`CI-*.yml` on `v3.0`, `ci-*.yml` on the `GH-Actions` branch) and the doc is the authoritative reference for how it fits together.\n\n## Agent Guidelines\n\nSee `doc/agents/` for detailed guidance on working with AI coding agents:\n- `doc/agents/project-conventions.md` — ProxySQL-specific rules (directories, build, test harness, git workflow)\n- `doc/agents/task-assignment-template.md` — Template for writing issues assignable to AI agents\n- `doc/agents/common-mistakes.md` — Known agent failure patterns with prevention and detection\n\n### Unit Test Harness\n\nUnit tests live in `test/tap/tests/unit/` and link against `libproxysql.a` via a custom test harness. Tests must use `test_globals.h` and `test_init.h` — see `doc/agents/project-conventions.md` for the full pattern.\n\n## Coding Conventions\n\n- Class names: `PascalCase` with protocol prefixes (`MySQL_`, `PgSQL_`, `ProxySQL_`)\n- Member variables: `snake_case`\n- Constants/macros: `UPPER_SNAKE_CASE`\n- C++17 required; conditional compilation via `#ifdef PROXYSQL31`, `#ifdef PROXYSQL40`, `#ifdef PROXYSQLFFTO`, `#ifdef PROXYSQLTSDB`, `#ifdef PROXYSQLCLICKHOUSE`. (`PROXYSQLGENAI` no longer guards any core code as of Step 7 of the GenAI plugin carve-out — it lives only inside `plugins/genai/` now.)\n- Performance-critical code — consider implications of changes to hot paths\n- RAII for resource management; jemalloc for allocation\n- Pthread mutexes for synchronization; `std::atomic<>` for counters\n","isInternal":false,"tokens":3395,"sizeBytes":13253},{"name":".windsurfrules","path":".windsurfrules","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.windsurfrules","title":"Windsurf Cascade Agent Rules","category":"windsurf-rule","format":"markdown","content":"# Windsurf Cascade Agent Rules\n\nPath: `.windsurfrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.windsurfrules)","tokens":300,"sizeBytes":155},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"# GitHub Copilot Instructions\n\nPath: `.github/copilot-instructions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.github/copilot-instructions.md)","tokens":300,"sizeBytes":188},{"name":".roomodes","path":".roomodes","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roomodes","title":"Roo Code Custom Persona Modes","category":"roo-rule","format":"markdown","content":"# Roo Code Custom Persona Modes\n\nPath: `.roomodes`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roomodes)","tokens":300,"sizeBytes":146},{"name":".roorules","path":".roorules","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roorules","title":"Roo Code Autonomous Agent Rules","category":"roo-rule","format":"markdown","content":"# Roo Code Autonomous Agent Rules\n\nPath: `.roorules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roorules)","tokens":300,"sizeBytes":148},{"name":".clinerules","path":".clinerules","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.clinerules","title":"Cline Extension Native Directives","category":"cline-rule","format":"markdown","content":"# Cline Extension Native Directives\n\nPath: `.clinerules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.clinerules)","tokens":300,"sizeBytes":154},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":194},{"name":"marketplace.json","path":"marketplace.json","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/marketplace.json)","tokens":300,"sizeBytes":164},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":180},{"name":"plugin.json","path":"plugin.json","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugin.json","title":"Plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# Plugin Plugin Manifest\n\nPath: `plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugin.json)","tokens":300,"sizeBytes":143},{"name":"README.md","path":"plugins/genai/README.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugins/genai/README.md","title":"genai Documentation","category":"plugin-manifest","format":"markdown","content":"# genai Documentation\n\nPath: `plugins/genai/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugins/genai/README.md)","tokens":300,"sizeBytes":164},{"name":"README.md","path":"scripts/release-tools/README.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/scripts/release-tools/README.md","title":"release-tools Documentation","category":"plugin-manifest","format":"markdown","content":"# release-tools Documentation\n\nPath: `scripts/release-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/scripts/release-tools/README.md)","tokens":300,"sizeBytes":188},{"name":"README.md","path":"tools/pgsql_user_sync/README.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/tools/pgsql_user_sync/README.md","title":"pgsql_user_sync Documentation","category":"plugin-manifest","format":"markdown","content":"# pgsql_user_sync Documentation\n\nPath: `tools/pgsql_user_sync/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/tools/pgsql_user_sync/README.md)","tokens":300,"sizeBytes":190},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":173},{"name":"mcp.json","path":"mcp.json","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/mcp.json)","tokens":300,"sizeBytes":157},{"name":"common-mistakes.md","path":"doc/agents/common-mistakes.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/common-mistakes.md","title":"Subagent: common-mistakes","category":"subagent-persona","format":"markdown","content":"# Subagent: common-mistakes\n\nPath: `doc/agents/common-mistakes.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/common-mistakes.md)","tokens":300,"sizeBytes":182},{"name":"project-conventions.md","path":"doc/agents/project-conventions.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/project-conventions.md","title":"Subagent: project-conventions","category":"subagent-persona","format":"markdown","content":"# Subagent: project-conventions\n\nPath: `doc/agents/project-conventions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/project-conventions.md)","tokens":300,"sizeBytes":194},{"name":"README.md","path":"doc/agents/README.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/README.md","title":"Subagent: readme","category":"subagent-persona","format":"markdown","content":"# Subagent: readme\n\nPath: `doc/agents/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/README.md)","tokens":300,"sizeBytes":155},{"name":"task-assignment-template.md","path":"doc/agents/task-assignment-template.md","rawUrl":"https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/task-assignment-template.md","title":"Subagent: task-assignment-template","category":"subagent-persona","format":"markdown","content":"# Subagent: task-assignment-template\n\nPath: `doc/agents/task-assignment-template.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/task-assignment-template.md)","tokens":300,"sizeBytes":209}],"systemPromptSnippet":"<yakaai_skills repo=\"sysown/proxysql\">\n<!-- File: .aideprules (Tokens: ~300 | Category: root-instruction) -->\n# Aider Coding Assistant Guidelines\n\nPath: `.aideprules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.aideprules)\n\n<!-- File: INSTRUCTIONS.md (Tokens: ~300 | Category: root-instruction) -->\n# Project Instructions & Agent Workflow\n\nPath: `INSTRUCTIONS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/INSTRUCTIONS.md)\n\n<!-- File: llms-full.txt (Tokens: ~300 | Category: root-instruction) -->\n# LLM Full Documentation Context\n\nPath: `llms-full.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms-full.txt)\n\n<!-- File: llms.txt (Tokens: ~300 | Category: root-instruction) -->\n# LLM Index & Context Digest\n\nPath: `llms.txt`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/llms.txt)\n\n<!-- File: PROMPT.md (Tokens: ~300 | Category: root-instruction) -->\n# Core System Prompt & Persona\n\nPath: `PROMPT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPT.md)\n\n<!-- File: PROMPTS.md (Tokens: ~300 | Category: root-instruction) -->\n# Agent Prompts Catalog\n\nPath: `PROMPTS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/PROMPTS.md)\n\n<!-- File: ROUTING.md (Tokens: ~300 | Category: root-instruction) -->\n# Multi-Agent Routing & Delegation Matrix\n\nPath: `ROUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/ROUTING.md)\n\n<!-- File: RULES.md (Tokens: ~300 | Category: root-instruction) -->\n# Development & Architecture Rules\n\nPath: `RULES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/RULES.md)\n\n<!-- File: SKILLS.md (Tokens: ~300 | Category: root-instruction) -->\n# Workspace Skills & Capabilities Index\n\nPath: `SKILLS.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SKILLS.md)\n\n<!-- File: SYSTEM.md (Tokens: ~300 | Category: root-instruction) -->\n# System Architecture & Agent Directives\n\nPath: `SYSTEM.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/SYSTEM.md)\n\n<!-- File: test/infra/SKILL.md (Tokens: ~2068 | Category: anthropic-skill) -->\n# ProxySQL Test Infrastructure - Agent Skill Guide\n\nThis guide provides step-by-step instructions for agents to run ProxySQL tests using the Unified CI infrastructure.\n\n## Prerequisites\n\nBefore running tests, ensure:\n1. Docker is installed and running\n2. The `proxysql-ci-base` image is built (see README.md section 0)\n3. You have sudo access for log directory management\n\n## Quick Start - Run a Specific Test Group\n\n```bash\n# 1. Set required environment variables\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"  # or your target group\nexport INFRA_TYPE=\"infra-mysql57-binlog\"  # optional, inferred from group\n\n# 2. Run the full pipeline (starts infra + runs tests)\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Step-by-Step Manual Execution\n\nUse this approach when you need more control or want to debug infrastructure issues.\n\n### Step 1: Environment Setup\n\n```bash\nexport WORKSPACE=$(pwd)\nexport INFRA_ID=\"dev-$USER\"  # Unique namespace for isolation\nexport TAP_GROUP=\"legacy-binlog-g1\"\nsource test/infra/common/env.sh\n```\n\n**Critical Environment Variables:**\n- `INFRA_ID` - **Required**. Unique namespace for containers/networks\n- `TAP_GROUP` - The test group from `test/tap/groups/groups.json`\n- `ROOT_PASSWORD` - Auto-derived from INFRA_ID hash if not set\n\n### Step 2: Start Infrastructure\n\n```bash\n# Option A: Use the helper (recommended)\n./test/infra/control/ensure-infras.bash\n\n# Option B: Manual per-infrastructure startup\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-init.bash\ncd ../../../\n```\n\n### Step 3: Start ProxySQL\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\n./test/infra/control/start-proxysql-isolated.bash\n```\n\nWait for \"Ready.\" message. If it crashes, check logs:\n```bash\ndocker logs proxysql.${INFRA_ID}\n```\n\n### Step 4: Configure ProxySQL Backend\n\n```bash\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./bin/docker-proxy-post.bash\n```\n\n**Verify configuration:**\n```bash\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT hostgroup_id, hostname, port, gtid_port, status FROM mysql_servers;\"\n```\n\n### Step 5: Run Tests\n\n```bash\nexport INFRA_ID=\"dev-$USER\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n**Run only specific tests:**\n```bash\nexport TEST_PY_TAP_INCL=\"test_binlog.*\"\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Common Issues and Solutions\n\n### Issue: \"Directory Not Empty\" Error\n\n**Cause:** Previous infrastructure data exists.\n\n**Solution:**\n```bash\n# Destroy existing infrastructure first\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\nsudo rm -rf ./logs/infra-mysql57-binlog-${INFRA_ID}\nsudo rm -rf ../../ci_infra_logs/${INFRA_ID}\n```\n\n### Issue: \"Access denied for user 'root'\"\n\n**Cause:** ROOT_PASSWORD not set or empty in ProxySQL.\n\n**Solution:**\n1. Ensure `.env` defines ROOT_PASSWORD:\n   ```\n   ROOT_PASSWORD=${ROOT_PASSWORD:-$(echo -n \"${INFRA_ID:-dev}\" | sha256sum | head -c 10)}\n   ```\n2. Re-run `docker-proxy-post.bash` after setting INFRA_ID\n3. Verify: `docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e \"SELECT username, password FROM mysql_users;\"`\n\n### Issue: \"Max connect timeout reached while reaching hostgroup\"\n\n**Cause:** MySQL containers not running or misconfigured.\n\n**Solution:**\n```bash\n# Check container status\ndocker ps --format \"table {{.Names}}\\t{{.Status}}\" | grep infra-mysql57-binlog\n\n# Check network aliases\ndocker network inspect ${INFRA_ID}_backend\n\n# Restart infrastructure if needed\n```\n\n### Issue: \"GTID: failed to connect to ProxySQL binlog reader on port 6020\"\n\n**Cause:** Reader containers not running or gtid_port misconfigured.\n\n**Solution:**\n1. Verify reader containers are running:\n   ```bash\n   docker ps | grep reader\n   ```\n2. Check mysql_servers has gtid_port set:\n   ```bash\n   docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n     -e \"SELECT hostname, gtid_port FROM mysql_servers;\"\n   ```\n\n### Issue: Test runs but no queries executed (act_queries: 0)\n\n**Cause:** Connection pool not initialized or query routing issue.\n\n**Solution:**\n1. Check mysql_users exist\n2. Verify mysql_query_rules loaded\n3. Check stats_mysql_connection_pool for connections\n4. Try running test individually after infrastructure warms up\n\n## Test Results Location\n\nAfter tests complete, logs are in:\n```\nci_infra_logs/${INFRA_ID}/\n├── proxysql/                    # ProxySQL logs\n│   ├── proxysql.log\n│   └── proxysql.db\n└── tests/proxysql-tester.py/\n    ├── tap_tests.log            # Test runner log\n    └── tests/\n        ├── test_name-t.log      # Individual test output\n        └── test_name-t.proxysql.log  # ProxySQL log during test\n```\n\n**Check test results:**\n```bash\n# Find test exit code\ngrep \"RC:\" ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log\n\n# View compressed logs\nzcat ci_infra_logs/${INFRA_ID}/tests/proxysql-tester.py/tests/test_name-t.log.gz\n```\n\n## Debugging Tips\n\n### 1. Check Container Connectivity\n\n```bash\n# From ProxySQL container, test MySQL connection\ndocker exec -it proxysql.${INFRA_ID} bash\nmysql -h mysql1.infra-mysql57-binlog -P 3306 -u root -p\n\n# Test reader connection\ntelnet mysql1.infra-mysql57-binlog 6020\n```\n\n### 2. Monitor ProxySQL Runtime\n\n```bash\n# Watch connection pool\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_connection_pool;\" -t\n\n# Watch query stats\ndocker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \\\n  -e \"SELECT * FROM stats_mysql_query_digest;\" -t | head -20\n```\n\n### 3. Infrastructure Verification Script\n\n```bash\n# Check all required containers are running\ndocker ps --format \"{{.Names}}\" | grep ${INFRA_ID}\n\n# Verify network\ndocker network ls | grep ${INFRA_ID}\n\n# Check logs for errors\ndocker logs proxysql.${INFRA_ID} 2>&1 | grep -i error | tail -20\n```\n\n## Cleanup\n\n```bash\n# Stop test runner (if still running)\ndocker rm -f test-runner.${INFRA_ID}\n\n# Stop ProxySQL\n./test/infra/control/stop-proxysql-isolated.bash\n\n# Destroy infrastructure\ncd test/infra/infra-mysql57-binlog\nexport INFRA_ID=\"dev-$USER\"\n./docker-compose-destroy.bash\n\n# Clean up logs (optional)\nsudo rm -rf ci_infra_logs/${INFRA_ID}\n```\n\n## Testing Different Configurations\n\n### Run a Single Test\n```bash\nexport INFRA_ID=\"single-test\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\nexport TEST_PY_TAP_INCL=\"test_binlog_reader-t\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n### Test with Different INFRA_ID (parallel runs)\n```bash\n# Terminal 1\nexport INFRA_ID=\"test-a\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n\n# Terminal 2 (completely isolated)\nexport INFRA_ID=\"test-b\"\nexport TAP_GROUP=\"legacy-binlog-g1\"\n./test/infra/control/ensure-infras.bash\n./test/infra/control/run-tests-isolated.bash\n```\n\n## Agent Checklist\n\nBefore asking user about test failures:\n\n- [ ] `INFRA_ID` is set and consistent across all commands\n- [ ] `TAP_GROUP` is defined in `test/tap/groups/groups.json`\n- [ ] Infrastructure containers are running (`docker ps`)\n- [ ] ProxySQL container is running and healthy\n- [ ] MySQL servers registered in ProxySQL (`SELECT * FROM mysql_servers`)\n- [ ] mysql_users exist with correct passwords\n- [ ] Test logs exist in `ci_infra_logs/${INFRA_ID}/tests/`\n- [ ] Checked test log for specific error messages\n- [ ] Checked ProxySQL log for crashes or errors\n\n<!-- File: .cursorrules (Tokens: ~300 | Category: cursor-rule) -->\n# Cursor IDE Native Rules\n\nPath: `.cursorrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursorrules)\n\n<!-- File: CLAUDE.md (Tokens: ~3395 | Category: claude-rule) -->\n# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nProxySQL is a high-performance, protocol-aware proxy for MySQL (and forks like MariaDB, Percona Server) and PostgreSQL. Written in C++17, it provides connection pooling, query routing, caching, and monitoring. Licensed under GPL.\n\n## Build Commands\n\nThe build system is GNU Make-based with a three-stage pipeline: `deps` → `lib` → `src`.\n\n```bash\n# Full release build (auto-detects -j based on nproc/hw.ncpu)\nmake\n\n# Debug build (-O0, -ggdb, -DDEBUG)\nmake debug\n\n# Build with ASAN (requires no jemalloc)\nNOJEMALLOC=1 WITHASAN=1 make build_deps_debug && make debug && make build_tap_test_debug\n\n# Build TAP tests (requires proxysql binary built first)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n\n# Clean\nmake clean                    # clean src/lib\nmake cleanall                 # clean everything including deps\n\n# Build packages\nmake packages\n```\n\n### Feature Tiers\n\nThe same codebase produces three product tiers via feature flags:\n\n| Tier | Flag | Version | Adds |\n|------|------|---------|------|\n| Stable | (default) | v3.0.x | Core proxy |\n| Innovative | `PROXYSQL31=1` | v3.1.x | FFTO, TSDB |\n| Plugin Chassis | `PROXYSQL40=1` | v4.0.x | Plugin loader + ABI (4-phase lifecycle, query-hook, shared Prometheus); builds and packages all v4.0 plugins including mysqlx and genai/MCP |\n\n**`PROXYSQL40=1` implies `PROXYSQL31=1` which implies `PROXYSQLFFTO=1` and `PROXYSQLTSDB=1`.**\nThere is no separate `PROXYSQLGENAI` flag — `PROXYSQL40=1` builds and packages all v4.0 plugins (mysqlx, genai/MCP, anomaly detection). All AI/MCP/RAG/LLM features live in `plugins/genai/` and load as a `.so` at runtime.\n\n### Building a tier — pass the flag on EVERY make, and clean when switching (IMPORTANT)\n\n**CI never builds the bare default.** Every CI package/test build sets a tier flag: `PROXYSQL31=1` (v3.1) or `PROXYSQL40=1` (v4.0/genai) — see `.github/workflows/CI-*.yml`. Build with the tier you are targeting. **Bare `make` compiles the Stable tier with FFTO and TSDB left OUT** (`MySQLFFTO.cpp`/`PgSQLFFTO.cpp` are excluded and the `#ifdef PROXYSQLFFTO` symbols like `*_thread___ffto_max_buffer_size` are not defined). For most work, build `PROXYSQL31=1` (or `PROXYSQL40=1` if touching plugins/genai).\n\n**The Makefile does NOT track the tier flag between invocations.** Object files and `lib/libproxysql.a` produced under one tier are silently reused when you next build under a different tier (or against a tree someone else built under a different tier). The classic symptom is a link failure:\n\n```\nundefined reference to `mysql_thread___ffto_max_buffer_size'\nundefined reference to `pgsql_thread___ffto_max_buffer_size'\n```\n\nThis is **not** a real breakage and **not** a bug in the default build — it is a stale-object *tier mismatch* (e.g. an FFTO-enabled `libproxysql.a` linked against a `main.o` compiled without `PROXYSQLFFTO`). Do **not** \"fix\" it by dropping the tier flag.\n\nFix / avoid it by cleaning when the tier changes, and by passing the SAME tier flag on every make in a session:\n\n```bash\n# Switching tiers (or unsure what the tree was last built with): clean first.\nmake clean                       # clears lib/ + src/ objects and libproxysql.a\nPROXYSQL31=1 make -j$(nproc)      # then build the tier you want, consistently\n# If deps were built under a different tier, also: make cleanall  (rebuilds deps — slow)\n```\n\n### Build Flags\n\n- `NOJEMALLOC=1` — disable jemalloc\n- `WITHASAN=1` — enable AddressSanitizer (requires `NOJEMALLOC=1`)\n- `WITHGCOV=1` — enable code coverage\n- `PROXYSQLCLICKHOUSE=1` — enabled by default in current builds\n\n## Testing\n\nTests use TAP (Test Anything Protocol) with Docker-based backend infrastructure.\n\n### Running TAP tests — DO NOT manually set up Docker containers\n\n**ALWAYS use `run-tests-isolated.bash`**. It handles infrastructure setup, ProxySQL start, test execution, and cleanup. Never manually create Docker networks, start containers, or run init scripts — the runner does all of that.\n\n**The proxysql binary under test must be a DEBUG build.** The isolated harness (`proxysql-tester.py`) issues debug-only admin commands (`LOAD DEBUG FROM DISK`, the `admin-debug` variable — both `#ifdef DEBUG`), so a release binary fails to (re)configure with errors like `Unknown global variable: 'admin-debug'` or `near \"LOAD\": syntax error`. Build with `make debug`, and pass the tier flag consistently (e.g. `PROXYSQL31=1 make debug`). The ProxySQL container runs the workspace-built binary, so after rebuilding, re-run `test/infra/control/start-proxysql-isolated.bash` to recreate **only** the ProxySQL container on the new binary (it leaves the backends up). A plain `ensure-infras.bash` will NOT pick up a rebuilt binary if ProxySQL is already running, and `docker restart` is not the supported mechanism.\n\n```bash\n# Set up infrastructure (backends + ProxySQL container)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/ensure-infras.bash\n\n# Run all tests for a TAP group\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/run-tests-isolated.bash\n\n# Run a SINGLE test within a group — use the TEST_PY_TAP_INCL regex filter.\n# DO NOT create a throwaway group to isolate one test; the test still lives in its\n# real group and you just filter. (See test/infra/SKILL.md and test/infra/README.md.)\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=legacy-g4 \\\n  TEST_PY_TAP_INCL=\"pgsql-reg_test_5866_result_format-t\" \\\n  test/infra/control/run-tests-isolated.bash\n\n# Swap in a rebuilt binary without tearing down backends\nWORKSPACE=$(pwd) INFRA_ID=dev-$USER TAP_GROUP=mysql84-g1 test/infra/control/start-proxysql-isolated.bash\n\n# Build test binaries first (requires proxysql binary)\nmake build_tap_tests          # release\nmake build_tap_test_debug     # debug\n```\n\nAvailable TAP groups are defined in `test/tap/groups/groups.json`. Group names follow the pattern `<infra>-g<N>` (e.g., `mysql84-g1`, `legacy-g2`, `pgsql16-g1`). `TEST_PY_TAP_INCL` is a regex matched against test names in the group — the documented way to run one test.\n\n### DO NOT\n\n- **DO NOT** manually create Docker networks (`docker network create`)\n- **DO NOT** manually start containers (`docker start`, `docker run`)\n- **DO NOT** run `docker-compose-init.bash` directly — use `ensure-infras.bash`\n- **DO NOT** symlink build artifacts between worktrees — build in each worktree separately\n- **DO NOT** copy source files between worktrees or repos\n- **DO NOT** run `cd test/tap/tests && make` and expect tests to pass without infrastructure\n\n### Test file conventions\n\nTest files follow the naming pattern `test_*.cpp` or `*-t.cpp` in `test/tap/tests/`.\n\nTest binaries are built via a pattern rule in `test/tap/tests/Makefile`: `make <testname>-t` compiles `<testname>-t.cpp` into `<testname>-t`. No special Makefile target is needed for new tests — just add the `.cpp` file and register it in `groups.json`.\n\n### Reporting CI/test failures\n\n**Test quality is paramount on this project. Never dismiss a CI failure as \"pre-existing\" or \"flaky\".** Those words are observations, not analyses, and using them as a conclusion lets real bugs survive.\n\nWhen CI fails on a branch or PR:\n\n1. **Read the actual failure.** Open the failing test log, the proxysql server log it produced, and the test source. Identify the specific assertion, timeout, crash, or non-zero exit. Quote the relevant lines in your report.\n2. **State the root cause, not the symptom.** \"Test X failed\" is a symptom. The root cause is *why* — a race condition, a stale fixture, a resource leak, a protocol regression, an env mismatch, etc.\n3. **Separate two distinct questions** and answer both with evidence:\n   - *Did the current change cause this failure?* — answer via commit-by-commit reasoning and code-path analysis, not just by comparing baseline pass/fail rates.\n   - *Is this test broken regardless of the current change?* — independent question. A failure that pre-dates the change is still a problem to fix or file, not a reason to merge over.\n4. **If the root cause cannot be determined within the session**, say so explicitly and recommend the next investigation step (re-run with logs, instrument the test, file a tracking issue). Do not paper over uncertainty with \"flaky\".\n5. **A repeatedly failing test is a higher-priority bug, not a lower one.** Recurrence is evidence that the failure mode is reproducible — that is exactly what makes it fixable.\n\n## Architecture\n\n### Build Pipeline\n\n```\ndeps/          → builds 25+ vendored dependencies as static libraries\nlib/           → compiles ~121 .cpp files into libproxysql.a\nsrc/main.cpp   → links against libproxysql.a to produce the proxysql binary\n```\n\n### Dual-Protocol Design\n\nMySQL and PostgreSQL share parallel class hierarchies with the same architecture but protocol-specific implementations:\n\n| Layer | MySQL | PostgreSQL |\n|-------|-------|------------|\n| Protocol | `MySQL_Protocol` | `PgSQL_Protocol` |\n| Session | `MySQL_Session` | `PgSQL_Session` |\n| Thread | `MySQL_Thread` | `PgSQL_Thread` |\n| HostGroups | `MySQL_HostGroups_Manager` | `PgSQL_HostGroups_Manager` |\n| Monitor | `MySQL_Monitor` | `PgSQL_Monitor` |\n| Query Processor | `MySQL_Query_Processor` | `PgSQL_Query_Processor` |\n| Logger | `MySQL_Logger` | `PgSQL_Logger` |\n\n### Core Components\n\n- **Admin Interface** (`ProxySQL_Admin.cpp`, `Admin_Handler.cpp`) — SQL-based configuration via SQLite3 backend. Supports runtime config changes without restart. Schema versions tracked in `ProxySQL_Admin_Tables_Definitions.h`.\n- **HostGroups Manager** — Routes connections based on hostgroup assignments. Supports master-slave, Galera, Group Replication, and Aurora topologies.\n- **Query Processor** — Parses queries, matches against routing rules, handles query caching via `Query_Cache`.\n- **Monitor** — Health-checks backends for replication lag, read-only status, and connectivity.\n- **Threading** — Event-based I/O using libev. `Base_Thread` base class with protocol-specific thread managers.\n- **HTTP/REST** (`ProxySQL_HTTP_Server`, `ProxySQL_RESTAPI_Server`) — Metrics and management endpoints.\n\n### Key Dependencies (in deps/)\n\n- `jemalloc` — memory allocator\n- `sqlite3` — admin config storage\n- `mariadb-client-library` — MySQL protocol\n- `postgresql` — PostgreSQL protocol\n- `re2`, `pcre` — regex engines\n- `libev` — event loop\n- `libinjection` — SQL injection detection\n- `lz4`, `zstd` — compression\n- `curl`, `libmicrohttpd`, `libhttpserver` — HTTP\n- `prometheus-cpp` — metrics\n- `libscram` — SCRAM authentication\n\n### Conditional Components\n\n- **FFTO** (Fast Forward Traffic Observer) — `MySQLFFTO.cpp`, `PgSQLFFTO.cpp`\n- **TSDB** — Time-series metrics with embedded dashboard\n- **ClickHouse** — Native ClickHouse protocol support\n- **GenAI / MCP / RAG / LLM** — Lives entirely in `plugins/genai/`\n  as of the carve-out completed in Step 7.  Loaded via `dlopen` when\n  `plugins = (genai)` is configured in `proxysql.cnf`; not part of\n  `libproxysql.a` or the `proxysql` binary.\n\n## Code Layout\n\n- `include/` — All headers (.h/.hpp). Include guards use `#ifndef __CLASS_*_H`.\n- `lib/` — Core library sources (~121 files). One class per file typically.\n- `src/main.cpp` — Entry point, daemon init, thread spawning (~95K lines).\n- `test/tap/` — TAP test framework and tests.\n- `test/infra/` — Docker-based test environments.\n- `.github/workflows/` — CI/CD pipelines (selftests, TAP tests, package builds, CodeQL). **See `doc/GH-Actions/README.md` for the architecture overview** — ProxySQL uses a two-branch caller/reusable split (`CI-*.yml` on `v3.0`, `ci-*.yml` on the `GH-Actions` branch) and the doc is the authoritative reference for how it fits together.\n\n## Agent Guidelines\n\nSee `doc/agents/` for detailed guidance on working with AI coding agents:\n- `doc/agents/project-conventions.md` — ProxySQL-specific rules (directories, build, test harness, git workflow)\n- `doc/agents/task-assignment-template.md` — Template for writing issues assignable to AI agents\n- `doc/agents/common-mistakes.md` — Known agent failure patterns with prevention and detection\n\n### Unit Test Harness\n\nUnit tests live in `test/tap/tests/unit/` and link against `libproxysql.a` via a custom test harness. Tests must use `test_globals.h` and `test_init.h` — see `doc/agents/project-conventions.md` for the full pattern.\n\n## Coding Conventions\n\n- Class names: `PascalCase` with protocol prefixes (`MySQL_`, `PgSQL_`, `ProxySQL_`)\n- Member variables: `snake_case`\n- Constants/macros: `UPPER_SNAKE_CASE`\n- C++17 required; conditional compilation via `#ifdef PROXYSQL31`, `#ifdef PROXYSQL40`, `#ifdef PROXYSQLFFTO`, `#ifdef PROXYSQLTSDB`, `#ifdef PROXYSQLCLICKHOUSE`. (`PROXYSQLGENAI` no longer guards any core code as of Step 7 of the GenAI plugin carve-out — it lives only inside `plugins/genai/` now.)\n- Performance-critical code — consider implications of changes to hot paths\n- RAII for resource management; jemalloc for allocation\n- Pthread mutexes for synchronization; `std::atomic<>` for counters\n\n<!-- File: .windsurfrules (Tokens: ~300 | Category: windsurf-rule) -->\n# Windsurf Cascade Agent Rules\n\nPath: `.windsurfrules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.windsurfrules)\n\n<!-- File: .github/copilot-instructions.md (Tokens: ~300 | Category: copilot-instructions) -->\n# GitHub Copilot Instructions\n\nPath: `.github/copilot-instructions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.github/copilot-instructions.md)\n\n<!-- File: .roomodes (Tokens: ~300 | Category: roo-rule) -->\n# Roo Code Custom Persona Modes\n\nPath: `.roomodes`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roomodes)\n\n<!-- File: .roorules (Tokens: ~300 | Category: roo-rule) -->\n# Roo Code Autonomous Agent Rules\n\nPath: `.roorules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.roorules)\n\n<!-- File: .clinerules (Tokens: ~300 | Category: cline-rule) -->\n# Cline Extension Native Directives\n\nPath: `.clinerules`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.clinerules)\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# Plugin Plugin Manifest\n\nPath: `plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugin.json)\n\n<!-- File: plugins/genai/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# genai Documentation\n\nPath: `plugins/genai/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/plugins/genai/README.md)\n\n<!-- File: scripts/release-tools/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# release-tools Documentation\n\nPath: `scripts/release-tools/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/scripts/release-tools/README.md)\n\n<!-- File: tools/pgsql_user_sync/README.md (Tokens: ~300 | Category: plugin-manifest) -->\n# pgsql_user_sync Documentation\n\nPath: `tools/pgsql_user_sync/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/tools/pgsql_user_sync/README.md)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/.cursor/mcp.json)\n\n<!-- File: mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/mcp.json)\n\n<!-- File: doc/agents/common-mistakes.md (Tokens: ~300 | Category: subagent-persona) -->\n# Subagent: common-mistakes\n\nPath: `doc/agents/common-mistakes.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/common-mistakes.md)\n\n<!-- File: doc/agents/project-conventions.md (Tokens: ~300 | Category: subagent-persona) -->\n# Subagent: project-conventions\n\nPath: `doc/agents/project-conventions.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/project-conventions.md)\n\n<!-- File: doc/agents/README.md (Tokens: ~300 | Category: subagent-persona) -->\n# Subagent: readme\n\nPath: `doc/agents/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/sysown/proxysql/HEAD/doc/agents/README.md)\n\n<!-- ... +1 more modular skills available via /api/skills/sysown/proxysql?path={path} -->\n</yakaai_skills>"}