Building an Intent-Aware CI Scanner for Modern Engineering Teams
- Mark Kendall
- Dec 28, 2025
- 4 min read
From Intent to Enforcement
Building an Intent-Aware CI Scanner for Modern Engineering Teams
Why this article exists
Modern engineering teams are under more pressure than ever.
Application teams are no longer just writing business logic. They are expected to:
own architecture
own security
own compliance
own cloud infrastructure
own CI/CD
own operational behavior
At the same time, organizations are introducing increasingly powerful AI tooling that can generate code faster than humans can reason about it.
This creates a dangerous and very real gap:
We can produce change faster than we can verify intent.
This article documents a practical, enterprise-safe answer to that problem.
Not another agent.
Not another chatbot.
Not another auto-coding experiment.
Instead, this is about automating intent verification—the same way linters automated syntax, scanners automated security checks, and policy engines automated compliance.
The core idea (plain English)
The idea is intentionally simple:
Engineers declare intent.
Engineers write code.
The system evaluates whether the code still honors the intent.
Nothing more.
Nothing less.
The output is not code.
The output is not decisions.
The output is signals.
Where this started: the AI project structure skeleton
This journey started with a Python repository structure that looked like an “AI project” but didn’t actually run anything.
It included folders like:
config/
llm/
prompt_engineering/
utils/
examples/
notebooks/
At first glance, this confused people.
There was no executable. No main entrypoint. No working app.
And that confusion was valid.
But here’s the key realization:
That structure was never meant to be an application.
It was meant to be the internal engine of a tool.
Once you see it that way, everything changes.
Reframing the structure: tool, not application
When reframed correctly, the structure makes perfect sense:
llm/ → model adapters (GPT, Claude, etc.)
prompt_engineering/ → controlled reasoning and prompts
config/ → policies, constraints, and guardrails
utils/ → logging, limits, safety mechanisms
notebooks/ → experimentation only (never production)
This is how you build a scanner, not how you build a product.
The missing piece was never “more AI.”
The missing piece was how this structure is invoked and controlled.
The missing layer: intent as a first-class artifact
This is where Intent and TeamBrain enter the picture.
Each repository introduces a simple but powerful concept:
/intent/
These files answer questions that usually live only in people’s heads:
What is this service responsible for?
What must never change?
What is explicitly out of scope?
Once intent is written down, something important happens.
Intent becomes:
versioned
reviewable
diffable
auditable
At that point, intent is no longer philosophy.
Intent becomes data.
The leap: testing code against intent
This is the critical step.
Once intent is data, it can be evaluated.
Not manually.
Not through meetings.
Not through tribal knowledge.
But through automation.
This does not mean asking AI to “understand everything.”
It means asking bounded, explicit questions, such as:
Does this change violate a declared invariant?
Does this expand responsibility beyond stated intent?
Does this introduce coupling that intent explicitly forbids?
Does this drift from declared service boundaries?
This is the same evolution we saw with:
compilers
linters
static analyzers
security scanners
The difference is simple but profound:
The rules are semantic, not syntactic.
Analyzer vs agent: a critical distinction
This system is not an autonomous agent.
It is a CI-invoked analyzer that may use LLMs internally.
That distinction is non-negotiable.
What it
is
Deterministic entrypoint
Short-lived execution
Read-only access
Structured output
Fully pipeline-controlled
What it is
not
Self-triggering
Long-running
State-mutating
Code-writing
Deployment-controlling
Internally, the tool may use:
prompts
reasoning steps
semantic judgment
Externally, it behaves exactly like:
a linter
a scanner
a policy engine
This framing is what makes the system enterprise-safe and governance-friendly.
How it runs in CI pipelines (the practical reality)
From the pipeline’s point of view, nothing exotic happens.
A CI job runs one command:
tmf_guard --mode pr-check
That command:
Reads the repository (code + intent)
Applies fast, deterministic checks first
Packages only relevant context
Calls the LLM only when semantic judgment is needed
Emits a structured result
Example output:
{
"intent_score": 84,
"status": "WARN",
"violations": [
{
"rule": "INVARIANT-003",
"severity": "MEDIUM",
"message": "Service performs enrichment not declared in intent"
}
]
}
The pipeline then behaves exactly as it always has:
PASS → continue
WARN → comment
FAIL → block
No magic.
No autonomy.
No surprises.
Permissions and trust boundaries
One of the biggest strengths of this approach is how clean the trust boundary is.
The analyzer needs:
read access to the repository
outbound HTTPS to an LLM API
optional token to comment on merge requests
It does not need:
write access to code
Kubernetes credentials
cloud provider access
production secrets
This keeps:
security teams comfortable
auditors satisfied
architects firmly in control
Policies, governance, and cognition—unified
This approach unifies three traditionally separate concerns.
Code policies
Deterministic rules
Schema checks
Structural constraints
Code governance
Architectural intent
Responsibility boundaries
Explicit invariants
Code cognition
Semantic reasoning
“Does this still mean what we said it means?”
Human-level judgment, machine-executed
Together, these form a single CI-enforced scanner.
That unification is the real breakthrough.
Why this matters
This system:
reduces manual architectural labor
scales governance across dozens of repositories
removes dependence on tribal knowledge
makes intent executable
provides fast, actionable feedback
generates audit artifacts automatically
Most importantly:
It shifts responsibility from people remembering intent to systems enforcing it.
This is not automation for speed.
This is automation for sanity.
The framing that makes this work
When explaining this system—to leadership, security, or engineers—this sentence matters:
“We’re not using AI to write code.
We’re using AI to verify that our code still matches what we said we were building.”
That framing is the anchor.
Closing thought
The original Python structure was never wrong.
It was simply waiting for the right purpose.
Combined with:
intent folders
CI pipelines
deterministic entrypoints
bounded AI reasoning
It becomes something far more powerful than a chatbot or agent:
An intent-aware CI scanner—a TeamBrain enforcement layer.
This is the canonical process.
This is the endpoint.
And now it’s written down.

Comments