Files
fete/.specify/memory/research/openapi-validation-pipeline.md
nitrix 6aeb4b8bca Migrate project artifacts to spec-kit format
- 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>
2026-03-06 20:19:41 +01:00

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
research
openapi
validation
hooks
backpressure
linting
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:

  1. Reads JSON from stdin containing tool_input.file_path
  2. Pattern-matches the file path to decide if it should run
  3. Executes validation (compile, lint, type-check, test)
  4. Returns JSON with either success message or failure details
  5. On failure: outputs hookSpecificOutput with 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-plugin v7.20.0 generates Spring interfaces from api.yaml (pom.xml:149-178)
  • Frontend: openapi-typescript v7.13.0 generates TypeScript types; openapi-fetch v0.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.

  • 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 logic
  • backend/pom.xml:149-178 — openapi-generator-maven-plugin configuration
  • backend/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.yaml config be added immediately with the recommended ruleset, 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?