Integration reference for Plankton (thanks to @alxfazio), a write-time code quality enforcement system for Claude Code. Plankton runs formatters and linters on every file edit via PostToolUse hooks, then launches a Claude subprocess to fix violations the Agent missed.
When to use
- You want automatic formatting and linting on every file edit (not just at commit time).
- You need to defend against the Agent bypassing checks by modifying linter configuration instead of actually fixing the code.
- You want tiered model routing for fix tasks (Haiku for simple style, Sonnet for logic, Opus for types).
- You develop in multiple languages (Python, TypeScript, Shell, YAML, JSON, TOML, Markdown, Dockerfile).
How it works
Three-phase architecture
Whenever Claude Code edits or writes a file, Plankton's multi_linter.sh PostToolUse hook runs:
阶段 1: 自动格式化 (静默)
├─ 运行格式化程序 (ruff format, biome, shfmt, taplo, markdownlint)
├─ 静默修复 40-50% 的问题
└─ 不向主智能体输出任何内容
阶段 2: 收集违规项 (JSON)
├─ 运行 Linter 并收集无法自动修复的违规项
├─ 返回结构化 JSON: {line, column, code, message, linter}
└─ 仍不向主智能体输出任何内容
阶段 3: 委派 + 验证
├─ 启动带有违规 JSON 的 claude -p 子进程
├─ 根据违规复杂性路由到不同层级的模型:
│ ├─ Haiku: 格式化、导入、样式 (E/W/F 代码) — 120s 超时
│ ├─ Sonnet: 复杂性、重构 (C901, PLR 代码) — 300s 超时
│ └─ Opus: 类型系统、深度推理 (unresolved-attribute) — 600s 超时
├─ 重新运行阶段 1+2 以验证修复结果
└─ 如果清理完成则 Exit 0,如果仍存在违规项则 Exit 2(报告给主智能体)
What the main Agent sees
| Scenario | What the Agent sees | Hook exit code |
|---|---|---|
| No violations | None | 0 |
| The subprocess fixed all issues | None | 0 |
| Violations still remain after the subprocess handles them | [hook] N violation(s) remain |
2 |
| Advisory information (duplicates, outdated tools) | [hook:advisory] ... |
0 |
The main Agent only sees issues the subprocess cannot fix. Most quality issues are resolved transparently.
Configuration protection (defense against rule gaming)
The LLM sometimes tries to modify .ruff.toml or biome.json to disable rules instead of fixing the code. Plankton prevents this through three layers of protection:
- PreToolUse hook —
protect_linter_configs.shblocks edits to all linter configuration before the modification happens. - Stop hook —
stop_config_guardian.shdetects configuration changes at the end of the session viagit diff. - Protected file list — including
.ruff.toml,biome.json,.shellcheckrc,.yamllint,.hadolint.yaml, etc.
Package manager enforcement
The PreToolUse hook on Bash blocks use of legacy package managers:
pip,pip3,poetry,pipenv→ Blocked (please useuv)npm,yarn,pnpm→ Blocked (please usebun)- Allowed exceptions:
npm audit,npm view,npm publish
Setup
Quick start
# 将 Plankton 克隆到你的项目(或共享位置)
# 注: Plankton 由 @alxfazio 开发
git clone https://github.com/alexfazio/plankton.git
cd plankton
# 安装核心依赖
brew install jaq ruff uv
# 安装 Python linter
uv sync --all-extras
# 启动 Claude Code — 钩子将自动激活
claude
No install commands, no plugin configuration. When you run Claude Code in the Plankton directory,.claude/settings.json the hooks in
are loaded automatically.
To use the Plankton hooks in your own project:
- Copy the
.claude/hooks/directory into your project. - Copy the hook configuration from
.claude/settings.json. - Copy the linter configuration files (
.ruff.toml,biome.json, etc.). - Install the corresponding linter for your language.
Language-specific dependencies
| Language | Required | Optional |
|---|---|---|
| Python | ruff, uv |
ty (type), vulture (dead code), bandit (safe) |
| TypeScript/JS | biome |
oxlint, semgrep, knip (dead export) |
| Shell | shellcheck, shfmt |
— |
| YAML | yamllint |
— |
| Markdown | markdownlint-cli2 |
— |
| Dockerfile | hadolint (>= 2.12.0) |
— |
| TOML | taplo |
— |
| JSON | jaq |
— |
Works with ECC
Complementary, not overlapping
| Concern | ECC | Plankton |
|---|---|---|
| Code quality enforcement | Post-tool-use hooks (Prettier, tsc) | Post-tool-use hooks (20+ Linters + subprocess fixes) |
| Security scanning | AgentShield, security-reviewer agent | Bandit (Python), Semgrep (TypeScript) |
| Config protection | — | Pre-tool-use hook blocking + stop hook detection |
| Package manager | Detection + setup | Enforcement (blocks legacy package managers) |
| CI integration | — | Pre-commit hooks for git |
| Model routing | Manual (/model opus) |
Automatic (violation complexity → corresponding tier) |
Recommended combination
- Install ECC as your plugin (agents, skills, commands, rules).
- Add Plankton hooks for write-time quality enforcement.
- Use AgentShield for security auditing.
- Use ECC's verification loop (verification-loop) as the final gate before PRs.
Avoiding hook conflicts
If you run both ECC and Plankton hooks:
- ECC's Prettier hook and Plankton's biome formatter may conflict on JS/TS files.
- Workaround: disable ECC's Prettier post-tool-use hook when using Plankton (Plankton's biome is more comprehensive).
- The two can coexist on different file types (ECC can handle what Plankton doesn't cover).
Configuration reference
Plankton's .claude/hooks/config.json controls all behavior:
{
"languages": {
"python": true,
"shell": true,
"yaml": true,
"json": true,
"toml": true,
"dockerfile": true,
"markdown": true,
"typescript": {
"enabled": true,
"js_runtime": "auto",
"biome_nursery": "warn",
"semgrep": true
}
},
"phases": {
"auto_format": true,
"subprocess_delegation": true
},
"subprocess": {
"tiers": {
"haiku": { "timeout": 120, "max_turns": 10 },
"sonnet": { "timeout": 300, "max_turns": 10 },
"opus": { "timeout": 600, "max_turns": 15 }
},
"volume_threshold": 5
}
}
Key settings:
- Disable languages you don't use to speed up hook runs.
volume_threshold— violations exceeding this value automatically escalate to a higher-tier model.subprocess_delegation: false— skip stage 3 entirely (report violations only).
Environment variable overrides
| Variable | Purpose |
|---|---|
HOOK_SKIP_SUBPROCESS=1 |
Skip stage 3 and report violations directly |
HOOK_SUBPROCESS_TIMEOUT=N |
Override model tier timeouts |
HOOK_DEBUG_MODEL=1 |
Log model selection decisions |
HOOK_SKIP_PM=1 |
Bypass package manager enforcement |
References
- Plankton (thanks @alxfazio)
- Plankton REFERENCE.md — full architecture documentation (thanks @alxfazio)
- Plankton SETUP.md — detailed installation guide (thanks @alxfazio)