I Got Tired of Playing Detective After Every AI Pull Request
Agents, CI, and reviewers never agreed on one boring question: what is this change allowed to touch, and what must stay true? EngineeringSpec 0.1 RC is a fail-closed CI gate that answers it — and refuses to guess.
By Majilesh
I started as a software engineer. Then I led teams. These days I spend more time as a solution / technical architect — still close enough to the code that bad PRs keep me honest.
Somewhere in the last year, a familiar pattern got worse.
You ask an agent (or a tired human) to fix a small bug. It does that. It also "helpfully" refactors an unrelated utility, tweaks a shared config, and touches a module everyone treats as read-only. CI is green. Review is skimmed. Two weeks later you're doing archaeology at 2am.
The root cause usually isn't malice. It's misalignment.
Agents, CI, and reviewers don't share the same explicit answer to a boring question:
What is this change allowed to touch — and what must stay true?
Chat threads, AGENTS.md prose, and "please be careful" prompts don't enforce that. Nothing re-derives the real diff against an approved boundary.
So I built something narrow on purpose.
What EngineeringSpec is
EngineeringSpec is an open, agent-neutral draft format for engineering change contracts.
One Markdown document (plus canonical JSON for machines) that says:
- Why we're changing something (issue, product ID, local intent)
- Which surfaces are in scope (
src/billing/**, modify — not the whole monorepo) - What must / must not hold
- What proof we intend to attach (tests, schema checks, review)
- Rollout / evidence notes when you need them
That's the contract.
The part that makes it more than a fancy README is the gate.
engineeringspec gate is a fail-closed CI check. It compares the actual git diff to the declared targets and change policies. If the PR wanders outside that fence, it fails. By default the contract is loaded from the base revision, so a branch can't quietly rewrite its own authorization.
Validation never executes the commands listed in the document. Specs are untrusted input. That was non-negotiable.
What it is not
I'm going to be blunt, because overselling this doesn't help anyone.
- It is not a planner.
- It is not an agent runtime.
- It is not a test runner or a policy engine.
- It does not prove your API is backward compatible just because you labelled a path
interface_only. - It does not replace OpenAPI, ADRs, CODEOWNERS, OpenSpec, ProductSpec, or branch protection.
Those tools answer different questions. EngineeringSpec answers a smaller one well:
Did this change stay inside the surfaces an approved contract allowed?
If OpenSpec (or your design doc) plans the behaviour change, EngineeringSpec constrains the implementation surface and records what evidence you owe. Architecture intent stays architectural; this is the engineering guardrail between intent and a merge.
Why I think this is a product now (and still an RC)
For a while EngineeringSpec was "a format with a validator." Useful, but easy to ignore.
What's in the 0.1 RC today is closer to something you can actually run at work:
- Spec + schema + conformance suite
- CLI:
validate,normalize,inspect,coverage,gate,receipts - GitHub Action you can pin and make a required check
- Deny-overrides for
read_only/observe - Multi-spec routing for a directory of contracts
- Agent-facing
check/context/explain, plus anadoptscaffold and a portable skill - A deliberate posture: fail closed, pin SHAs, don't pretend coverage means tests ran
That's a core product: change authorization + traceability around agent (and human) diffs.
It is still a release candidate. The format is draft. Independent second implementations are thin. Evidence ingestion is early. I haven't proven, at population scale, that agents produce better outcomes — only that the enforcement mechanism is real and dogfooded.
I'm fine with that honesty. I'd rather ship a sharp fence than a fuzzy "AI engineering platform."
Who this is for
- Teams already using coding agents on brownfield repos
- Platform / CI people who are tired of scope creep landing as "LGTM"
- Architects who can draw the boundary but can't yet make CI enforce it
- Anyone who has said "we have AGENTS.md" and watched an agent ignore it
If your pain is "the agent can't write a design," look at planning tools. If your pain is "the agent wrote fine code in the wrong rooms of the house," try this.
Try it in thirty minutes
Pick one risky PR shape you've already seen go wrong. Don't boil the ocean.
npx @engineeringspec/cli@next init --template feature --id ES-my-change
# edit targets until they're uncomfortably narrow
npx @engineeringspec/cli@next validate ENGINEERING_SPEC.md
npx @engineeringspec/cli@next gate ENGINEERING_SPEC.md --base origin/main --strict
Wire the GitHub Action with a full commit SHA, protect the spec path with CODEOWNERS, and make the gate required for that path. There's a production-gate.md recipe in the repo docs for exactly this setup.
For agents mid-task, the habit that matters is simple: run check / gate before claiming done — not after CI fails.
The architect's version of the same idea
In EA/SA terms: we already model systems, dependencies, and standards. What we rarely have is a merge-time control that says "this change is authorized against those surfaces."
Today the contract is authored (or scaffolded) by humans. Tomorrow it might be derived from architecture models, OpenAPI, or dependency graphs. That's interesting — and secondary.
First prove the guardrail. Then automate the authoring.
What I want from you
Not applause. Critique and scars.
- Try one contract on one real PR
- Tell me where the format is too heavy, too vague, or wrong
- Open an issue if the gate fails closed in a stupid way — or fails open in a dangerous one
Repo · Site · CLI: npx @engineeringspec/cli@next
I'm building this because I've lived both sides of the fence — shipping code and owning architecture — and I'm done treating "please only touch X" as a vibe.
Make the authorized surface explicit. Then make CI check it.