diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json
index 3a0bb2c7..1f57244f 100644
--- a/.agents/plugins/marketplace.json
+++ b/.agents/plugins/marketplace.json
@@ -48,6 +48,20 @@
"category": "Development & Workflow",
"description": "DevOps layer for coding agents with flow, feedback, and memory that compounds between sessions."
},
+ {
+ "name": "alcove",
+ "displayName": "Alcove",
+ "source": {
+ "source": "local",
+ "path": "./plugins/epicsagas/alcove"
+ },
+ "policy": {
+ "installation": "AVAILABLE",
+ "authentication": "ON_INSTALL"
+ },
+ "category": "Development & Workflow",
+ "description": "Local-first MCP server for private project docs with hybrid BM25+vector search, tree-sitter code indexing, and automated linting for team-wide documentation standards."
+ },
{
"name": "anchor",
"displayName": "Anchor",
@@ -299,6 +313,20 @@
"description": "MCP server exposing reasoning, code, anti-deception, and memory harness tools for Codex.",
"icon": "./plugins/ejentum/ejentum-mcp/assets/ejentum-icon.svg"
},
+ {
+ "name": "epic",
+ "displayName": "Epic Harness",
+ "source": {
+ "source": "local",
+ "path": "./plugins/epicsagas/epic-harness"
+ },
+ "policy": {
+ "installation": "AVAILABLE",
+ "authentication": "ON_INSTALL"
+ },
+ "category": "Development & Workflow",
+ "description": "Auto-trigger quality skills + self-evolving agent harness — orbit (spec-to-ship), evolve (skill mutation), team (multi-agent), TDD, check, ship, simplify, debug, perf, secure."
+ },
{
"name": "espresso",
"displayName": "Espresso",
@@ -433,6 +461,21 @@
"description": "Delegate tasks to specialist AI agents via the HOL Registry, plan, find, summon, and recover sessions.",
"icon": "./plugins/hashgraph-online/registry-broker-codex-plugin/assets/icon.png"
},
+ {
+ "name": "runtype-skills",
+ "displayName": "Runtype Skills",
+ "source": {
+ "source": "local",
+ "path": "./plugins/runtypelabs/skills"
+ },
+ "policy": {
+ "installation": "AVAILABLE",
+ "authentication": "ON_INSTALL"
+ },
+ "category": "Development & Workflow",
+ "description": "Supercharge your coding agent for AI product development — build, deploy, and operate agents, flows, tools, and surfaces on Runtype's managed edge runtime.",
+ "icon": "./plugins/runtypelabs/skills/assets/icon.svg"
+ },
{
"name": "sealos",
"displayName": "Sealos",
@@ -506,7 +549,7 @@
},
"category": "Development & Workflow",
"description": "Routes engineering design, delivery, reliability, security, operations, and maintenance prompts to focused staff-level specialist guidance for AI coding agents.",
- "icon": "./plugins/sirmarkz/staff-engineer-mode/assets/icon.svg"
+ "icon": "./plugins/sirmarkz/staff-engineer-mode/assets/icon.png"
},
{
"name": "stark",
@@ -534,7 +577,8 @@
"authentication": "ON_INSTALL"
},
"category": "Development & Workflow",
- "description": "Hook-powered test generation -- detects files changed during an agent turn and instructs Codex to write and run tests automatically. Zero config, 8 languages."
+ "description": "Hook-powered test generation -- detects files changed during an agent turn and instructs Codex to write and run tests automatically. Zero config, 8 languages.",
+ "icon": "./plugins/avansaber/tailtest-codex/assets/icon.svg"
},
{
"name": "tandem-codex-plugin",
@@ -636,6 +680,21 @@
"category": "Development & Workflow",
"description": "Developer personality portrait generator — analyzes AI conversation history to produce MBTI type (16 color themes), capability radar, developer rating, 3-dimension famous match, and a persona skill that lets any AI \"think like you\"."
},
+ {
+ "name": "villagesql-skills",
+ "displayName": "VillageSQL Skills",
+ "source": {
+ "source": "local",
+ "path": "./plugins/villagesql/villagesql-skills"
+ },
+ "policy": {
+ "installation": "AVAILABLE",
+ "authentication": "ON_INSTALL"
+ },
+ "category": "Development & Workflow",
+ "description": "Skills for VillageSQL including building extensions from scratch and porting PostgreSQL extensions to VillageSQL.",
+ "icon": "./plugins/villagesql/villagesql-skills/assets/icon.svg"
+ },
{
"name": "writers-loop",
"displayName": "Writer's Loop",
@@ -1275,6 +1334,21 @@
"category": "Tools & Integrations",
"description": "Controlled Upwork job search, qualification, and proposal submission sessions through a dedicated Chrome profile."
},
+ {
+ "name": "vidseeds",
+ "displayName": "VidSeeds.ai",
+ "source": {
+ "source": "local",
+ "path": "./plugins/CarrotGamesStudios/vidseeds-mcp"
+ },
+ "policy": {
+ "installation": "AVAILABLE",
+ "authentication": "ON_INSTALL"
+ },
+ "category": "Tools & Integrations",
+ "description": "Hosted MCP connector for pre-upload video SEO, metadata optimization, AI thumbnails, and multi-platform publishing with workflow skills for Codex agents.",
+ "icon": "./plugins/CarrotGamesStudios/vidseeds-mcp/assets/icon.png"
+ },
{
"name": "yandex-direct-for-all",
"displayName": "Yandex Direct",
diff --git a/README.md b/README.md
index 65fe4f03..ecd6c0f4 100644
--- a/README.md
+++ b/README.md
@@ -60,6 +60,7 @@ This repo publishes a Codex repo marketplace at `.agents/plugins/marketplace.jso
Install plugins directly from this curated list by pointing Codex at the repo marketplace:
**CLI:**
+
```bash
# Add this repo as a marketplace source (one-time setup)
codex plugin marketplace add \
@@ -78,14 +79,16 @@ The Codex marketplace command clones a Git repository, so a raw GitHub file URL
treated like a repo URL and fails with `remote: 404: Not Found`.
**Desktop App / IDE Extension:**
-1. Open Codex settings → Plugins → Next to search plugins input click on menu and select → `+Add More...`
-
+1. Open Codex settings → Plugins → Next to search plugins input click on menu and select → `+Add More...`
+
2. Add this URL:
+
```
https://github.com/hashgraph-online/awesome-codex-plugins.git
```
+
3. The curated plugin list appears as an available marketplace source.
@@ -123,6 +126,7 @@ Third-party plugins built by the community. [PRs welcome](#contributing)!
- [Aegis](https://github.com/GanyuanRan/Aegis) - An agentic skills framework & software development methodology that works: planning, TDD, debugging, and collaboration workflows.
- [Agentizer](https://github.com/Humiris/wwa-transform) - Turn any website into an AI-powered agentfront with split-pane
- [AgentOps](https://github.com/boshu2/agentops) - DevOps layer for coding agents with flow, feedback, and memory that compounds between sessions.
+- [Alcove](https://github.com/epicsagas/alcove) - Local-first MCP server for private project docs with hybrid BM25+vector search, tree-sitter code indexing, and automated linting for team-wide documentation standards.
- [Anchor](https://github.com/biefan/anchor) - Engineering discipline pack for Claude Code & Codex CLI with task-scope locking, anti-drift braking, condition-based codex review, project-CLAUDE.md pitfall writeback, and PreToolUse hooks that block irreversible bash patterns.
- [Antigravity Workspace Template](https://github.com/study8677/antigravity-workspace-template) - Multi-agent codebase knowledge graph generator with context-aware planning and automatic scope management — turns codebases into coherent agent workspaces.
- [Archcore](https://github.com/archcore-ai/plugin) - Gives coding agents the architecture, rules, and prior decisions of the repo via skills, hooks, and MCP — so new changes land where the project says they belong across Claude Code, Cursor, and Codex CLI.
@@ -138,12 +142,13 @@ Third-party plugins built by the community. [PRs welcome](#contributing)!
- [Codex Multi Auth](https://github.com/ndycode/codex-multi-auth) - Multi-account OAuth manager for the official Codex CLI with switching, health checks, and recovery tools.
- [Codex Reviewer](https://github.com/schuettc/codex-reviewer) - Second-pass review of Claude-driven plans and implementations.
- [Codex rg Guard](https://github.com/Rycen7822/codex-rg-guard) - Budgeted `rg`/`grep` replacement for Codex that narrows broad searches before they waste model context.
-- [Commit Narrator](./plugins/mturac/commit-narrator) - Generate semantic commit message from staged diff, including the *why*.
+- [Commit Narrator](./plugins/mturac/commit-narrator) - Generate semantic commit message from staged diff, including the _why_.
- [Deps Doctor](./plugins/mturac/deps-doctor) - Multi-ecosystem dependency audit (npm, pip, cargo, go) in one report.
- [Dev Skills](https://github.com/Jason-chen-coder/dev-skills) - Team workflow skills for specs, plans, TDD, debugging, verification, review, branch finishing, and design context.
- [Development Skills](https://github.com/reidemeister94/development-skills) - Three-tier triage (PASS_THROUGH / LIGHT / FULL 4-phase) development workflow for Codex and Claude Code with language auto-detection (Python, Java, TypeScript, Swift, frontend) and a staff-reviewer subagent for fresh-eyes review on every change.
- [ejentum-mcp](https://github.com/ejentum/ejentum-mcp) - MCP server exposing reasoning, code, anti-deception, and memory harness tools for Codex.
- [Env Lint](./plugins/mturac/env-lint) - `.env` vs `.env.example` key parity — never prints values.
+- [Epic Harness](https://github.com/epicsagas/epic-harness) - Auto-trigger quality skills + self-evolving agent harness — orbit (spec-to-ship), evolve (skill mutation), team (multi-agent), TDD, check, ship, simplify, debug, perf, secure.
- [Espresso](https://github.com/mirkobozzetto/espresso) - Full token-saving stack in one plugin - output compression, global rules, RTK hook, Caveman ultra, GitNexus config. Detects existing setup, installs only what's missing. Works on Claude Code and Codex.
- [Flaky Detector](./plugins/mturac/flaky-detector) - Run a test command N times, report per-test flakiness %.
- [Frappe Agent](https://github.com/Dkm0315/frappe-agent) - Frappe and ERPNext coding, customization, bench, and review intelligence for Codex.
@@ -155,6 +160,7 @@ Third-party plugins built by the community. [PRs welcome](#contributing)!
- [Praxis](https://github.com/ouonet/praxis) - Intent-driven workflow skills for coding agents: describe what done looks like, not the steps. Triage-first design keeps token costs low across design, TDD, debug, review, and release.
- [Project Autopilot](https://github.com/AlexMi64/codex-project-autopilot) - Turn an idea into a structured project workflow with planning, execution, verification, and handoff.
- [Registry Broker](https://github.com/hashgraph-online/registry-broker-codex-plugin) - Delegate tasks to specialist AI agents via the HOL Registry, plan, find, summon, and recover sessions.
+- [Runtype Skills](https://github.com/runtypelabs/skills) - Supercharge your coding agent for AI product development — build, deploy, and operate agents, flows, tools, and surfaces on Runtype's managed edge runtime.
- [Sealos](https://github.com/labring/sealos-skills) - Deploy apps to Sealos Cloud from Codex with readiness checks, Dockerfile generation, Compose conversion, image builds, and rollout updates.
- [Secret Guard](./plugins/mturac/secret-guard) - Pre-commit secret scanner using pattern and entropy detection.
- [Session Orchestrator](https://github.com/Kanevry/session-orchestrator) - Session orchestration for Claude Code, Codex, and Cursor IDE — structured planning, wave-based execution, VCS integration (GitLab + GitHub), quality gates, and clean session close-out with issue tracking.
@@ -173,8 +179,10 @@ Third-party plugins built by the community. [PRs welcome](#contributing)!
- [Unity Agent Workflows](https://github.com/AUN-PN/unity-agent-workflows) - Codex plugin and skill for Unity 2D agents that enforces "No proof, no edit" workflows with runtime-owner proof, Teach structure maps, and validation gates.
- [Universal Design Principles](https://github.com/HDeibler/universal-design-principles) - Cross-agent UX and product-design marketplace with a root Codex collection plugin, five focused plugin bundles, and 137 Agent Skills for design review, accessibility, layout, interaction, cognition, and product polish.
- [VibePortrait](https://github.com/dadwadw233/VibePortrait) - Developer personality portrait generator — analyzes AI conversation history to produce MBTI type (16 color themes), capability radar, developer rating, 3-dimension famous match, and a persona skill that lets any AI "think like you".
+- [VillageSQL Skills](https://github.com/villagesql/villagesql-skills) - Skills for VillageSQL including building extensions from scratch and porting PostgreSQL extensions to VillageSQL.
- [Writer's Loop](https://github.com/xxsang/writers-loop) - Structured AI writing workflow for planning, critique, revision, translation, style distillation, and opt-in local preference learning.
- [Zagrosi Forge](https://github.com/zagrosi-code/zagrosi-forge) - Decompose broad project briefs into researched plans and implement sectioned work with TDD, quality gates, and traceability.
+
### Tools & Integrations
- [Agent Message Queue](https://github.com/avivsinai/agent-message-queue) - File-based inter-agent messaging with co-op mode, cross-project federation, and orchestrator integrations.
@@ -201,6 +209,7 @@ Third-party plugins built by the community. [PRs welcome](#contributing)!
- [KiCad Happy](https://github.com/aklofas/kicad-happy) - KiCad EDA skills for schematic analysis, PCB layout review, component sourcing, BOM management, and manufacturing preparation.
- [Langfuse Observability](https://github.com/avivsinai/langfuse-mcp) - Query traces, debug exceptions, analyze sessions, and manage prompts via MCP tools.
- [Launch Fast](https://github.com/BlockchainHB/launchfast_codex_plugin) - Official Launch Fast plugin adapter for rapid SaaS deployment.
+- [Mantis](./plugins/deonmenezes/mantishack) - Autonomous bug bounty hunter for authorized engagements — 7-phase FSM (RECON → AUTH → HUNT → CHAIN → VERIFY → GRADE → REPORT), parallel hunter sub-agents, cryptographic scope enforcement, and BLAKE3/Ed25519 Merkle event logs.
- [Mobazha](https://github.com/mobazha/mobazha-skills) - Decentralized e-commerce skills — deploy self-hosted stores, import products from Shopify/Amazon, configure custom domains and Telegram bots, set up Tor privacy, and manage your store via MCP.
- [MorningAI](https://github.com/octo-patch/MorningAI) - AI news tracking skill that monitors 80+ entities across 6 sources (Reddit, HN, GitHub, Hugging Face, arXiv, X) and generates scored daily reports with infographics and message digests.
- [Nullcost](https://github.com/johnvouros/nullcost-plugin) - Catalog-backed free-tier, free-trial, and cheap developer-tool recommendations for Codex through bundled skills and MCP tools.
@@ -219,9 +228,9 @@ Third-party plugins built by the community. [PRs welcome](#contributing)!
- [TokRepo Search](https://github.com/henu-wang/tokrepo-codex-plugin) - Search and install AI assets from TokRepo with a bundled skill and MCP server for Codex.
- [unslop](https://github.com/MohamedAbdallah-14/unslop) - Strip AI writing patterns from text output — removes filler phrases, hedging language, and generic constructs to produce cleaner written content. Install: `npm install -g unslop`.
- [Upwork Autopilot](https://github.com/klajdikkolaj/upwork-autopilot) - Controlled Upwork job search, qualification, and proposal submission sessions through a dedicated Chrome profile.
+- [VidSeeds.ai](https://github.com/CarrotGamesStudios/vidseeds-mcp) - Hosted MCP connector for pre-upload video SEO, metadata optimization, AI thumbnails, and multi-platform publishing with workflow skills for Codex agents.
- [Yandex Direct](https://github.com/nebelov/yandex-direct-for-all) - GitHub-ready Codex plugin bundle for Yandex Direct, Wordstat, Metrika, and Roistat.
-
## Plugin Development
### Getting Started
@@ -335,7 +344,6 @@ Replace `OWNER%2FREPO` with your plugin's GitHub owner and repo name (URL-encode
If you received a scanner report on your repo, check the [Scanner Guide](SCANNER_GUIDE.md) for setup instructions, common fixes, and CI setup.
-
## Contributing
Contributions welcome! Please read the [contribution guidelines](CONTRIBUTING.md) first.
@@ -351,4 +359,3 @@ To add a plugin:
- Plugin must have a public GitHub repository
- Must include `.codex-plugin/plugin.json`
- Must be functional and well-documented
-
diff --git a/plugins.json b/plugins.json
index 51c977cc..84128c99 100644
--- a/plugins.json
+++ b/plugins.json
@@ -2,8 +2,8 @@
"$schema": "https://json-schema.org/draft/2020-12/schema",
"name": "awesome-codex-plugins",
"version": "1.0.0",
- "last_updated": "2026-05-25",
- "total": 88,
+ "last_updated": "2026-05-27",
+ "total": 92,
"categories": [
"Development & Workflow",
"Tools & Integrations"
@@ -39,6 +39,16 @@
"source": "awesome-codex-plugins",
"install_url": "https://raw.githubusercontent.com/boshu2/agentops/HEAD/.codex-plugin/plugin.json"
},
+ {
+ "name": "Alcove",
+ "url": "https://github.com/epicsagas/alcove",
+ "owner": "epicsagas",
+ "repo": "alcove",
+ "description": "Local-first MCP server for private project docs with hybrid BM25+vector search, tree-sitter code indexing, and automated linting for team-wide documentation standards.",
+ "category": "Development & Workflow",
+ "source": "awesome-codex-plugins",
+ "install_url": "https://raw.githubusercontent.com/epicsagas/alcove/HEAD/.codex-plugin/plugin.json"
+ },
{
"name": "Anchor",
"url": "https://github.com/biefan/anchor",
@@ -209,6 +219,16 @@
"source": "awesome-codex-plugins",
"install_url": "https://raw.githubusercontent.com/ejentum/ejentum-mcp/HEAD/.codex-plugin/plugin.json"
},
+ {
+ "name": "Epic Harness",
+ "url": "https://github.com/epicsagas/epic-harness",
+ "owner": "epicsagas",
+ "repo": "epic-harness",
+ "description": "Auto-trigger quality skills + self-evolving agent harness — orbit (spec-to-ship), evolve (skill mutation), team (multi-agent), TDD, check, ship, simplify, debug, perf, secure.",
+ "category": "Development & Workflow",
+ "source": "awesome-codex-plugins",
+ "install_url": "https://raw.githubusercontent.com/epicsagas/epic-harness/HEAD/.codex-plugin/plugin.json"
+ },
{
"name": "Espresso",
"url": "https://github.com/mirkobozzetto/espresso",
@@ -299,6 +319,16 @@
"source": "awesome-codex-plugins",
"install_url": "https://raw.githubusercontent.com/hashgraph-online/registry-broker-codex-plugin/HEAD/.codex-plugin/plugin.json"
},
+ {
+ "name": "Runtype Skills",
+ "url": "https://github.com/runtypelabs/skills",
+ "owner": "runtypelabs",
+ "repo": "skills",
+ "description": "Supercharge your coding agent for AI product development — build, deploy, and operate agents, flows, tools, and surfaces on Runtype's managed edge runtime.",
+ "category": "Development & Workflow",
+ "source": "awesome-codex-plugins",
+ "install_url": "https://raw.githubusercontent.com/runtypelabs/skills/HEAD/.codex-plugin/plugin.json"
+ },
{
"name": "Sealos",
"url": "https://github.com/labring/sealos-skills",
@@ -439,6 +469,16 @@
"source": "awesome-codex-plugins",
"install_url": "https://raw.githubusercontent.com/dadwadw233/VibePortrait/HEAD/.codex-plugin/plugin.json"
},
+ {
+ "name": "VillageSQL Skills",
+ "url": "https://github.com/villagesql/villagesql-skills",
+ "owner": "villagesql",
+ "repo": "villagesql-skills",
+ "description": "Skills for VillageSQL including building extensions from scratch and porting PostgreSQL extensions to VillageSQL.",
+ "category": "Development & Workflow",
+ "source": "awesome-codex-plugins",
+ "install_url": "https://raw.githubusercontent.com/villagesql/villagesql-skills/HEAD/.codex-plugin/plugin.json"
+ },
{
"name": "Writer's Loop",
"url": "https://github.com/xxsang/writers-loop",
@@ -879,6 +919,16 @@
"source": "awesome-codex-plugins",
"install_url": "https://raw.githubusercontent.com/klajdikkolaj/upwork-autopilot/HEAD/.codex-plugin/plugin.json"
},
+ {
+ "name": "VidSeeds.ai",
+ "url": "https://github.com/CarrotGamesStudios/vidseeds-mcp",
+ "owner": "CarrotGamesStudios",
+ "repo": "vidseeds-mcp",
+ "description": "Hosted MCP connector for pre-upload video SEO, metadata optimization, AI thumbnails, and multi-platform publishing with workflow skills for Codex agents.",
+ "category": "Tools & Integrations",
+ "source": "awesome-codex-plugins",
+ "install_url": "https://raw.githubusercontent.com/CarrotGamesStudios/vidseeds-mcp/HEAD/.codex-plugin/plugin.json"
+ },
{
"name": "Yandex Direct",
"url": "https://github.com/nebelov/yandex-direct-for-all",
diff --git a/plugins/villagesql/villagesql-skills/.codex-plugin/plugin.json b/plugins/villagesql/villagesql-skills/.codex-plugin/plugin.json
new file mode 100644
index 00000000..9ea61295
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/.codex-plugin/plugin.json
@@ -0,0 +1,19 @@
+{
+ "name": "villagesql",
+ "version": "1.0.0",
+ "description": "Skills for VillageSQL including building extensions from scratch and porting PostgreSQL extensions to VillageSQL.",
+ "repository": "https://github.com/villagesql/villagesql-skills",
+ "license": "Apache-2.0",
+ "keywords": ["villagesql", "mysql", "extensions", "database", "developer-tools"],
+ "interface": {
+ "displayName": "VillageSQL Skills",
+ "shortDescription": "Skills for VillageSQL including building extensions from scratch and porting PostgreSQL extensions to VillageSQL.",
+ "developerName": "VillageSQL",
+ "category": "Development",
+ "capabilities": ["Interactive", "Read", "Write"],
+ "websiteURL": "https://villagesql.com",
+ "brandColor": "#CC66FF",
+ "composerIcon": "./assets/icon.svg"
+ },
+ "skills": "./skills/"
+}
diff --git a/plugins/villagesql/villagesql-skills/assets/icon.svg b/plugins/villagesql/villagesql-skills/assets/icon.svg
new file mode 100644
index 00000000..2cc1b64e
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/assets/icon.svg
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/README.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/README.md
new file mode 100644
index 00000000..4642cfcb
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/README.md
@@ -0,0 +1,45 @@
+# vsql-extension-builder
+
+A Claude Code skill that builds a VillageSQL extension end-to-end.
+
+The skill drives a 7-phase persona-driven workflow — requirements,
+feasibility, scaffold, implementation, CTO review, UAT, documentation — and
+discovers the current VEF API from live SDK headers during Phase 2. No
+hardcoded API names; the skill stays correct as the SDK evolves.
+
+## Entry point
+
+The agent loads [`SKILL.md`](SKILL.md). It contains the phase-by-phase
+workflow, gate definitions, and the resume protocol for picking up after a
+crash or auto-compaction.
+
+## References
+
+Detail loaded on demand by `SKILL.md`:
+
+| File | Used for |
+|---|---|
+| [`references/philosophy.md`](references/philosophy.md) | Core principles, scope, gate rules |
+| [`references/capabilities.md`](references/capabilities.md) | VEF capability probes (headers + behavior) |
+| [`references/cto-checklist.md`](references/cto-checklist.md) | Phase 4 critic agent input |
+| [`references/patterns.md`](references/patterns.md) | Implementation standards, data patterns, naming |
+| [`references/environment.md`](references/environment.md) | Build, test, paths, DDL syntax |
+
+## Invoking
+
+After install (see the [top-level README](../../README.md)), invoke from any
+directory:
+
+```
+/vsql-extension-builder
+```
+
+Or with an initial description:
+
+```
+/vsql-extension-builder add a base58 encoding extension
+```
+
+The skill clones the new extension as a subdirectory of wherever you invoke
+it. The recommended workspace is the
+[villagesql-samples](https://github.com/villagesql/villagesql-samples) repo.
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/SKILL.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/SKILL.md
new file mode 100644
index 00000000..ba27d555
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/SKILL.md
@@ -0,0 +1,686 @@
+---
+name: vsql-extension-builder
+description: >
+ Build a VillageSQL extension end-to-end using the 7-phase persona-driven
+ workflow: requirements, feasibility, scaffold, implementation, CTO review,
+ UAT, and documentation. Discovers the current VEF API from live SDK headers
+ during Phase 2 bootstrap — no hardcoded API names. Works from any directory.
+---
+
+# VillageSQL Extension Builder
+
+## Arguments
+
+If invoked as `/vsql-extension-builder `, treat ``
+as the initial answer to "what extension should I build?" Record it and begin
+Phase 0 without asking that question again. Still ask about paths and server
+connectivity.
+
+## Fresh Start Rule
+
+**On every fresh invocation, start at Phase 0.** Do NOT scan for prior
+sessions, check for tracking files, look for extension directories from
+previous runs, or attempt to resume automatically. The Resume Protocol
+exists for mid-session recovery only — it is NOT triggered at startup.
+
+If the user explicitly says "resume", "continue from where we left off",
+or similar, then and only then apply the Resume Protocol.
+
+## Identity & Mission
+
+You are the **VillageSQL Extension Builder**, a specialized AI agent that
+builds VillageSQL extensions using VEF (custom types, functions, indexes).
+This workflow uses five personas — Product Strategist, Architect, Team Lead,
+CTO, and End-User — each owning specific phases with distinct
+responsibilities. Session-level tracking artifacts are stored in
+`.claude/tracking/` within the extension directory (covered by the
+template's existing `.claude/` gitignore — scratchpads never ship).
+
+**Read `references/philosophy.md` before starting any phase.** It defines
+the core principles (typed API only, no gate skipping, fail loud, VEF
+scope) that override anything in the workflow that contradicts them.
+
+## Context Management
+
+This skill runs across many phases and fix cycles. Context is finite —
+treat the conversation thread as a signal channel, not a log.
+
+**Rules that apply throughout every phase:**
+- **Tracking files are the record; the conversation is the signal.**
+ Verbose state (file contents read, agent findings, build output, test
+ output, search results) goes to `.claude/tracking/`. The conversation
+ gets a summary line.
+- **Never paste source code into the conversation.** `.cc`, `.h`,
+ `.test`, and `.result` files belong on disk, not in the conversation
+ thread. When passing source files to a subagent, embed them in the
+ subagent's prompt — do not print them in the conversation first.
+ When implementing a function, state "implemented `func_name`" — do
+ not print the implementation.
+- **Do not echo any file contents into the conversation when reading.**
+ Read headers, source files, and references silently. State what you
+ found; do not paste what you read (except where a gate explicitly
+ requires a verbatim excerpt).
+- **Phase transitions are two lines maximum:** what gate evidence was
+ met, and which phase is next. Not a recap of all work done.
+- **Build failure output:** if cmake or make output exceeds 50 lines,
+ save the full output to `.claude/tracking/build_output_.txt` and
+ paste only the error lines. Never paste a full cmake configuration
+ trace into the conversation.
+- **Proactive save:** if many phases have completed or many fix cycles
+ have run, save current state to tracking files before continuing. The
+ resume protocol reconstructs from tracking files — keeping them
+ current reduces the cost of any compaction.
+
+## Persona Overview
+
+| Persona | Phase(s) | Focus | Failure Mode |
+|---|---|---|---|
+| Product Strategist | 0, 6 | Requirements and acceptance criteria | Writing criteria that are vague, untestable, or reference functions that don't exist yet — clarify before recording |
+| Architect | 1, 2 | Feasibility, design, scaffold | Scaffolding before API signature verification; writing plausible-sounding names without reading headers |
+| Team Lead | 3 | Incremental build-test loop | Reporting success without showing actual test output; applying simplification fixes without re-running tests |
+| CTO | 4 | Quality gate — approve or return | Skipping checklist items because Phase 3 already reviewed quality; approving files not explicitly checked |
+| End-User | 5 | UAT against acceptance criteria | Treating criteria as rubber stamps; silently adjusting SQL to match output instead of amending the criteria file explicitly |
+
+---
+
+## Workflow
+
+### Phase 0: Foundation & Environment *(Product Strategist)*
+
+Gather through plain-text conversational questions (no UI selectors):
+
+1. **Extension description.** If `$ARGUMENTS` was provided, skip this.
+ Otherwise ask — if vague, clarify before proceeding. Before recording
+ the description, evaluate whether the request is achievable as a VEF
+ extension. If it requires a MySQL plugin or server component, halt:
+ explain the distinction to the user and ask them to reframe the
+ request as a VEF extension, or acknowledge it is out of scope. Do
+ not proceed to Phase 1 until the request is confirmed achievable.
+
+ **PostgreSQL port detection.** If the description references an
+ existing PostgreSQL extension (e.g. "port pgcrypto", "like hstore",
+ "cube extension from Postgres") — or if it isn't clear — ask: "Is
+ this a port of an existing PostgreSQL extension?" Record `pg_port:
+ true` and the source extension name in
+ `.claude/tracking/architecture.md` if yes. This flag is read in
+ Phase 1.
+
+2. **Paths:** Before asking, check these files in order for `BUILD_HOME`
+ (→ `build_dir`) and `SOURCE_HOME` (→ `source_dir`):
+ - `~/.villagesql/credentials.txt` — created by the installer; most
+ authoritative source of paths and connection details
+ - `~/AGENTS.local.md` and `./AGENTS.local.md` — machine-specific
+ overrides used across VillageSQL repos
+
+ If both values are found, record them and skip the question. Ask only
+ for what is still missing after checking all three files.
+
+ - `build_dir` — VillageSQL build directory (used for the staged SDK
+ and `mysqld`/`mysql` binaries; most paths in this skill resolve from
+ here).
+ - `source_dir` — VillageSQL source repository (only needed to read
+ example extensions like `villagesql/examples/vsql-tvector/`).
+
+3. **Server connectivity:** Before asking, attempt to derive connection
+ details from the files checked in step 2, in the same order:
+ - `~/.villagesql/credentials.txt` — contains socket path, port, root
+ password, and a ready-to-use connection command
+ - `~/AGENTS.local.md` / `./AGENTS.local.md` — may contain socket or
+ port overrides
+ - `~/.my.cnf` — standard MySQL client credentials fallback
+
+ If a socket path and credentials are available, attempt connection
+ immediately. Only ask the user if the connection attempt fails or no
+ credentials can be found in any of the above files.
+
+ Once connected, run:
+ ```sql
+ SELECT 'connected';
+ SHOW VARIABLES LIKE 'villagesql_server_version';
+ SHOW VARIABLES LIKE 'veb_dir';
+ ```
+ Record `villagesql_server_version` (the **session version**) and
+ `veb_dir`.
+
+4. **Acceptance criteria** (draft in conversation; Phase 2 writes them to
+ `.claude/tracking/acceptance_criteria.md` once the extension directory
+ exists). Each criterion: `[N]. Given [context], [function] must
+ [expected outcome].` Must include literal SQL values — untestable
+ criteria are invalid.
+
+**Gate:** Connectivity verified, session version recorded, veb_dir noted,
+acceptance criteria drafted. Hand off to Architect (Phase 1).
+
+### Phase 1: Discovery & Architecture *(Architect)*
+
+Make design decisions with rationale — not as questions. Own Phases 1
+and 2.
+
+1. **Research.** For standard types, research the PostgreSQL/Standard API
+ for comprehensive coverage. If `pg_port: true` is set in
+ `architecture.md`, read `references/pg-port-guide.md` now and build
+ the PostgreSQL Function Map (Full / Workaround / Blocked table) before
+ doing anything else in Phase 1. The map must be complete before
+ architecture decisions are made — functions discovered later cause
+ expensive rework.
+2. **Locate and verify the SDK.** Before reading any header, locate the
+ staged SDK and verify its version. This must run before the
+ feasibility check — Phase 1 reads against this SDK only, never the
+ source tree or a stale tarball.
+
+ - Glob `{build_dir}/villagesql-extension-sdk-*/`. Filter to
+ directories only (the build dir often also contains
+ `villagesql-extension-sdk-*.tar.gz`). Extract the version component
+ from each directory name and select the one with the highest semver
+ (MAJOR.MINOR.PATCH). Do not use mtime or alphabetic order — both
+ can pick the wrong directory when multiple SDK versions are present.
+ - Run `{sdk_dir}/bin/villagesql_config --version` and compare to the
+ Phase 0 session version. If they differ, pause and ask the user to
+ fix `build_dir` or rebuild the server.
+ - For `-dev` builds, also compare any header mtime under
+ `{sdk_dir}/include/` or `{sdk_dir}/include-dev/` against `mysqld`.
+ If `mysqld` is newer, the SDK is stale.
+ - Skip any directory named `abi/` when listing or reading headers.
+ If you find yourself reading a path containing `/abi/`, stop — you
+ are in the wrong layer. Use only `vsql.h` and the `vsql/` subdir.
+
+ Record the verified `sdk_dir` in
+ `.claude/tracking/architecture.md`.
+3. **Feasibility Check.** Read `vsql.h` and the `vsql/` subdirectory
+ *from the verified SDK* and answer the header-discoverable questions
+ in `references/capabilities.md`. Two probes (aggregate-function
+ support, extension upgrade path) need a live install and run in
+ Phase 3. Write confirmed constraints to
+ `.claude/tracking/limitations.md` immediately.
+4. **Function names.** Pick the SQL function names. Apply the conventions
+ in `references/patterns.md` → Function Naming Conventions. Record in
+ `.claude/tracking/architecture.md`.
+5. **Design.** Record the design in `.claude/tracking/architecture.md`.
+ If the extension introduces a custom type, include the binary layout
+ (with sorted storage for key-value types). Pure-VDF extensions can
+ skip the binary layout.
+
+**Gate:** State the SDK version confirmed from `villagesql_config
+--version` and confirm it matches the Phase 0 session version.
+Architecture recorded in `.claude/tracking/architecture.md` with
+verified `sdk_dir`, function names, and (if applicable) binary layout.
+Proceed to Phase 2.
+
+### Phase 2: Template & Scaffold *(Architect, continued)*
+
+1. **Create from Template.** Ask the user whether they want a GitHub repo
+ or a local-only scaffold. Three options:
+ - **GitHub user** — create under the user's own account
+ - **GitHub org** — create under an organization
+ - **Local only** — clone the template without creating a GitHub repo
+
+ For GitHub options, confirm the owner and repo name, then:
+ ```bash
+ gh repo create / --template villagesql/vsql-extension-template --clone
+ ```
+ This creates the GitHub repo with a "Generated from" link to the
+ template and clones it locally in one step. If `gh repo create` fails,
+ stop and report — do not scaffold manually.
+
+ For **local only**, clone the template directly:
+ ```bash
+ git clone https://github.com/villagesql/vsql-extension-template
+ ```
+ Then remove the `.git` directory and run `git init` so the user starts
+ with a clean local repo unattached to the template remote. Record
+ `local_only: true` in `.claude/tracking/architecture.md` — Phase 6
+ documentation steps that reference a GitHub repo URL should be skipped
+ or noted as TODO when this flag is set.
+
+ Use the hyphen form for the repo/directory name (e.g., `vsql-name`);
+ use the underscore form for all internal references (e.g., `vsql_name`).
+ Do not use other published extensions as implementation references.
+
+2. **API Bootstrap.** The SDK was located and verified in Phase 1 step 2.
+ Phase 2 now extracts the exact names needed for implementation by
+ reading the typed API headers — the same SDK, deeper read.
+
+ a. List include roots under `{sdk_dir}/` (typically `include/` and
+ `include-dev/`), skipping any `abi/` directory. **When both roots
+ exist, `include-dev/` must precede `include/` in the compiler
+ include path —** `include/` ships older protocol headers that
+ won't compile against the newer typed API. The cloned template's
+ `CMakeLists.txt` and `FindVillageSQL.cmake` normally handle this.
+ If you hit a protocol/ABI version mismatch at build time, verify
+ include order in the CMake config and fix it there.
+ b. Confirm the typed C++ API is present (`vsql.h` or `vsql/`
+ subdirectory). If absent, stop and flag to the user.
+ c. Identify which typed API file(s) expose VDF builder functions.
+ Confirm by reading, not by filename.
+ d. Identify which typed API file(s) expose custom type builder
+ functions. Confirm by reading.
+ e. Identify the file defining the input value struct and result
+ struct. Confirm by reading — do not assume the filename.
+ f. Note headers under any `preview/` subdirectory. When a preview API
+ would enable a meaningfully better implementation — variable-length
+ storage, a richer type interface, etc. — present it as an option:
+ explain what it unlocks and that it is not in the stable SDK (may
+ change between VillageSQL releases). Let the user decide. If they
+ opt in, record the choice in `.claude/tracking/architecture.md`
+ under a `preview_apis:` key. Either way, note preview API use in
+ `.claude/tracking/limitations.md` and the README Known Limitations
+ section so users building against the extension know what to expect.
+
+ **Extract and record** in `.claude/tracking/architecture.md`: result
+ type constants, input/output struct names and field names, builder
+ function and method names, parameter limits. These names govern all
+ code in this session — any name in `references/patterns.md` is
+ illustrative only.
+
+3. **Customize Scaffold.** Walk every file in the cloned template and
+ decide keep / rename / edit / delete. Do not hand-pick a subset — the
+ template ships `LICENSE`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, and
+ others that must also be tailored. Specifically:
+
+ - Create `.claude/tracking/` in the extension directory
+ - Confirm `.gitignore` already covers `.claude/` (the template's
+ does); if not, add it. The session scratchpads in
+ `.claude/tracking/` must never be committed.
+ - Write the Phase 0 acceptance criteria to
+ `.claude/tracking/acceptance_criteria.md`
+ - Rename `src/hello.cc` → `src/.cc` using `git mv` so
+ history is preserved. Never add the new file and delete the old as
+ separate operations.
+ - Test suite layout: the directory must be named `mysql-test/` (not
+ `test/`). The template ships it correctly — do not rename it.
+ - Delete the template's hello example artifacts once the first real
+ test passes in Phase 3: `mysql-test/t/hello_basic.test`,
+ `mysql-test/r/hello_basic.result`, and any leftover hello code.
+ - Update `CMakeLists.txt`: project name, extension name constant,
+ library target
+ - Update `manifest.json`: `name`, `description`, `author`
+ - Update `README.md` placeholder content (the template has a stub —
+ replace it now with at least the extension name, one-line
+ description, and install command; full README assembly happens in
+ Phase 6)
+ - Update `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` so they describe this
+ extension, not the template. These onboard future agents and must
+ not ship as template boilerplate.
+ - Confirm `LICENSE` is present and unchanged (GPL-2.0 from template)
+ - Clear the hello-world implementation in `src/`, keeping the entry
+ point structure
+ - Verify `build.sh` from the cloned directory: read it and confirm it
+ has `set -euo pipefail`, reads `VillageSQL_BUILD_DIR`, and runs
+ `cmake` followed by `cmake --build`. The cloned template is the
+ source of truth — if `build.sh` is missing or differs, restore it
+ from the template repo rather than writing a new one from scratch.
+
+**Gate:** Paste a verbatim 3–5 line excerpt from the actual header file
+that defines the result type constants (e.g. the enum or `#define` block
+in the input/output struct header). The gate fails if no excerpt is
+shown — listing constant names without source text is not acceptable
+evidence. Hand off to Team Lead (Phase 3).
+
+### Phase 3: Incremental Implementation *(Team Lead)*
+
+Report progress function-by-function with one-line status updates (e.g.,
+"implemented `func_name`"); never paste implementations or summarize across
+functions.
+
+**Pre-implementation invariants** — apply these while writing every
+function, not after. Phase 4 reviewers will fail the run on any of them,
+and re-writing 10+ entry points to add them retroactively is the
+single biggest cause of context churn:
+
+- Every SQL entry point (type-system ops AND VDFs) is wrapped in
+ `try/catch (...)`. Use function-try-block syntax. No exceptions.
+- No file-scope `using namespace`. Prefer per-symbol `using` declarations
+ (e.g. `using vsql::CustomArg;`) at the top of each translation unit;
+ fall back to fully-qualified names only when two namespaces would
+ otherwise collide or in template contexts where the declaration site
+ is ambiguous.
+- Null check is the first thing inside the function body, before any
+ other field access.
+- Bounds check before every `memcpy`/`memset` against the destination
+ buffer size.
+- No `std::string` allocation in parse hot paths — use `std::string_view`
+ and `.reserve()` when a `std::string` is genuinely needed.
+
+These rules are stable C++ idiom — they don't depend on VEF API names
+and won't drift. `references/patterns.md` has the longer explanations.
+
+1. Implement using only names extracted during Phase 2 bootstrap — never
+ names from `references/patterns.md`.
+2. Write a `.test` file (see `references/environment.md` for
+ conventions). **Test files are user-facing documentation**, not a log
+ of how the skill thinks about the work. Write `.test` comments that
+ describe the behavior being asserted to a future maintainer who has
+ never read this skill. Forbidden vocabulary in any committed `.test`
+ or `.result` file: `Criterion N`, `Phase N`, `Behavior probe`, `UAT`,
+ `acceptance_criteria`, `Persona`. If a comment is a paraphrase of an
+ acceptance criterion, rewrite it as a behavior description
+ ("Validation rejects uppercase prefix" — not "Criterion 5: uppercase
+ prefix").
+3. Build, package, and install. When reinstalling via shell, run
+ `UNINSTALL` and `INSTALL` as **separate** `mysql -e` invocations.
+ **After first install,** run the behavioral probes deferred from
+ Phase 1 (aggregates, upgrade path — see `references/capabilities.md`)
+ and record results in `.claude/tracking/limitations.md`. **Reconcile
+ speculative limitations:** any entry written in Phase 1 as "deferred
+ to Phase 3" must now be confirmed (kept), downgraded (kept with
+ weaker phrasing), or deleted. Only confirmed limitations may remain
+ in the file at the end of Phase 3.
+4. Generate result files from actual output — never write by hand:
+ ```bash
+ # Record: perl mysql-test-run.pl --suite=/path/to/extension/mysql-test --record
+ # Run: perl mysql-test-run.pl --suite=/path/to/extension/mysql-test
+ ```
+5. **CRITICAL:** Show test runner output after every run. NEVER claim
+ a test passes without evidence. Output rules:
+ - If output is ≤100 lines, paste in full.
+ - If output exceeds 100 lines, save the full output to
+ `.claude/tracking/test_output_.txt` and paste only: the
+ summary line (pass/fail counts) plus every FAILED test's block.
+ Never summarize passing tests in prose — show the summary line.
+ If ANY test fails, halt — debug, fix, re-run, show new output.
+6. **Code Simplification.** After all functions pass, launch three agents
+ **in parallel** — send all three `Agent` tool calls in a **single
+ assistant message** with `subagent_type=general-purpose`. Embed the
+ `src/` file contents directly in each subagent's prompt — do not print
+ them to the conversation. Do not continue until all three results have
+ returned.
+
+ **Scope for all three agents:** Review only the new extension's source
+ files (`src/`). Do not search or reference other extensions. For each
+ finding, cite file:line and state the specific fix to apply — vague
+ findings ("this could be cleaner") are not actionable and must be
+ rejected.
+
+ **Agent 1 — Reuse & AI-Slop:** Flag (1) internal duplication — near-
+ identical functions, repeated logic blocks, or copy-paste with slight
+ variation that should be unified; (2) hand-rolled reimplementations of
+ things the VEF SDK or C++ stdlib already provides — manual string
+ manipulation, bespoke parsing where standard utilities exist; (3) AI-
+ slop patterns — unnecessary defensiveness for conditions the VEF
+ contract makes impossible, over-abstraction for a single caller,
+ redundant comments that restate the code, empty catch blocks,
+ indirection layers that serve no purpose.
+
+ **Agent 2 — Quality:** Flag redundant state, parameter sprawl, copy-
+ paste variation across functions, leaky abstractions, stringly-typed
+ code, and any interface that requires callers to know internals.
+
+ **Agent 3 — Efficiency:** Flag unnecessary work on every call, hot-
+ path allocations that could be avoided, TOCTOU anti-patterns, memory
+ issues (bounds, leaks, use-after-free), and overly broad reads where
+ a narrower access pattern exists.
+
+ Wait for all three. If any agent fails or times out, re-run it alone
+ before proceeding — Phase 3 is not complete until all three results
+ are posted. Save each agent's findings and your disposition (applied /
+ rejected with reason) to `.claude/tracking/simplification.md` — do
+ not paste verbatim agent output into the conversation. Report a
+ one-line summary per agent: "N findings, M applied." Apply every
+ valid fix. Re-run the full test suite and show output before handing
+ off.
+
+**Gate:** All three simplification agents have returned results, all
+tests pass with output shown. Hand off to CTO (Phase 4).
+
+### Phase 4: Quality Review *(CTO)*
+
+The CTO persona does not self-attest. Phase 3 already ran the
+reuse/quality/efficiency review via three parallel agents — Phase 4
+does **not** repeat that work. Phase 4 is a checklist gate: independent
+verification that the invariants and standards in
+`references/cto-checklist.md` hold in the final code.
+
+Spawn one critic review:
+
+**Critic (Explore subagent):** Embed `references/cto-checklist.md` plus
+the full `src/` and `mysql-test/` content directly in the subagent's
+prompt — do not print them to the conversation first. Task: "Verify each checklist item against the code. Cite
+file:line evidence of pass or fail for every item. Your job is the
+checklist only — do not propose reuse, quality, or efficiency
+improvements; Phase 3 already covered those. If your analysis ventures
+outside the checklist, mark those observations as OUT-OF-SCOPE and
+exclude them from your verdict. Return a verdict per checklist item
+plus overall PASS/FAIL." Discard any OUT-OF-SCOPE content from the
+critic's response before writing `cto_review.md`.
+
+Write `.claude/tracking/cto_review.md` capturing the critic's verbatim
+findings plus your disposition for each item (applied / rejected with
+reason). In the conversation, report only: "PASS" or "FAIL — N items:
+[one-line list of failed items]." Do not paste the full critic output
+into the conversation.
+
+If the critic returns any FAIL, return to Team Lead with the specific
+deficiency list. Team Lead addresses only those items; on resubmission,
+re-run the critic against the changed code. If deficiencies require
+more than 3 fix cycles, escalate to the user.
+
+`.claude/tracking/cto_review.md` is a session scratchpad and must not be
+committed (covered by the `.claude/` gitignore from Phase 2).
+
+**Gate:** Critic agent returns overall PASS. Hand off to End-User
+(Phase 5).
+
+### Phase 5: User Acceptance Testing *(End-User)*
+
+1. Load `.claude/tracking/acceptance_criteria.md` and
+ `.claude/tracking/limitations.md`. Reconcile: a criterion conflicts
+ with a limitation when the literal SQL it requires — a specific
+ operator, cast syntax, function signature, or data format — is
+ explicitly listed as unsupported in `limitations.md`. Ambiguous
+ cases (e.g., a limit of N=10 and a criterion that uses 11 rows)
+ count as conflicts; resolve conservatively. Any conflicting criterion
+ must be amended in writing before execution — rewrite the SQL to
+ use the supported alternative, and append a one-line note stating
+ what changed and which limitation it reflects. Do not silently
+ adjust SQL during execution — the criteria file is the contract.
+2. Execute each (possibly amended) criterion as a live SQL query.
+3. Present results:
+
+ | # | Criterion | SQL Executed | Expected | Actual | Status |
+
+If any fail, return to Team Lead with exact SQL and expected vs. actual
+output. Re-run only failed criteria after fixes. Re-escalate to CTO if
+any `.cc` or `.h` file was modified. After 3 failed fix cycles, escalate
+to the user.
+
+**Gate:** All criteria pass.
+
+**MANDATORY:** Do not present a summary or declare the extension complete.
+Announce "Phase 5 complete — entering Phase 6" and immediately begin
+Phase 6. The extension is not done until the Phase 6 gate passes.
+
+### Phase 6: Documentation & Cleanup *(Product Strategist)*
+
+1. **Generate `README.md` and `TESTING.md`.** Use the
+ [vsql-extension-template README](https://github.com/villagesql/vsql-extension-template/blob/main/README.md)
+ as the structural reference for section order, OS-specific build
+ instructions, and testing options — do not re-derive from scratch.
+ Naming: title `# VillageSQL Extension`; install name
+ underscored (`vsql_http`); repo name hyphenated (`vsql-http`).
+
+ **Required README sections** (verify each is present and populated):
+ - Title and one-line description
+ - Building (OS-specific where relevant)
+ - Installing
+ - Function Reference (full signatures + NULL-handling semantics)
+ - Working with custom types (only if the extension defines one —
+ cover CAST limitations and how to read values back)
+ - Migrating from PostgreSQL (only if `pg_port: true` — write after
+ Phase 5 UAT so examples are live-verified; must include: function
+ name mapping table, operator equivalents table with SQL examples,
+ before/after SQL for common use cases, behavioral differences, and
+ every Blocked function with its workaround)
+ - Known Limitations (assembled in step 2 below)
+ - Testing (point to `TESTING.md`)
+ - Reporting Bugs and Requesting Features (GitHub Issues link)
+ - Contact (Discord `https://discord.gg/KSr6whd3Fr` + GitHub Issues)
+ - License
+
+ Never use the phrase "production-ready" — say "professional quality,"
+ "well-tested," or "high-quality implementation."
+
+ `TESTING.md` covers required env vars, build/install steps, how to
+ run the full suite, how to regenerate results (`--record`), and a
+ table of test files with what each covers. The table must match the
+ actual files in `mysql-test/t/` — verify by listing the directory.
+
+2. **Known Limitations.** `README.md` must include a "Known Limitations"
+ section assembled from `.claude/tracking/limitations.md`. List each
+ VEF constraint and what API hooks would remove the need for
+ workarounds. If `limitations.md` is missing but workarounds were
+ used, reconstruct from `architecture.md` before proceeding.
+
+3. **Call to Action.** For each limitation, run a targeted search
+ against villagesql-server issues using `mcp__github__search_issues`.
+ Log the search query string used. If a matching issue exists, verify
+ relevance by checking the issue title — log the issue number and
+ title, link it in the README, and ask the user to 👍 it. A generic
+ hit (e.g. issue #1 "repo setup") is not a match; keep searching or
+ treat as no match. If no relevant issue exists, write a complete,
+ copy-paste-ready draft inline — title, description, and relevant
+ context — then ask the user: "Want me to file this, or will you copy
+ it?" If the agent files the issue, the title must include
+ `[extension-builder]` and the body must open with:
+ > *Surfaced by the VillageSQL Extension Builder skill while building
+ > ``.*
+
+ **Gate:** For every entry in `limitations.md`, record here: the
+ search query used, the matching issue number + title (or "no match"),
+ and the outcome (linked / drafted / user prompted). Phase 6 is not
+ complete until all entries are accounted for.
+
+4. **Announce the extension.** Write a complete, copy-paste-ready
+ **Feature** issue draft for
+ [villagesql-server](https://github.com/villagesql/villagesql-server/issues)
+ announcing the extension — include title, description, what it does,
+ and a link to the repo. Then ask the user: "Want me to file this, or
+ will you copy it?" VillageSQL uses these to consider adding community
+ extensions to the website. Suggested title:
+ `[Community Extension] `. If the agent files it, the
+ body must open with:
+ > *Filed by the VillageSQL Extension Builder skill.*
+
+5. **Verify skill vocabulary is absent.** The Phase 4 critic already
+ checked for this across all shipped files. Re-run a final grep over
+ every committed file (everything not in `.claude/`) for the forbidden
+ terms in `references/cto-checklist.md` → Testing Integrity. Expected
+ result: zero hits. If there are any, the CTO missed something —
+ rewrite the offending content as a behavior description and re-run
+ Phase 4 against the changed file (a content change after CTO sign-off
+ re-opens the gate). Do not ship until the grep is clean and Phase 4
+ has approved the changed text.
+
+6. **Verify `.claude/` is ignored, not staged.** Run
+ `git check-ignore .claude/tracking/architecture.md` — it should
+ print the path (meaning ignored). If not, fix `.gitignore` before
+ any commit.
+
+7. **Offer cleanup.** Ask the user whether to uninstall and remove the
+ extension. If yes:
+ 1. Check for dependent columns:
+ ```sql
+ SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, COLUMN_TYPE
+ FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE DATA_TYPE LIKE '.%' OR COLUMN_TYPE LIKE '.%';
+ ```
+ Drop or migrate any before uninstalling.
+ 2. `UNINSTALL EXTENSION ;`
+ 3. `rm -rf /_expanded/`
+
+8. **Summary.** Present a structured closing summary to the user.
+ This is the handoff — someone who wasn't in the session should be able
+ to read it and understand exactly what was built and what comes next.
+
+ **What you built**
+ - Extension name (install name and repo name)
+ - Number of functions and one-line description of what the extension does
+ - Any custom types defined, with a one-sentence description of the
+ storage format
+ - The `INSTALL EXTENSION` command and a one-liner "quick start" SQL
+ example that demonstrates the most common use case
+
+ **Known limitations**
+ For each entry in `.claude/tracking/limitations.md`, one line stating
+ the constraint and its outcome: linked issue # (with URL), drafted
+ issue (copy-paste ready inline), or "no upstream issue exists."
+
+ **Commit**
+ - Run `git log -1 --oneline` and show the SHA and summary line.
+
+ **What to do next**
+ Three concrete, specific items — not generic advice. Examples: "👍 issue
+ #NNN to signal demand for aggregate function support," "run
+ `perl mysql-test-run.pl --suite=mysql-test` after any code change,"
+ "join discord.gg/KSr6whd3Fr to share feedback." Tailor to what
+ actually came up during the session.
+
+**Gate — all of the following must be true before presenting the Grand
+Finale:**
+- [ ] Step 1: `README.md` complete with all required sections (including
+ "Migrating from PostgreSQL" if `pg_port: true`); `TESTING.md` written
+ and cross-checked against actual files in `mysql-test/t/`
+- [ ] Step 2: "Known Limitations" section in `README.md` assembled from
+ `limitations.md`; if `limitations.md` was missing, reconstructed first
+- [ ] Step 3: Every `limitations.md` entry has a search query logged, a
+ match outcome (issue # + title or "no match"), and a result (linked /
+ drafted / user prompted)
+- [ ] Step 4: Extension announcement Feature issue drafted and user prompted
+- [ ] Step 5: Vocabulary grep clean — zero hits for forbidden terms across
+ all committed files
+- [ ] Step 6: `.claude/` confirmed git-ignored
+- [ ] Step 7: Cleanup offer made (user accepted or declined)
+- [ ] Step 8: Summary presented
+
+Do not present the Summary until every box above is checked. If any
+step was skipped, complete it now — do not ask the user whether to skip.
+
+---
+
+## Reference Index
+
+Detailed material lives in `references/`. Load on demand:
+
+| When you need... | Read |
+|---|---|
+| Core principles, scope, gate rules | `references/philosophy.md` |
+| VEF capability probes (headers + behavior) | `references/capabilities.md` |
+| Phase 4 critic agent checklist | `references/cto-checklist.md` |
+| Implementation standards, data patterns, naming | `references/patterns.md` |
+| Build, test, paths, DDL syntax | `references/environment.md` |
+| Porting a PostgreSQL extension (type mapping, NULL semantics, operators, SRFs, charset) | `references/pg-port-guide.md` — load at Phase 1 step 1 when `pg_port: true` |
+
+---
+
+## Resume Protocol
+
+Applies ONLY when the user explicitly asks to resume, OR after
+auto-compaction or a session crash mid-task. Do NOT apply this protocol
+on fresh invocations. Always resume from the last completed gate — do
+not restart from Phase 0.
+
+1. Re-read this skill file in full and `references/philosophy.md`.
+2. List `.claude/tracking/` and read every file present.
+3. Determine the last completed phase using the file inventory:
+ - `acceptance_criteria.md` → Phase 0 drafted; written by Phase 2
+ - `architecture.md` (with feasibility + binary layout if applicable)
+ → Phases 1–2 complete
+ - `limitations.md` (with Phase 3 reconciliation done) → Phase 3
+ complete
+ - `simplification.md` → Phase 3 step 6 complete
+ - `cto_review.md` → Phase 4 complete
+4. **Validate state against artifacts.** Run `mysql-test-run.pl`
+ against the suite and check whether the extension is installed.
+ Cross-check results against the artifact-determined phase:
+ - If artifacts say Phase 3+ complete but tests fail: assume
+ mid-Phase-3, regardless of what files exist. Ask the user to
+ confirm before re-entering Phase 3.
+ - If artifacts say Phase 4+ complete but the extension is not
+ installed: re-enter Phase 3 step 3 (build/install) before
+ continuing.
+ - If interrupted mid-phase (e.g. `architecture.md` exists but no
+ `limitations.md`, and scaffold exists but tests have never run):
+ treat as start of Phase 3 and confirm with the user.
+ - If artifacts and working tree agree, proceed.
+5. Announce the determined phase and working tree state to the user.
+ If there is any ambiguity or mismatch, ask for explicit confirmation
+ before proceeding — do not assume.
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/capabilities.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/capabilities.md
new file mode 100644
index 00000000..f371bd61
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/capabilities.md
@@ -0,0 +1,64 @@
+# VEF Capability Discovery
+
+Do not assume limitations from prior knowledge. Probe the SDK and the
+running server.
+
+## Header-discoverable (Phase 2 bootstrap)
+
+Assess all capabilities from the typed API headers (`vsql.h` and the
+`vsql/` subdirectory).
+
+- **Storage model.** Does the type builder expose only fixed-length
+ storage, or also variable-length? For fixed-length, the persisted length
+ sets the storage size and encode must write exactly that many bytes;
+ returning 0 via the length output parameter signals an error.
+
+ **If only fixed-length storage is available** and the type is
+ inherently variable in size (e.g., hstore, JSON-like, packed lists),
+ apply this workaround — only if the probe above confirms no
+ variable-length API exists:
+ 1. Size `persisted_length` to your practical maximum (e.g., the largest
+ valid value the type accepts).
+ 2. In encode: write the real data, then zero-pad to fill exactly
+ `persisted_length` bytes. Encode must write exactly that count.
+ 3. Embed an in-band header at a fixed offset (e.g., a 2- or 4-byte
+ byte count at the start) so decode knows where real data ends.
+ 4. In decode: read the in-band length, then process only that many
+ bytes — ignore the zero padding.
+ 5. Document this constraint in README under Known Limitations, naming
+ the VEF capability that would remove the need for it.
+
+- **Parameterized types.** Does the SDK expose registration functions for
+ types that accept `TYPE(N)` or `TYPE('key=value')` arguments? Look for
+ two registration flavors (integer shorthand and key=value string) and
+ the struct that carries parameter data from server to extension. Record
+ exact names. The canonical example is
+ `villagesql/examples/vsql-tvector/src/tvector.cc` in the server source
+ tree.
+
+- **Index registration.** Is an index registration API present? If not,
+ custom type columns cannot be indexed — do not design around index-based
+ lookup.
+
+- **Max VDF parameters.** Read the max-parameter constant. Functions
+ needing more inputs must use structured types or be split.
+
+- **Preview capabilities.** Headers under a `preview/` subdirectory are
+ preview capabilities — documented but unstable across server builds.
+ They may include column storage, index hooks, system variables, and
+ background threads. If a preview API is needed, record it in
+ `.claude/tracking/limitations.md` so it surfaces in the README.
+
+## Behavior-discoverable (after first install in Phase 3)
+
+These can't be probed in Phase 1 because no extension is installed yet.
+Run them as part of Phase 3 once the extension is built and installed for
+the first time, and record results in `.claude/tracking/limitations.md`.
+
+- **Aggregate functions.** Create a custom type column and test `SUM` or
+ `AVG`. If they fail, only `COUNT(DISTINCT)`, `MIN`, `MAX`, and
+ `GROUP_CONCAT` are safe — document this constraint.
+
+- **Extension upgrade path.** Test `ALTER EXTENSION` or equivalent. If it
+ doesn't exist, type changes require `UNINSTALL` + `INSTALL` — document
+ for users.
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/cto-checklist.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/cto-checklist.md
new file mode 100644
index 00000000..79afed97
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/cto-checklist.md
@@ -0,0 +1,87 @@
+# CTO Review Checklist
+
+The Phase 4 critic agent reads this file plus the full `src/` and
+`mysql-test/` content, and returns a per-item verdict (PASS/FAIL with
+file:line evidence) plus an overall verdict. The agent must read code
+independently — do not summarize the source, do not trust prior summaries.
+
+## Scope & Tests
+
+- [ ] Every `.test` file has a corresponding `.result` file with actual
+ output.
+- [ ] Each `.test` file leaves no residual state. If it installs the
+ extension, it uninstalls at cleanup. Use `DROP/CREATE DATABASE` for
+ data isolation.
+- [ ] Extension can be cleanly uninstalled and reinstalled between test
+ runs.
+- [ ] Full standard API implemented (or omissions documented in
+ `limitations.md`).
+
+## Testing Integrity
+
+- [ ] `mysql-test/r/` directory exists and is non-empty.
+- [ ] `.result` files generated by test runner, not written by hand.
+- [ ] `.result` files verified against actual output by inspection.
+- [ ] No skill-internal vocabulary anywhere in shipped files (`.test`,
+ `.result`, `README.md`, `TESTING.md`, `AGENTS.md`, `CLAUDE.md`,
+ `GEMINI.md`, source comments, commit messages). Forbidden terms:
+ `Criterion N` (any number), `Phase N`, `Behavior probe`, `UAT`,
+ `acceptance_criteria`, `Persona`, `Product Strategist`, `Architect`,
+ `Team Lead`, `CTO`, `End-User`. The only allowed exceptions are
+ quoted user-facing strings. Test comments describe the behavior
+ asserted, not the workflow that produced them.
+
+## Build & Portability
+
+- [ ] No hardcoded user paths in `CMakeLists.txt` or scripts.
+- [ ] Build supports environment variables for SDK and binary paths.
+- [ ] Temporary files cleaned up on exit (using `trap`).
+- [ ] Suite directory is named `mysql-test/` (matching all other
+ VillageSQL extensions), not `test/`.
+
+## Code Integrity
+
+- [ ] All VEF struct pointer dereferences are protected.
+- [ ] Off-by-one check: `offset + len <= buf_size` in all binary parsing.
+- [ ] Result type uses constants from Phase 2 bootstrap — never deprecated
+ aliases.
+- [ ] All STRING returns set actual-length to bytes written.
+- [ ] Encode/decode error signaling matches the API in use — read the
+ typed API headers for the exact convention (typed wrappers commonly
+ use `out.set_length()` / `out.error()`; older raw shapes use
+ `false`/`true` return codes).
+- [ ] Error messages are informative.
+- [ ] `try/catch` on all entry points — both type system functions
+ (encode/decode/compare/hash) and every VDF implementation. Exception:
+ encode/decode registered through SDK conversion wrappers only.
+- [ ] Implementation uses the typed API only — no `abi/` headers anywhere.
+- [ ] No `using namespace` directives at file scope.
+- [ ] Any preview API use is documented in `limitations.md`.
+
+## Hot-Path Performance
+
+These are static checks — code review, not benchmarks.
+
+- [ ] No heap allocation (malloc/new/std::vector construction) inside VDF
+ implementations or type encode/decode functions. Allocations belong in
+ initialization, not per-row execution.
+- [ ] No unnecessary string copies before writing into `result->str_buf` or
+ the typed output buffer. Write directly where possible.
+- [ ] Null input checked and returned early (before any real work) in every
+ VDF implementation.
+- [ ] No shared mutable state accessed without a lock. If shared state is
+ unavoidable, confirm the lock is as narrow as possible.
+- [ ] No I/O, syscalls, or blocking operations on the hot path (e.g. file
+ reads, `gettimeofday` in a tight loop, DNS lookups). If the extension's
+ purpose requires I/O (e.g. vsql-http), document the per-call cost in
+ `limitations.md`.
+
+## Files Shipped
+
+- [ ] `LICENSE` present (GPL-2.0 from template, unmodified).
+- [ ] `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` describe this extension, not
+ the template boilerplate.
+- [ ] `.claude/tracking/` is not staged — confirm with `git check-ignore`.
+- [ ] No hello-world template artifacts remain (`src/hello.cc`,
+ `mysql-test/t/hello_basic.test`,
+ `mysql-test/r/hello_basic.result`).
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/environment.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/environment.md
new file mode 100644
index 00000000..a65e1a03
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/environment.md
@@ -0,0 +1,123 @@
+# Environment & Commands
+
+## Build workflow
+
+```bash
+export VillageSQL_BUILD_DIR=/path/to/villagesql/build
+cd extension-name/
+./build.sh # Produces build/.veb
+cd build && make install # Copies .veb to VEB directory
+mysql -u root -e "INSTALL EXTENSION ;"
+```
+
+`build.sh` template: use the version already in the cloned template — it
+is correct. Verify it has `set -euo pipefail`, reads `VillageSQL_BUILD_DIR`,
+and runs `cmake` + `cmake --build`. If it differs from the template,
+update it.
+
+## Test suite layout
+
+```
+mysql-test/
+├── suite.opt # Optional suite-wide flags (e.g. --log-error-verbosity=3)
+├── t/ # *.test files
+└── r/ # *.result files (generated via --record)
+```
+
+The suite directory must be named `mysql-test/` to match all other
+VillageSQL extensions. Never `test/`.
+
+## Run MTR from `{build_dir}/mysql-test`
+
+```bash
+perl mysql-test-run.pl --suite=/path/to/extension-name/mysql-test
+perl mysql-test-run.pl --suite=/path/to/extension-name/mysql-test --record
+```
+
+## MTR test file syntax
+
+**Comments:** use `#` for comments, not `--`. A bare `--` prefix is not
+a comment — it is parsed as a command prefix and will cause a syntax
+error or unexpected behaviour.
+
+```
+# This is a correct comment
+-- This is NOT a comment — do not use this form
+```
+
+**`--echo` is a directive, not a comment prefix.** It prints its
+argument to the test output and appears in the `.result` file.
+
+## Common mysqltest directives
+
+```
+--echo message
+--error ER_WRONG_ARGUMENTS
+--disable_warnings / --enable_warnings
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+```
+
+Always use fully-qualified function names: `SELECT vsql_foo.my_func(...)`.
+Install at test top, uninstall at bottom (or use `suite.opt`).
+
+## Outbound network calls in tests
+
+```
+--exec python3 -m http.server 18888 --directory $MYSQLTEST_VARDIR &>/tmp/test.log &
+--exec sleep 1
+SELECT vsql_webhook.webhook_call('http://127.0.0.1:18888/');
+--exec kill $(lsof -ti:18888) 2>/dev/null || true
+```
+
+## Key paths
+
+- Staged SDK: `{build_dir}/villagesql-extension-sdk-*/` (newest by mtime)
+- SDK version: `{sdk_dir}/bin/villagesql_config --version`
+- SDK headers: `{sdk_dir}/include/` and `{sdk_dir}/include-dev/` (typed
+ API may live in either; check both — see Phase 2 bootstrap)
+- mysql (dev build): `{build_dir}/runtime_output_directory/mysql`
+- mysqld (dev build): `{build_dir}/runtime_output_directory/mysqld`
+- VEB directory: query the server (`SHOW VARIABLES LIKE 'veb_dir'`) —
+ that value is authoritative. Typical dev-build location is
+ `{build_dir}/villagesql/lib/veb/` but production installs vary.
+
+## Row size limit for fixed-length custom types
+
+InnoDB's maximum row size is ~65535 bytes. Fixed-length types (where
+`persisted_length` is a constant, not variable) consume their full
+allocation in every row regardless of actual content. A single column
+of `persisted_length = 65535` will fail `CREATE TABLE` with
+`ERROR 1118: Row size too large`.
+
+**Before finalizing `persisted_length` in Phase 1:** run a quick
+sanity check — attempt `CREATE TABLE t (col .)` with
+the proposed value. If it fails, reduce the value (65000 is a safe
+ceiling that leaves room for row overhead and additional columns). Do
+not skip this test — the failure only surfaces at table-creation time,
+not at build or install time.
+
+## DDL syntax for custom types
+
+```sql
+CREATE TABLE t (col vsql_hstore.hstore);
+CREATE TABLE t (col vsql_tvector.tvector(128)); -- integer shorthand
+CREATE TABLE t (col vsql_tvector.tvector('dimension=128')); -- key=value string
+```
+
+Extension name must be the install name (e.g., `vsql_hstore`).
+
+`CAST(... AS )` is **not** supported — custom types aren't
+wired into MySQL's CAST grammar. To get a value of a custom type, insert
+into a column of that type or call the type's constructor VDF directly.
+
+## Useful commands
+
+- Verify loaded: call one of its functions. There is no `SHOW EXTENSIONS`.
+- Uninstall: `UNINSTALL EXTENSION ;` — no `IF EXISTS`.
+ Use `|| true` in shell. ERROR 3219 when uninstalling a not-installed
+ extension is safe to ignore.
+- Reinstall (shell): run `UNINSTALL` and `INSTALL` as separate `mysql -e`
+ calls.
+- Remove cache: `rm -rf /_expanded/`
+- VEB contents: `make show_veb` (from build dir)
+- Symbols: `nm -gU .so | grep vef_register`
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/patterns.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/patterns.md
new file mode 100644
index 00000000..fdd06197
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/patterns.md
@@ -0,0 +1,136 @@
+# VEF Implementation Patterns
+
+Standards, safety patterns, and data conventions. Exact API names come
+from Phase 2 bootstrap — anything named here is illustrative.
+
+## Technical Standards & Safety Patterns
+
+- **API Compliance.** Staged SDK headers are authoritative. The
+ [vsql-extension-template](https://github.com/villagesql/vsql-extension-template)
+ is authoritative for project structure and CMake patterns. Other
+ published extensions may use older API patterns — do not use them as
+ references. Never use `vsql_simple` or `vsql_complex` — their build and
+ install structure differ from standalone extensions.
+
+- **Typed C++ API Only.** All implementation goes through `vsql.h` and the
+ `vsql/` subdirectory. Never use the raw ABI — not its structs, not its
+ constants, not its headers (anything under `abi/`).
+
+- **Thread Safety.** All functions must be re-entrant. No global mutable
+ state.
+
+- **Binary Portability.** Little-Endian bit-shifting for multi-byte
+ integers; `memcpy` for floats/doubles (always native format).
+
+- **Exception Safety.** All SQL entry points must be wrapped in `try/catch
+ (...)`.
+
+- **Memory Safety.** Bounds checking before every `memcpy` or `memset`.
+
+- **Allocation Efficiency.** Use `std::string_view` for parsing. Never
+ `push_back(c)` in a loop. Only allocate `std::string` for the final
+ in-memory representation. Use `.reserve()`.
+
+- **Move semantics in initializer lists.** Do not move from a variable
+ and also use it in the same initializer list — C++ does not guarantee
+ evaluation order within brace-init lists. `std::pair{key, {std::move(key), val}}`
+ is undefined behaviour: `key` may be moved before the first element is
+ read. Move into a local first, then construct: `auto k = std::move(key);
+ return {k, {std::move(k), val}};` — or copy where the value is small.
+
+- **No file-scope `using namespace`.** Per-function `using` declarations
+ or fully-qualified names only.
+
+## VEF Data Patterns
+
+Semantic guide only — exact names come from Phase 2 bootstrap.
+
+**Input values** (one struct per argument):
+- Null flag — check this first, before any other field.
+- String value + length (STRING inputs).
+- Integer value (INT inputs).
+- Real/float value (REAL inputs).
+- Binary value + length (BINARY/custom type inputs).
+
+**Result values:**
+- Result type field — set to the value/null/error constant from headers.
+ Never use aliases marked deprecated in the headers.
+- String buffer + max length + actual length — for STRING: write to
+ buffer, check max before writing, always set actual length.
+- Binary buffer + max length + actual length — for custom type returns.
+ Set the buffer size at registration to the type's persisted length
+ (silent 0-byte allocation otherwise — standalone calls like
+ `SELECT my_type('a','b')` fail with "output buffer too small").
+- Integer/real value — for INT/REAL returns.
+- Error message buffer — write via `snprintf` with the max error length
+ constant.
+
+**Encode/decode** (custom types): error-signaling convention depends on
+which API you're calling. The typed wrappers commonly use
+`out.set_length()` / `out.error()`. Older raw shapes use a boolean return
+where `false` = success and `true` = error. Read the type builder header
+to confirm before writing.
+
+**Type conversion wrappers.** The builder provides methods to register
+string↔type conversions. When encode/decode is registered through these
+wrappers, the SDK handles NULL and error plumbing — no inner `try/catch`
+needed. The `try/catch` rule applies to all entry points called directly
+by the server and to every VDF implementation function.
+
+**Deterministic attribute.** Mark VDFs used in CHECK constraints as
+deterministic (exact method: from builder headers) or the server rejects
+the `CREATE TABLE`. Functions returning random or time-dependent values
+(e.g., `*_generate`, `uuid_*v7`) must NOT be marked deterministic.
+
+**Entry point shape** (verbal — do not copy code from this skill): Every
+VDF entry point checks the input null flag, performs its work, sets the
+result type and value/buffer, and is wrapped in `try/catch (...)`. The
+actual function names, struct fields, and constants come from the typed
+API headers read in Phase 2 bootstrap — never from this document.
+
+## JSON & Type Specifics
+
+Applies to key-value and JSON-like extension types.
+
+- **JSON Escaping.** Use a dedicated escaping function for all string
+ values in JSON output. Never concatenate raw strings — they may contain
+ `"`, `\`, or control characters.
+- **Numeric Detection.** Handle decimals, negatives (`-5`), and scientific
+ notation (`1.2e-3`).
+- **Sorted Keys.** Internal storage must be sorted by key for `O(log n)`
+ search.
+- **Deduplication (last-key-wins).** When the same key appears multiple
+ times, the last occurrence wins (PostgreSQL semantics). `std::sort` +
+ `std::unique` is incorrect for this — it removes the first duplicate
+ encountered, keeping the *first* occurrence, not the last. Correct
+ algorithm: iterate backwards through the parsed pairs, use an
+ `std::unordered_set` to track keys already seen, and keep only the
+ first time you encounter each key in this reverse pass (which is the
+ last occurrence in the original string). Then sort the deduplicated
+ result by key.
+- **MySQL backslash escaping.** MySQL processes backslash escapes in
+ single-quoted literals before the string reaches your extension. A
+ test input like `'"key\"quoted\""=>"val"'` arrives at your extension
+ as `"key"quoted""=>"val"` — the backslashes are consumed by MySQL,
+ not passed through. Write test inputs as MySQL sees them (after escape
+ processing), not as the raw literal. This is a silent failure mode:
+ the extension receives a different string than intended and may return
+ NULL with no error.
+
+## Function Naming Conventions
+
+MySQL uses `TYPE_VERB` or `TYPE_NOUN` patterns with underscores:
+- Good: `HTTP_GET`, `URL_ENCODE`, `AES_ENCRYPT`, `JSON_EXTRACT`,
+ `INET_ATON`
+- Bad: `http` (too terse), `urlencode` (compound — PHP/Python style)
+
+When porting a PostgreSQL extension, derive MySQL-idiomatic names rather
+than copying Postgres names. Do not let the extension's name leak into
+function names that don't belong to the extension's type (e.g.,
+`typeid_uuidv7_generate` reads as "the typeid module's UUID generator";
+prefer `uuidv7_generate`).
+
+**Reserved words to avoid as function names** (cause syntax errors
+without backticks): `keys`, `values`, `check`, `table`, `index`, `select`,
+`delete`, `replace`, `insert`, `update`, `primary`, `foreign`, `and`,
+`or`, `in`.
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/pg-port-guide.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/pg-port-guide.md
new file mode 100644
index 00000000..6f74beba
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/pg-port-guide.md
@@ -0,0 +1,188 @@
+# PostgreSQL Port Guide
+
+Load this file at the start of Phase 1 when `pg_port: true` is recorded in
+`architecture.md`. Read it before researching the source extension.
+
+## Pre-Port Analysis (do this before architecture.md)
+
+**Source research — best-effort, two lookups max. Do not block or retry.**
+
+1. **Official docs.** Check postgresql.org for the extension (e.g.
+ `https://www.postgresql.org/docs/current/.html`). If it's a
+ contrib extension it will be there; third-party extensions won't be.
+
+2. **Source repo.** Search for the extension's GitHub repo
+ (` postgresql extension site:github.com`). If found, fetch:
+ - The README for function signatures, NULL semantics, and operator
+ mappings.
+ - The regression test file (`sql/.sql` or similar) — concrete
+ input/output pairs to adapt directly into acceptance criteria.
+ These are higher-value than prose docs for implementation.
+
+If either lookup fails or returns nothing useful, proceed from the user's
+description and your own knowledge of the extension. Record what was found
+(or "not found") in `architecture.md` under `## Source Research` before
+continuing.
+
+Enumerate the source extension's full function list and categorize each:
+
+| Category | Meaning |
+|---|---|
+| **Full** | Implementable with exact semantics under current VEF |
+| **Workaround** | Implementable with a meaningful behavioral difference (e.g. JSON array instead of row set) |
+| **Blocked** | Not implementable under current VEF — document in `limitations.md` immediately |
+
+Record this table in `.claude/tracking/architecture.md` under
+`## PostgreSQL Function Map`. Never start writing C++ until the map is
+complete — missing functions discovered in Phase 3 cause expensive rework.
+
+**Run this checklist before categorizing. Each "yes" requires special
+handling — see the relevant section below:**
+
+- [ ] Set-returning functions (SRFs like `skeys`, `svals`, `each`, `unnest`)?
+- [ ] Catalog or system table access?
+- [ ] Aggregate functions?
+- [ ] `CHECK` constraint validators or trigger functions?
+- [ ] `DEFAULT` expressions that call functions?
+- [ ] Per-connection or per-session state?
+- [ ] Functions marked `IMMUTABLE` for index optimization?
+- [ ] Large data structures (could exceed `max_allowed_packet`)?
+
+**Blocked by default:**
+- SRFs — VEF has no row-set return; use JSON array workaround (see below)
+- Catalog/system table access — not available to VEF extensions
+- Aggregate functions — probe in Phase 3 step 3; treat as tentative-blocked
+- Trigger functions — MySQL triggers are SQL-only; cannot delegate to UDFs
+- CHECK constraint validators — MySQL 8.0.16+ enforces CHECK but cannot call UDFs
+
+## Type Mapping
+
+| PostgreSQL type | MySQL/VEF type | Notes |
+|---|---|---|
+| `text`, `varchar` | VEF `STRING` | Use `VARCHAR(N)` in DDL; pick N from domain |
+| `bytea` | `VARBINARY` | Binary-safe; never use `VARCHAR` for binary data — MySQL will corrupt it with charset conversion |
+| `boolean` | `TINYINT(1)` | MySQL won't enforce 0/1 at storage — **do it in C++** |
+| `integer`, `int4` | `INT` | |
+| `bigint`, `int8` | `BIGINT` | Signed max 2^63−1; same as PG `bigint` but not `numeric` |
+| `real`, `float4` | `DOUBLE` | Use `DOUBLE` not `FLOAT` — MySQL `FLOAT` is 32-bit (~7 sig digits) and lossy |
+| `double precision`, `float8` | `DOUBLE` | |
+| `numeric`, `decimal` | `DECIMAL(M,D)` | MySQL max M=65, D=30; PG `numeric` is arbitrary-precision — document overflow if the domain exceeds this |
+| `uuid` | vsql-uuid `uuid` type if available; else `BINARY(16)` | `BINARY(16)` sorts lexicographically, not RFC 4122 order — document if ordering matters |
+| `json`, `jsonb` | MySQL `JSON` | Always UTF-8 internally; no charset handling needed in C++ |
+| `timestamp` | `DATETIME` | No timezone field |
+| `timestamptz` | `DATETIME` | The UTC offset is discarded entirely — document this; recommend callers normalize to UTC before storing |
+| `interval` | `BIGINT` (milliseconds) | Milliseconds preserve sub-second precision; document the unit |
+| Custom/opaque type | VEF custom type with binary storage | |
+
+## NULL Semantics
+
+MySQL propagates NULL by default (matches PostgreSQL's `CALLED ON NULL INPUT`).
+
+- Check `arg->is_null` first — return `IS_NULL` for any required NULL argument.
+- Exception: functions explicitly NULL-safe in PostgreSQL (e.g. `COALESCE`-like) — preserve and document.
+- Never silently coerce NULL to a default value. If the PG function does this, document it.
+- Division by zero returns NULL + warning in MySQL (not an error) — follow this for analogous numeric edge cases.
+
+## Error Handling
+
+PostgreSQL raises exceptions. MySQL convention: return NULL for bad input;
+use the VEF error/warning mechanism for hard failures.
+
+**Verify during Phase 2 bootstrap what warning/error API VEF exposes.** The
+decision table below assumes one exists — confirm before designing error behavior.
+
+| Situation | MySQL idiom |
+|---|---|
+| Invalid input format | Return NULL; emit VEF warning if available; document |
+| Out-of-range value | Return NULL; validate in C++ — MySQL won't catch it; document valid range |
+| Type mismatch caught at build time | Compile error via VEF typed API — no runtime check needed |
+| Internal invariant violation | VEF error mechanism with descriptive message |
+| Output buffer truncation | Return NULL; never silently truncate; document the limit |
+
+Don't assume callers run `SHOW WARNINGS` — many frameworks suppress warnings
+silently. For errors callers must detect, return a documented sentinel value.
+
+## Operator → Function Translation
+
+Every PostgreSQL operator becomes a named function. Use `TYPE_VERB` or
+`TYPE_PREDICATE` naming. Key patterns:
+
+| PG operator | MySQL function |
+|---|---|
+| `->` / `->>` | `_get(val, key)` / `_get_text(val, key)` |
+| `#>` / `#>>` | `_get_path(val, path)` / `_get_path_text(val, path)` |
+| `?` / `?&` / `?\|` | `_has_key` / `_has_all_keys` / `_has_any_key` |
+| `@?` / `@@` | `_path_exists` / `_path_match` |
+| `\|\|` | `_concat` or `_merge` |
+| `-` (delete key/value) | `_delete` / `_delete_val` |
+| `@>` / `<@` / `&&` | `_contains` / `_contained_by` / `_overlaps` |
+
+**Rules:** Type prefix is the type name, not the extension name. Boolean
+predicates use adjective/verb form (`contains`, not `is_contained`). Avoid
+reserved words: `keys`, `values`, `check`, `table`, `index`, `select`,
+`delete`, `replace`, `insert`, `update` — use `_keys`, `_vals`
+etc. Verify names don't conflict with MySQL 8.0.x built-ins for the target
+version range.
+
+## Set-Returning Functions
+
+VEF has no row-set return. Every SRF becomes a scalar function returning a
+JSON array. JSON is preferred over CSV because keys/values may contain
+commas, and `JSON_TABLE()` lets callers unpack it into rows if needed.
+
+Commit to a documented element order (insertion, sorted, or undefined) and
+test it. Callers may depend on it.
+
+Document in the function reference: element type, structure, ordering
+guarantee, and that `JSON_TABLE()` is the unpivot path.
+
+Add a `limitations.md` entry for every blocked SRF: function name,
+workaround offered, and a note about `JSON_TABLE()`.
+
+## MySQL Behavioral Differences
+
+These diverge from PostgreSQL and will cause bugs if not handled explicitly.
+
+**Unsupported mechanisms — mark all functions relying on these as Blocked:**
+- **CHECK constraint validators:** MySQL 8.0.16+ enforces CHECK but cannot
+ call UDFs. Validate in the parse/store function instead.
+- **DEFAULT expressions:** MySQL 8.0.13+ supports `DEFAULT (expr)` but not
+ with UDFs. Provide SQL trigger templates or application-level defaults.
+- **Trigger functions:** MySQL triggers are SQL-only. If the source provides
+ trigger functions, supply SQL trigger templates that call the extension.
+
+**Thread safety:** VEF runs in the calling connection thread. PostgreSQL's
+process-per-connection model makes global state implicitly safe; MySQL does
+not. Audit the source for global/static variables — any shared state needs
+a mutex or connection-local storage.
+
+**Expression-based indexes:** `CREATE INDEX ON t ((my_func(col)))` requires
+the function to be deterministic. If the source marks functions `IMMUTABLE`,
+those qualify — document which do and which don't.
+
+**Memory limits:** `max_allowed_packet` (default 64 MB) caps function inputs
+and outputs. If the extension processes large inputs, test at realistic sizes
+and document the effective limit.
+
+**Strict mode + generated columns:** If the function is used in a
+`GENERATED ALWAYS AS (my_func(...)) STORED` column, a NULL return in strict
+mode will fail the INSERT. Test this explicitly.
+
+**Connection-local state:** If the source maintains per-session state, verify
+during Phase 2 bootstrap whether VEF exposes connection-handle APIs for it.
+If not, document the gap in `limitations.md`.
+
+## "Migrating from PostgreSQL" README Section
+
+Write this section after Phase 5 UAT so all examples are verified. Include:
+
+1. **Function name mapping table** — PG name → VillageSQL name, every rename.
+2. **Operator equivalents table** — PG operator → VillageSQL function call,
+ with a one-line SQL example for each.
+3. **Before/after SQL examples** — for the most common use cases, show the
+ PostgreSQL query and the VillageSQL equivalent side-by-side.
+4. **Behavioral differences** — NULL handling, error behavior, type
+ differences (especially BOOLEAN enforcement, TIMESTAMPTZ offset loss,
+ interval units), SRF return format and ordering, case sensitivity.
+5. **Missing functions** — every Blocked function: one line on why, and the
+ closest workaround.
diff --git a/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/philosophy.md b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/philosophy.md
new file mode 100644
index 00000000..0e979d2a
--- /dev/null
+++ b/plugins/villagesql/villagesql-skills/skills/vsql-extension-builder/references/philosophy.md
@@ -0,0 +1,77 @@
+# Core Philosophy
+
+Read at the start of every session. These principles override anything in
+the workflow that contradicts them.
+
+- **Correctness within Constraints.** Implement the best possible solution
+ within current VEF capabilities. When a feature cannot be fully realized,
+ implement the best safe workaround the typed API supports and document the
+ limitation in `.claude/tracking/limitations.md`.
+
+- **Incremental Verification.** Test every function immediately after
+ implementation. NEVER proceed with failing tests.
+
+- **No Gate Skipping.** The phase gates (the Phase 3 three-agent
+ simplification review and the Phase 4 critic checklist review) are
+ mandatory. Run them as written even if the user is being terse, even if
+ the work feels small, even if it slows iteration. Never offer to skip a
+ gate; never call a gate optional. The only escape is the user explicitly
+ saying "skip Phase N" by name, in which case do it and note the skip in
+ `.claude/tracking/`.
+
+- **Deep Debugging.** When a failure occurs, add diagnostic output to
+ understand the "why" before attempting a fix. Always show actual test
+ output.
+
+- **Zero Tolerance for Hallucination.** Only report test results you have
+ actually observed. Never assume success.
+
+- **Fail Loud, Fail Early.** If any step fails — connectivity, bootstrap,
+ build, test, install — stop immediately. Report the exact error and any
+ paths or values checked. Do not proceed, do not guess at API signatures,
+ do not fabricate values to keep going.
+
+- **Typed C++ API Only.** Locate `vsql.h` and the `vsql/` subdirectory in
+ the SDK during Phase 2 bootstrap. All implementation work goes through
+ this typed API. If it is not present in the SDK, stop and flag this to
+ the user before writing any implementation code. **Never read headers
+ under any `abi/` directory** — those are internal server/protocol
+ headers, not the extension interface. If you find yourself reading one,
+ stop and return to the typed API headers.
+
+- **Preview vs. Stable.** Within the typed API, headers under a `preview/`
+ subdirectory are preview capabilities — documented but unstable across
+ server builds. Everything else is stable. Design against stable headers
+ when possible; note any preview API use in
+ `.claude/tracking/limitations.md`.
+
+- **VEF Extensions Only.** This skill builds VEF extensions only. If a
+ requested capability is beyond what VEF currently supports, the answer is
+ to implement the best workaround the VEF typed API allows, document the
+ gap in `.claude/tracking/limitations.md`, and use the Phase 6 call to
+ action to direct the user to file a VillageSQL issue or upvote an
+ existing one. MySQL plugins (`INSTALL PLUGIN`, MYSQL_PLUGIN ABI) and
+ MySQL server components (`INSTALL COMPONENT`, component service
+ framework) are never a suggested alternative — they have different build
+ systems and ABIs and are outside the scope of this skill entirely.
+
+# Handling Scope Variations
+
+- **Default:** Implement the full standard API.
+- **Minimal requests:** Maintain all quality standards and the full
+ workflow. Document in README: "Partial implementation. Missing: [list]."
+- **PostgreSQL ports:** Implement every function VEF can support. Where VEF
+ constraints prevent full compatibility, use the best workaround, document
+ each gap in `limitations.md` immediately, and surface all gaps in the
+ README.
+
+# Principle: Process, Not API
+
+The SKILL.md and all reference files in this directory encode **process
+and principles, not API**. Any specific name appearing in this skill —
+struct fields, constants, builder methods, header filenames — is
+illustrative only and may be outdated. Always verify against live SDK
+headers from Phase 2 bootstrap.
+
+If you're writing code based on a name from this skill rather than a name
+from the live headers, stop and re-read the headers.