Your policy engine governs your pipeline. Ours governs the change
Most delivery platforms have had policy-as-code for years — Harness shipped OPA-backed Policy as Code in 2022, before we existed. But those engines were designed to govern the platform's own entities: pipeline configs, feature flags, infrastructure definitions. None of them was built to evaluate the content of a change an AI agent just proposed. That is a different object, and it needs the gate in a different place: between the agent and the pull request.
Here is the whole argument in one sentence: a policy engine can only protect you from the things it was pointed at.
Point it at pipeline configurations and it will catch a bad pipeline configuration. Point it at the content of a change an agent just wrote, before that change becomes a pull request, and it catches something else entirely.
This post is about the second one — what the sequence actually looks like, and why the position of one step in it is the only part that matters.
The flow
Before a human is involved
Verify the bundle
An init container pulls the policy bundle as a signed OCI artifact and checks its signature. If verification fails, the runtime never starts.
cosign verify
Read the rules
The crew reads your repository, your environment profile, and the index of every rule currently in force — before writing anything.
rule_index
Emit an artifact
The DevOps Engineer produces the workflow, chart, and Application your stack needs. At this point it is a candidate, proposed to nobody.
ci.yaml · Chart.yaml
The policy gate
opa eval data.proposal.denyThree layers are evaluated together. Each may only tighten the one above it.
Constitution
ours, non-waivable
Specialist packs
SOC 2 today
Your overlay
yours, tightens only
Denied
Returns an object carrying the rule_id that objected — so the agent knows exactly what to fix.
Back to step 3. No pull request is created.
Passes
Every rule in force was satisfied, and the change carries the list of which ones.
Crosses the line below.
Nothing crosses this line unevaluated
What a human sees
The pull request opens
The body cites the rules the change satisfies, so a reviewer starts from what was already checked rather than from scratch.
A named human merges
The mechanical questions are answered, so their attention goes to judgement. No configuration flag skips this step.
The argument is the position of step 4, and the arrow that goes backwards. A change that violates policy never becomes a pull request someone has to argue about — it goes back to the agent with the reason attached. By the time a person is involved, the only questions left are the ones a person is actually better at.
Why step 3 sits where it does
Almost every governance story in this market puts the check somewhere else, and the position is not a detail.
After the merge is where scanners live. The finding arrives once a human has already decided the change was fine, so acting on it costs a revert, a conversation, and someone's afternoon. Findings get deferred — not through negligence, but through the ordinary economics of interrupting work that looks finished.
In the reviewer's head is where "we require approval" puts it. That works until the reviewer is reading their fortieth agent-authored diff of the week at five on a Friday, and it was never a control in the first place — it was a hope with a checkbox.
Between the agent and the pull request is the only position where the finding is free. Nobody has committed to anything. There is no decision to reverse and no awkwardness in reversing it. The same rule, evaluated at the same strictness, changes from an argument into a fact about the change.
That is why the gate runs before the PR exists rather than as a check on it.
Credit where it is due
Here is the part a competitive post usually leaves out.
Policy-as-code in software delivery is not our idea, and we are not the first to ship it. Harness announced Policy as Code, powered by OPA in May 2022 — years before TruStacks existed. It is a real product, it is Rego, and it works. If you want a policy engine governing your delivery platform, they have had one for a long time and we are not going to pretend otherwise.
So the interesting question is not who got there first. It is what the engine was pointed at.
What the engines evaluate
Read Harness's own documentation and the scope is consistent and clearly stated. Their OPA governs Harness entities: pipeline configurations, feature flags, and — in Infrastructure as Code Management — the Workspace, the Terraform Plan, and the Terraform State.
Those are the right objects for what that engine was built to do in 2022, when the thing producing pipeline configurations was a person. Governing the platform's own entities is exactly what a delivery platform should govern.
An agent's output is a different object. It is a diff. A Dockerfile that happens to install a package. A workflow file that just acquired an image-push step. A Helm chart with an ingress nobody asked for. Evaluating that requires rules that read the proposed content, and an input shape built around a proposal:
deny contains msg if {
some cluster in input.proposal.target_clusters
cluster.tier == "prod"
some f in input.proposal.files
startswith(f.path, ".github/workflows/")
_has_image_push(f.content)
not _has_prod_environment(f.content)
msg := {
"rule_id": "acme.requires_prod_approval_gate",
"message": sprintf("%s pushes images for a prod deploy with no environment gate", [f.path]),
}
}
Note the return value. A denial is an object carrying a rule_id, not a
string. That is what puts a citation on the pull request, so the agent knows
precisely what to fix and a reviewer sees which rule objected rather than a
bare complaint. It is also what makes the decision traceable a year later,
which is the entire ask from an auditor.
This is a design consequence, not a feature gap
It would be easy — and wrong — to write this as "they are behind." They are not. Their engine does its job well.
The difference is what each system was designed around, and that is sticky in a way feature lists are not. A policy engine built to govern a platform's internal entities has an input model shaped like those entities. Pointing it at the content of an arbitrary proposed change is not a configuration change; it is a different object model, a different rule library, and a different place in the sequence.
Meanwhile the honest scoreboard on the thing everyone argues about: both of us require a human to approve. Harness documents that agent-generated pull requests require human approval with no auto-merge. We agree with them. Anyone selling you "we keep the human in the loop, they don't" is describing a market that no longer exists.
The two differences that actually survive
Strip out everything both products do and two things are left.
Your architects author the deepest layer. Our constitution is the foundation; your overlay sits underneath it and can only ratchet stricter. It may say "an image scanner must be present, and it must be FIPS-validated." It may not say "an image scanner must be present, except for internal services." A linter proves that at compile time, before the bundle is signed — so the attempt to loosen a rule is a build failure with a name on the commit, not a quiet conversation six months later. The constitution itself is non-waivable, including by us: there is no support ticket that turns a rule off for your tenant, because the capability does not exist.
The artifact is yours and it is portable. The bundle is a signed file in your repository under a licence you can read. You can check out the exact rules that were in force on the day of any given merge. And if you leave us, your policy leaves with you — which is a sentence a platform vendor structurally cannot say, because their controls are configuration inside the platform you would be leaving.
On who thought of what, and when
We are a young company, so there is a temptation to claim we invented something. We are not going to do that, for the same reason we publish a facts page with dates on it: a claim you cannot check is worth nothing, and a claim that turns out to be false costs more than it ever earned.
What we will offer instead is provenance. Every design decision behind this gate was written down as a dated architecture decision record before it was built — the policy bundle layout, the per-agent rule scoping, the OPA execution model, the open-core boundary. We have published the dates and the reasoning on our decisions page.
The honest limit on that: the decision records themselves live in a repository that is not open to the public yet, so today you have our summary of them rather than the documents. We would rather say that than imply you can go read something you cannot. When the repository opens, the entries link straight through.
Agents propose. Policy decides. Humans approve.
Claims about Harness are drawn from their own public material: the Policy as Code announcement (May 2022) and the OPA policies documentation. Both are recorded with a verification date in our comparisons registry. If we have described their product inaccurately, tell us and we will correct it.
- policy as code
- AI delivery governance
- OPA
- Rego