Polychro — Comparison¶
How Polychro relates to the adjacent tools teams reach for when they want to lint and govern their specifications. For a feature inventory see Features; for the bigger picture see Spec-Driven Integration.
A 2019 problem vs. a 2026 problem¶
Most of the "lint your specs" space solves a 2019 problem: how do we govern OpenAPI files in CI? Polychro is built for the 2026 problem: how do we validate any spec, in-process, at the speed an AI agent generates it? That reframing is the whole point.
Five shifts that moved the problem¶
The incumbents aren't worse linters — they were built for a job that has changed underneath them. Five shifts explain the gap:
- The author changed — an AI agent now writes specs far faster than a human can review them, so the linter's job moves from end-of-pipeline gate to inner-loop guardrail.
- The loop changed — a guardrail an agent calls inside a single turn has to return in well under a second; a multi-second subprocess can't participate.
- The surface changed — the specs that matter are no longer just OpenAPI:
capabilities, MCP manifests,
AGENTS.md,SKILL.md, CRDs, and arbitrary YAML all drive runtime behavior now. - The failure mode changed — "it parses" no longer means "it works"; the bugs that bite are semantic and cross-object (port conflicts, dangling references, unreachable steps, secret exposure), which schema alone misses.
- The distribution changed — agents are wired with MCP, so a linter that isn't callable as an MCP tool never reaches the loop that needs it.
The side-by-side below is really a scorecard against those five shifts.
Why in-loop beats at-the-gate¶
A CI check runs after the agent has moved on — by the time it fails, the context is gone and the fix is expensive. An in-loop guardrail catches the same bug in the same turn, while the correction is still cheap and the agent can self-correct before anything reaches a human or a merge. As agents generate more specs, that difference compounds: validation that runs at agent speed keeps pace with generation, while a merge-time gate becomes the bottleneck.
The neighbours fall into three segments, each operating at a different layer:
- Meta-linters / orchestrators — Super-Linter, MegaLinter. Large Docker images that bundle dozens of third-party linters and run them in CI. They delegate spec linting to a rule engine.
- Spectral-family rule engines — Spectral (Node), Vacuum (Go), Redocly Lint (TypeScript). Single-purpose linters for OpenAPI / AsyncAPI rulesets.
- Embeddable, polyglot, agent-era spec engines — Polychro. A composable pipeline (well-formedness → schema → ruleset → format-aware) that runs as a native binary, a JVM library, an MCP server, or a GitHub Action.
Polychro replaces the rule-engine layer and absorbs the spec-validation slice of the meta-linters — collapsing what is today three or four tools, two or three config files, and a Docker dependency into one binary, one config, one diagnostic format, sub-second. Because it speaks the Spectral ruleset format natively, existing rule investment carries over unchanged.
Side-by-side¶
| Dimension | Super-Linter | MegaLinter | Spectral | Vacuum | Polychro |
|---|---|---|---|---|---|
| Category | Meta-linter | Meta-linter | Rule engine | Rule engine | Spec engine |
| Primary language | Bash (wraps tools) | Python | TypeScript / Node | Go | Java (+ GraalVM native) |
| Distribution | Docker ~2 GB | Docker 0.8–2 GB | npm + Docker | Single binary | Binary + JVM + npm + PyPI + Go module |
| Cold start | 10–60 s | 10–60 s | 2–5 s | <100 ms | <100 ms |
| In-process embedding | ❌ | ❌ | JS only | Go only | Java + Go + Node + Python SDKs |
| MCP server mode | ❌ | ❌ | ❌ | ❌ | ✅ polychro serve |
| Well-formedness layer | partial (yamllint) | partial (yamllint) | ❌ | ❌ | ✅ dedicated module |
| JSON Schema for YAML | ❌ | via v8r | ❌ | partial | ✅ Draft 2020-12 native |
| Spectral-format rulesets | via Spectral CLI | via Spectral CLI | ✅ native | ✅ native | ✅ native engine |
| Markdown structural rules | style only | style only | ❌ | ❌ | ✅ anchors, links, frontmatter |
| HTML rules | htmlhint | htmlhint | ❌ | ❌ | ✅ document / fragment / email / embedded-ui |
| Custom rule functions | n/a | n/a | JS | JS + Go | Java SPI + JS + Python + Groovy |
Interoperate, don't contest¶
Polychro doesn't try to win every lane — it interoperates with the ecosystem:
- it speaks the Spectral ruleset format, so existing
given/thenrules run unchanged, - it emits SARIF, so its findings drop straight into CI and code-scanning dashboards, and
- it runs as a GitHub Action, so it slots into the same workflows the meta-linters already orchestrate.
The migration story is "keep your rulesets, swap the engine."
When another tool is the better pick¶
Scoping the wedge honestly:
- Reach for a meta-linter (Super-Linter, MegaLinter) when you want a one-line "lint everything in the repo" sweep across 20+ languages, and the spec-validation slice is a minor part of the job.
- Reach for Vacuum when you lint only OpenAPI, host only Go, and want best-in-class OpenAPI polish (dashboard, auto-fix) — Polychro offers no advantage there.
- Stay on Spectral when you have deep Stoplight/Studio investment and are happy with the status quo.
Polychro is the right call when you need to validate non-OpenAPI specs (capabilities, MCP manifests, CRDs, instruction files), embed validation in-process inside a JVM app, or wire an MCP-callable guardrail into an AI agent loop — and want one tool, one config for well-formedness, schema, rulesets, and Markdown/HTML at once.