- Move cross-cutting docs (personas, design system, implementation phases, Ideen.md) to .specify/memory/ - Move cross-cutting research and plans to .specify/memory/research/ and .specify/memory/plans/ - Extract 5 setup tasks from spec/setup-tasks.md into individual specs/001-005/spec.md files with spec-kit template format - Extract 20 user stories from spec/userstories.md into individual specs/006-026/spec.md files with spec-kit template format - Relocate feature-specific research and plan docs into specs/[feature]/ - Add spec-kit constitution, templates, scripts, and slash commands - Slim down CLAUDE.md to Claude-Code-specific config, delegate principles to .specify/memory/constitution.md - Update ralph.sh with stream-json output and per-iteration logging - Delete old spec/ and docs/agents/ directories - Gitignore Ralph iteration JSONL logs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8.7 KiB
date, git_commit, branch, topic, tags, status
| date | git_commit | branch | topic | tags | status | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-03-04T22:27:37.933286+00:00 | 91e566efea |
master | Automatic OpenAPI Validation Pipelines for Backpressure Hooks |
|
complete |
Research: Automatic OpenAPI Validation Pipelines
Research Question
What automatic validation pipelines exist for OpenAPI specs that can be integrated into the current Claude Code backpressure hook setup, running after the OpenAPI spec has been modified?
Summary
The project already has a PostToolUse hook system that runs backend compile checks and frontend lint/type-checks after Edit/Write operations. Adding OpenAPI spec validation requires a new hook script that triggers specifically when api.yaml is modified. Several CLI tools support OpenAPI 3.1.0 validation — Redocly CLI is the strongest fit given the existing Node.js toolchain, MIT license, active maintenance, and zero-config baseline.
Current Backpressure Setup
Hook Architecture (.claude/settings.json)
The project uses Claude Code hooks for automated quality gates:
| Hook Event | Trigger | Scripts |
|---|---|---|
PostToolUse |
Edit|Write tool calls |
backend-compile-check.sh, frontend-check.sh |
Stop |
Agent attempts to stop | run-tests.sh |
How Hooks Work
Each hook script:
- Reads JSON from stdin containing
tool_input.file_path - Pattern-matches the file path to decide if it should run
- Executes validation (compile, lint, type-check, test)
- Returns JSON with either success message or failure details
- On failure: outputs
hookSpecificOutputwith error context (PostToolUse) or{"decision":"block"}(Stop)
Existing Pattern for File Matching
# backend-compile-check.sh — matches Java files
case "$FILE_PATH" in
*/backend/src/*.java|backend/src/*.java) ;;
*) exit 0 ;;
esac
# frontend-check.sh — matches TS/Vue files
case "$FILE_PATH" in
*/frontend/src/*.ts|*/frontend/src/*.vue|frontend/src/*.ts|frontend/src/*.vue) ;;
*) exit 0 ;;
esac
An OpenAPI validation hook would use the same pattern:
case "$FILE_PATH" in
*/openapi/api.yaml|*/openapi/*.yaml) ;;
*) exit 0 ;;
esac
Existing OpenAPI Tooling in the Project
- Backend:
openapi-generator-maven-pluginv7.20.0 generates Spring interfaces fromapi.yaml(pom.xml:149-178) - Frontend:
openapi-typescriptv7.13.0 generates TypeScript types;openapi-fetchv0.17.0 provides type-safe client - No validation/linting tools currently installed — no Redocly, Spectral, or other linter config exists
Tool Evaluation
Redocly CLI (@redocly/cli)
| Attribute | Value |
|---|---|
| OpenAPI 3.1 | Full support |
| Install | npm install -g @redocly/cli or npx @redocly/cli@latest |
| CLI | redocly lint api.yaml |
| License | MIT |
| Maintenance | Very active — latest v2.20.3 (2026-03-03), daily/weekly releases |
| GitHub | ~1.4k stars (Redocly ecosystem: 24k+ combined) |
Checks: Structural validity against OAS schema, configurable linting rules (naming, descriptions, operation IDs, security), style/consistency enforcement. Built-in rulesets: minimal, recommended, recommended-strict. Zero-config baseline works immediately. Custom rules via redocly.yaml.
Fit for this project: Node.js already in the toolchain (frontend). npx form requires no permanent install. MIT license compatible with GPL-3.0. The @redocly/openapi-core package is already present as a transitive dependency of openapi-typescript in node_modules.
Spectral (@stoplight/spectral-cli)
| Attribute | Value |
|---|---|
| OpenAPI 3.1 | Full support (since v6.x) |
| Install | npm install -g @stoplight/spectral-cli |
| CLI | spectral lint api.yaml |
| License | Apache 2.0 |
| Maintenance | Active — latest v6.15.0 (2025-04-22), slower cadence |
| GitHub | ~3k stars |
Checks: Schema compliance, missing descriptions/tags/operationIds, contact/license metadata. Highly extensible custom rulesets via YAML/JS. Configurable severity levels.
Fit for this project: Well-established industry standard. Apache 2.0 compatible with GPL. Less actively maintained than Redocly (10 months since last release). Heavier custom ruleset system may be over-engineered for current needs.
Vacuum (daveshanley/vacuum)
| Attribute | Value |
|---|---|
| OpenAPI 3.1 | Full support (via libopenapi) |
| Install | brew install daveshanley/vacuum/vacuum or Go binary |
| CLI | vacuum lint api.yaml |
| License | MIT |
| Maintenance | Active — latest release 2025-12-22 |
| GitHub | ~1k stars |
Checks: Structural validation, Spectral-compatible rulesets, OWASP security checks, naming conventions, descriptions/examples/tags. Single Go binary — no runtime dependencies.
Fit for this project: Zero-dependency binary is appealing for CI. However, adds a non-Node.js tool dependency when the project already has Node.js. Spectral ruleset compatibility is a plus for portability.
oasdiff (oasdiff/oasdiff)
| Attribute | Value |
|---|---|
| OpenAPI 3.1 | Beta |
| Install | brew install oasdiff or Go binary |
| CLI | oasdiff breaking base.yaml revision.yaml |
| License | Apache 2.0 |
| Maintenance | Active — latest v1.11.10 (2026-02-05) |
| GitHub | ~1.1k stars |
Checks: 300+ breaking change detection rules (paths, parameters, schemas, security, headers, enums). Requires two spec versions to compare — not a standalone validator.
Fit for this project: Different category — detects breaking changes between spec versions, not structural validity. Useful as a CI-only check comparing HEAD~1 vs HEAD. OAS 3.1 support is still beta.
Not Recommended
- swagger-cli: Abandoned, no OAS 3.1 support
- IBM OpenAPI Validator: Active but opinionated IBM-specific rules add configuration overhead for no benefit
Tool Comparison Matrix
| Tool | OAS 3.1 | License | Last Release | Stars | Runtime | Category |
|---|---|---|---|---|---|---|
| Redocly CLI | Full | MIT | 2026-03-03 | ~1.4k | Node.js | Lint + validate |
| Spectral | Full | Apache 2.0 | 2025-04-22 | ~3k | Node.js | Lint |
| Vacuum | Full | MIT | 2025-12-22 | ~1k | Go binary | Lint + validate |
| oasdiff | Beta | Apache 2.0 | 2026-02-05 | ~1.1k | Go binary | Breaking changes |
Integration Pattern
Hook Script Structure
An OpenAPI validation hook would follow the existing pattern in .claude/hooks/:
#!/usr/bin/env bash
set -euo pipefail
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('file_path',''))" 2>/dev/null || echo "")
# Only run for OpenAPI spec files
case "$FILE_PATH" in
*/openapi/*.yaml|*/openapi/*.yml) ;;
*) exit 0 ;;
esac
cd "$CLAUDE_PROJECT_DIR/backend"
# Run validation
if OUTPUT=$(npx @redocly/cli@latest lint src/main/resources/openapi/api.yaml --format=stylish 2>&1); then
echo '{"hookSpecificOutput":{"hookEventName":"PostToolUse","additionalContext":"✓ OpenAPI spec validation passed."}}'
else
ESCAPED=$(echo "$OUTPUT" | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PostToolUse\",\"additionalContext\":$ESCAPED}}"
fi
Registration in .claude/settings.json
The hook would be added to the existing PostToolUse array alongside the compile and lint hooks:
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR/.claude/hooks/openapi-validate.sh\"",
"timeout": 120
}
Configuration (Optional)
A redocly.yaml in the project root or backend/ directory can customize rules:
extends:
- recommended
rules:
operation-operationId: error
tag-description: warn
no-ambiguous-paths: error
Code References
.claude/settings.json:1-32— Hook configuration (PostToolUse + Stop events).claude/hooks/backend-compile-check.sh— Java file detection pattern + compile check.claude/hooks/frontend-check.sh— TS/Vue file detection pattern + type-check + lint.claude/hooks/run-tests.sh— Stop hook with test execution and block/approve logicbackend/pom.xml:149-178— openapi-generator-maven-plugin configurationbackend/src/main/resources/openapi/api.yaml— The OpenAPI 3.1.0 spec to validate
Open Questions
- Should the validation use a pinned version (
npx @redocly/cli@1.x.x) or latest? Pinned is more reproducible; latest gets rule updates automatically. - Should a
redocly.yamlconfig be added immediately with therecommendedruleset, or start with zero-config (structural validation only) and add rules incrementally? - Is breaking change detection (oasdiff) desirable as a separate CI check, or is structural validation sufficient for now?