---
type: "article"
title: "Linters are where API governance becomes real"
summary: "Why we left Spectral for Vacuum at Apideck, and what OpenLint means for your ruleset"
newsletter: "The Weekly Interface"
newsletter_handle: "the-weekly-interface"
newsletter_url: "https://usecommune.com/n/the-weekly-interface"
author: "Samir Amzani (@samz)"
published: "2026-10-07T13:22:34.444Z"
canonical_url: "https://usecommune.com/n/the-weekly-interface/a/2026-09-29-linters-where-api-governance-becomes-real"
markdown_url: "https://usecommune.com/n/the-weekly-interface/a/2026-09-29-linters-where-api-governance-becomes-real.md"
chat_url: "https://usecommune.com/n/the-weekly-interface/a/2026-09-29-linters-where-api-governance-becomes-real/chat"
body_source: "native"
likes: 1
replies: 2
body_words: 2239
---

# Linters are where API governance becomes real

![](https://fmxorstnlyoqpqdftivs.supabase.co/storage/v1/object/public/article-images/ce4dc54b-7510-4b7c-8a4f-2f24438a73bb/bbf2a173-1952-4ee6-92e3-c8468f834aa1/1791325101224-scdzanzt.png)

# Linters are where API governance becomes real

Every company I have worked with had API guidelines, and almost nobody read them past the first month. At Adidas the guidelines stayed the same; what changed was the day they started running in the pipeline.

The guidelines lived on a wiki page, sometimes in a nicely designed PDF, once on a whole site with a table of contents. Everyone agreed with them. The APIs kept drifting anyway. Kin Lane counted the same thing from the other side: across [260 design reviews he ran, about 15 teams had read the guidelines](https://apievangelist.com/2026/09/19/big-city-storytelling-openlint/).

At Adidas we published the [API guidelines in the open](https://github.com/adidas/api-guidelines), and next to them a Spectral ruleset that encoded the parts a machine could check. From then on the style guide was a CI step. It went red when a team shipped a contract with inconsistent naming, a missing error schema or an endpoint nobody had bothered to describe. Reviewers got to argue about design, because the build had already complained about the camelCase.

API governance only becomes real when your rules run in CI, and the asset worth owning is the ruleset, not the linter that runs it.

***

## Why a linter is the cheapest lever you have

Three things make this a CTO problem once more than a handful of teams build APIs.

Your estate is polyglot whether you like it or not. One team ships Java, another Go, a third has a Node service nobody wants to touch. You can't enforce consistency in that much code, and you can't put a human architect on every pull request. The one artifact every team produces in the same format is the API description, usually OpenAPI. Lint that, and you govern every team whatever language sits behind it.

Review is expensive. Every hour a senior engineer spends asking for plural nouns, a 4xx response or a parameter description is an hour off the design questions that matter. A ruleset takes that mechanical half of API review off the table for good. It also removes the awkward conversation. Nobody argues with the build the way they argue with a colleague.

The third one is new. Coding assistants now write API contracts at volume, and they are plausible far more often than they are right. An assistant will invent a naming convention used nowhere else in your company, skip the security scheme, and hand you an OpenAPI document that validates perfectly while breaking every guideline you have. More contracts land in your repos each week, and fewer of them were read by someone who knows your standards. A deterministic check in CI is the one gate that grows with that volume.

***

## A ruleset is a product, in five layers

Most companies that say they lint their APIs run the default ruleset that ships with the tool. That is spellcheck. Kin Lane went and measured it: of [1,005 public GitHub repositories running Spectral in CI](https://apievangelist.com/2026/07/08/most-teams-just-turned-spectral-on-and-stopped), 63% use the default ruleset and nothing else. 13% set `continue-on-error`, so a failing lint never blocks anything.

A ruleset that earns its place works in layers, and each one costs more effort and pays back more:

![](https://fmxorstnlyoqpqdftivs.supabase.co/storage/v1/object/public/article-images/ce4dc54b-7510-4b7c-8a4f-2f24438a73bb/bbf2a173-1952-4ee6-92e3-c8468f834aa1/1791328534677-0vxeaz6m.png)

1. Validity. Is this a well-formed OpenAPI document? Every tool does this out of the box.
2. Naming and structure. Path casing, plural resources, consistent parameter names, versioning in the right place, one shape for pagination. Most day-to-day review noise lives here, and this layer pays for itself in the first month.
3. Security. Every operation has a security scheme, nothing goes over plain HTTP, no sensitive data in query strings. You don't have to write these. Stoplight's [OWASP ruleset](https://github.com/stoplightio/spectral-owasp-ruleset) targets the OWASP API Security Top 10 2023, API Commons maintains a [version with 22 checks](https://github.com/api-commons/spectral-owasp-ruleset) covering all ten categories, and Vacuum ships one built in.
4. Documentation. Descriptions on every operation and parameter, examples on every schema, tags that mean something. Boring to write. It is also the difference between an API that gets adopted and one that gets a Slack message asking how it works.
5. Business rules. Every money field uses the company Money schema. Every list endpoint supports the standard filter syntax. Every event carries the tenant identifier. These need custom functions, they are yours alone, and they are the rules that protect your actual architecture.

If you want proof that a ruleset can carry real policy, look at the Netherlands. The government's [REST API Design Rules](https://gitdocumentatie.logius.nl/publicatie/api/adr/2.1.0/) are mandatory for public bodies under a "comply or explain" regime, and they [ship as Spectral rulesets](https://github.com/developer-overheid-nl/adr-rulesets). The linter is named right there in the normative text.

For a quick audit of your own setup, ask which layer your ruleset stops at. In my experience most stop at two. Nobody reaches five without treating the ruleset as a product, with an owner, tests and a changelog.

***

## Own the ruleset, rent the runtime

For years the tool was Spectral and nobody got fired for it. The decision that matters now is the ruleset format, because the format outlives whatever runs it.

Spectral is still the reference. It shipped five releases in 2026, from 6.15.1 in April to [6.16.3 in August](https://www.npmjs.com/package/@stoplight/spectral-cli), and Spectral's maintainers merged OpenAPI 3.2 support on 17 September. The community side is another picture. According to [Kin's count](https://apievangelist.com/2026/07/29/i-am-forking-spectral/), maintainers closed 157 issues in 2021, 12 in 2025 and 10 so far this year. There are 241 open issues, and the oldest open community pull request has waited five years. Then on 30 June a 29-line pull request called "chore: added scarf telemetry to cli" made the linter [phone home on install](https://apievangelist.com/2026/07/02/if-youre-using-spectral-it-is-now-gathering-data-opt-out/). You can switch it off with `scarfSettings.enabled: false`.

My read on the four options, as of September 2026:

| Tool | What it is | Pick it when | Watch out for |
| --- | --- | --- | --- |
| Spectral | The reference implementation. Most published rulesets target it. | You run it, your custom functions are JavaScript, and it works. | A JavaScript toolchain in CI, telemetry since June, a stalled issue tracker. |
| Vacuum | Go, single binary, MIT. Spectral ruleset compatible. OpenAPI 2 to 3.2, AsyncAPI 3, JSON Schema. Language server, HTML report, MCP server. | You want speed, no Node in the pipeline and a short dependency list. Large monorepos of specs. | Smaller community. JavaScript custom functions use a "very similar" design to Spectral's, so check the signatures before you migrate. |
| Redocly CLI | Part of the Redocly platform. Strong built-in rules and good docs. | You already publish docs with Redocly and want one toolchain. | Its own format. Coming from Spectral means a [migration guide](https://redocly.com/docs/cli/guides/migrate-from-spectral) and rewritten rules. |
| Speakeasy CLI | A [linter built on its own Go OpenAPI library](https://www.speakeasy.com/blog/why-we-built-our-own-openapi-linter), around SDK generation. | SDK generation is your main workflow and lint is a means to it. | Its own `lint.yaml` and TypeScript rules. The linter is there to serve the generator. |

Write your rules in the Spectral-compatible YAML format, keep them in their own repository with tests, and treat the tool that runs them as replaceable. Vacuum runs them today. OpenLint is being designed to run them tomorrow. Write your rules in a vendor's native format instead and you have signed up for that vendor's roadmap, whether you meant to or not.

***

## What leaving Spectral looked like at Apideck

I love Spectral. It has saved me more review hours than any other tool in the API space. We still moved off it at Apideck, and the reason had nothing to do with rules.

It was the dependency tree. Spectral pulls in a large graph of JavaScript packages, and every few weeks one of them showed up in a vulnerability report. None of them were about linting. All of them needed a human to look, decide, bump and rerun the pipeline. That is a lot of maintenance for a tool whose whole job is to say yes or no in CI. Add the telemetry, and the case for staying got thin.

Vacuum is one Go binary. We dropped it into the pipeline and it read the rulesets we already had. The migration took few hours mostly spent checking the handful of custom functions. Our governance didn't change. The cost of maintaining the thing that enforces it went to almost zero.

What I took from it:

- Keep the rules, swap the runtime.
- Check your custom functions first, they are the only part that doesn't move for free.
- Do it before the next vulnerability report lands.

***

## The case against: green-check theatre

The strongest objection to all of this comes from the same data I just used. If 63% of pipelines lint on factory settings and 13% never block, most of what passes for linting is a green tick that makes everyone feel governed. In Kin's census, [2 pipelines out of roughly a thousand](https://daily.dev/posts/most-teams-just-turned-spectral-on-and-stopped-there-zu733zfh1) scored 6 out of 8 on his maturity rubric.

Kin takes it further. He calls governance [a stack](https://apievangelist.com/2026/07/14/the-open-api-governance-toolchain/): a machine rule enforces a written policy, a piece of guidance explains it, and it protects a consumer experience. The linter is the only part you can see from outside. In his version of what governing APIs at scale looks like, [75% is people work](https://www.linkedin.com/posts/kinlane_most-api-governance-advice-is-aspirational-activity-7488678315159908352-02yN).

He is right, and it's worse than the census shows. You can pass a lint run today that touched almost nothing in your document, and you would never know.

My answer is to treat the ruleset as software: an owner, a good and a bad example per rule as tests, a changelog, and a build that blocks. A wiki page with nobody reading it can't fail a build. The people forking Spectral put coverage on their roadmap, which tells you they treat the ruleset the same way.

***

## OpenLint makes the format a real spec

Kin Lane [announced the fork](https://apievangelist.com/2026/07/29/i-am-forking-spectral/) on 29 July, starting from Spectral 6.16.2. The core idea is to pull the ruleset format out of the tool. Today it is "described by five internal draft-07 meta-schemas coupled to that linter's runtime", in the words of the [spec repository](https://github.com/api-commons/spotlight-spec). The fork turns it into one normative JSON Schema with its own versioning and a conformance suite any linter can be tested against.

Phil Sturgeon and Jakub Rożek, who built Spectral at Stoplight, are in, along with Dave Shanley of Vacuum and Frank Kilcommins. Mike Kistler is too. His [OpenAPI 3.2 pull request](https://github.com/stoplightio/spectral/pull/2917) to Spectral sat for six months with an approving review, was closed on 16 September, and the maintainers merged their own version built on it the next day. Kin says most of the working group is European, including two national governments.

The name came from a [community vote](https://github.com/api-commons/spotlight-spec/issues/39) that ended in a tie: OpenLint at +6, Spectical at +6. A trademark check settled it. Kin's line: ["The name is the first compliance artifact you ship."](https://apievangelist.com/2026/09/19/big-city-storytelling-openlint/) [Someone in the comments](https://www.linkedin.com/posts/kinlane_name-the-spectral-fork-issue-39-api-commons-activity-7503809671837700096-Lyvh) asked why nobody had proposed Sporky McSporkface. Fair question.

I watched the [recording](https://youtu.be/0Mj6PoCLb-I) of the first office hours on 23 September. The [agenda](https://github.com/openlint/community/issues/1) reads like the list enterprises have been asking Spectral for: modular rulesets, federation so a platform team owns the core and product teams extend it, ratings, autofix, overlays, and industry rulesets (FHIR and PSD2 came up on the call). The group split coverage in two: how much of the ruleset your tests exercise, and how much of the document your rules reached. Kin wants one ruleset format that every linter runs, so nobody has to migrate. Vacuum could become the Go implementation of the same standard.

The [meeting summary](https://openlint.org/meetings/office-hours/2026-09-23/) puts the home at Open Source Europe, for "sovereignty reasons", with funding through Open Collective and Spectral's Apache-2.0 license carried forward. The code starts as a fresh repository with Spectral's full history rather than a GitHub fork, so fixes can be cherry-picked in both directions. Removing telemetry and supply chain health are on the list, which is the polite version of why we left. AI use is minimal and agreed per pull request, and not used for writing issues. Phil's line: paste your prompt, not the result.

Nothing is installable yet. The first four discussions are aliases, multi-format support, cleaning out what they call Stoplightisms, and rules testing. Don't wait for it, but keep your rules compatible with it.

***

## What I would do this quarter

If I walked into a company as CTO tomorrow and the APIs were a mess, this is the order:

- Put a linter in CI this week, even with the default ruleset, and make it block. No `continue-on-error`. Use Vacuum unless you have a reason not to.
- Write your own rules in the Spectral-compatible format, in their own repository, with an owner, tests and a changelog. Reaching layer three by December is still more governance than most companies have.
- Run the ruleset in the editor, on the pull request, and on the assistant's output before a human looks at it. The earlier it fails, the cheaper the fix.
- Watch OpenLint. If federation and coverage ship, a portable ruleset gets them the same week.

Guidelines tell people what good looks like. Linters check it when nobody is looking, and next year more of your contracts will be written by something that doesn't read wiki pages.

Reply and tell me which of the five layers your ruleset stops at.

***

## Discussion (2 replies)

Numbering shows the reply tree: `2.1` is a reply to `2`. Message text is reproduced verbatim as posted.

### 1. Kin Lane (@kinlane) - 2026-10-07T13:32:56.828Z

Great post. Thanks so much for the reference of my work. I look forward to what is possible with OpenLint.

### 2. Samir Amzani (@samz) - 2026-10-07T13:38:16.936Z

> Quoting Kin Lane (@kinlane): Great post. Thanks so much for the reference of my work. I look forward to what is possible with OpenLint.

Thanks Kin, and thanks for putting real numbers on what many of us only suspected, looking forward to OpenLint bright future
