<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Varun Jose — AI Engineering & Architecture]]></title><description><![CDATA[Varun Jose — AI Engineering & Architecture]]></description><link>https://varun-jose.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6aa0ea98d54a6f0b32d01cb5/b3286401-f14e-477f-9e5d-0e9fb387a36e.png</url><title>Varun Jose — AI Engineering &amp; Architecture</title><link>https://varun-jose.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 18 Sep 2026 19:46:57 GMT</lastBuildDate><atom:link href="https://varun-jose.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How Do You Fairly Compare AI Coding Agents?]]></title><description><![CDATA[Building AgentCompat CI for repeatable repository experiments with deterministic contract checks
I started AgentCompat CI after running the same kind of coding task through different AI agents.
At fir]]></description><link>https://varun-jose.hashnode.dev/how-do-you-fairly-compare-ai-coding-agents</link><guid isPermaLink="true">https://varun-jose.hashnode.dev/how-do-you-fairly-compare-ai-coding-agents</guid><category><![CDATA[ai agents]]></category><category><![CDATA[AI Engineering]]></category><category><![CDATA[software architecture]]></category><category><![CDATA[Devops]]></category><category><![CDATA[vibe coding]]></category><dc:creator><![CDATA[Varun Jose]]></dc:creator><pubDate>Wed, 09 Sep 2026 21:09:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6aa0ea98d54a6f0b32d01cb5/2e56aec9-8df9-4d1a-bcad-340f250e898c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Building AgentCompat CI for repeatable repository experiments with deterministic contract checks</h2>
<p>I started AgentCompat CI after running the same kind of coding task through different AI agents.</p>
<p>At first, comparing the results seemed straightforward: give each agent the task, look at the code, run the tests, and decide which implementation looked better.</p>
<p>But the more I experimented, the less comfortable I became with that comparison.</p>
<p>Was one agent actually better, or did it simply start with a different repository state? Did both agents see the same project context? What if one modified the tests or introduced additional dependencies?</p>
<p>That led me to a more useful question:</p>
<p><strong>How do we compare coding agents in a way that is repeatable and engineering-driven rather than subjective?</strong></p>
<p>That question became AgentCompat CI.</p>
<p>AgentCompat CI is an experimental Python framework for running coding-agent CLIs against controlled repository tasks and evaluating the resulting candidate workspace using explicit engineering rules.</p>
<p>The goal is not to determine which AI model is universally “best”.</p>
<p>The question is deliberately narrower:</p>
<blockquote>
<p><strong>Given this repository, this task and these engineering rules, did this coding agent produce an acceptable workspace?</strong></p>
</blockquote>
<p>This article describes <strong>AgentCompat CI v0.1.0</strong>, based on repository revision <code>8e730ef</code>.</p>
<p>One clarification is important from the beginning: despite <strong>CI</strong> being part of the project name, the current version is primarily a CLI/framework for <strong>CI-style deterministic evaluation</strong>. Native integrations such as GitHub Actions, JUnit/SARIF reporting and richer automated benchmark pipelines remain future work.</p>
<hr />
<h1>Why comparing coding agents is harder than it looks</h1>
<p>A manual comparison mixes many variables together:</p>
<ul>
<li><p>repository state</p>
</li>
<li><p>task wording</p>
</li>
<li><p>local tools</p>
</li>
<li><p>agent configuration</p>
</li>
<li><p>approval permissions</p>
</li>
<li><p>provider authentication</p>
</li>
<li><p>model selection</p>
</li>
<li><p>project instructions</p>
</li>
<li><p>dependencies</p>
</li>
<li><p>validation rules</p>
</li>
<li><p>human judgement</p>
</li>
</ul>
<p>Suppose I ask two agents:</p>
<blockquote>
<p>Add cursor-based pagination to <code>GET /orders</code>.</p>
</blockquote>
<p>Both may produce valid-looking implementations.</p>
<p>But one might change three files while another changes twelve.</p>
<p>One may introduce a new dependency.</p>
<p>One may alter the test suite.</p>
<p>One may create additional generated artifacts.</p>
<p>One may interpret the requirement slightly differently.</p>
<p>If I simply inspect both solutions manually and decide which one I prefer, the result is difficult to reproduce.</p>
<p>AgentCompat CI attempts to control some of these variables.</p>
<p>It captures a specific repository commit, loads a declared task, creates independent repository workspaces and evaluates the candidate using explicit rules.</p>
<p>It also records execution and verification evidence so the verdict can be inspected later.</p>
<p>It does <strong>not</strong> control everything.</p>
<p>Each coding-agent CLI still brings its own model, configuration, context-discovery behaviour, permissions and tool implementation.</p>
<p>So AgentCompat CI should not be interpreted as a pure foundation-model benchmark.</p>
<p>It is evaluating <strong>coding-agent systems operating through their actual CLIs</strong>.</p>
<hr />
<h1>The core idea</h1>
<p>Conceptually, the workflow is:</p>
<pre><code class="language-text">Repository
    ↓
Task + Engineering Contract
    ↓
AgentCompat CLI
    ↓
Coding Agent
    ↓
Disposable Workspace
    ↓
Verification + Deterministic Evaluation
    ↓
PASS / FAIL + Evidence
</code></pre>
<p>The coding agent remains free to determine <strong>how</strong> it solves the development task.</p>
<p>AgentCompat defines <strong>how the result is accepted</strong>.</p>
<p>That distinction is central to the project.</p>
<hr />
<h1>Architecture</h1>
<p>AgentCompat CI is currently implemented in Python 3.12+ using libraries including Typer, Pydantic, Rich and GitPython, with asynchronous subprocess execution for coding-agent CLIs.</p>
<p>The main responsibilities are separated across several components.</p>
<table>
<thead>
<tr>
<th>Component</th>
<th>Responsibility</th>
</tr>
</thead>
<tbody><tr>
<td><code>cli.py</code></td>
<td><code>validate</code> and <code>run</code> commands, adapter selection, terminal reporting, JSON output and exit codes</td>
</tr>
<tr>
<td><code>models.py</code> / <code>contracts.py</code></td>
<td>Typed configuration, YAML loading and rule merging</td>
</tr>
<tr>
<td><code>runner.py</code></td>
<td>Task loading, execution sequencing, verification and verdict assembly</td>
</tr>
<tr>
<td><code>adapters/</code></td>
<td>Integration with Codex, Gemini and Kiro</td>
</tr>
<tr>
<td><code>workspace.py</code></td>
<td>Disposable Git workspaces, source commit capture and change collection</td>
</tr>
<tr>
<td><code>evaluators.py</code></td>
<td>Deterministic candidate checks</td>
</tr>
<tr>
<td>dependency modules</td>
<td>Dependency snapshots, policy and drift evaluation</td>
</tr>
</tbody></table>
<p>A single <code>agentcompat run</code> currently executes <strong>one baseline, one candidate and one task</strong>.</p>
<p>Although the configuration can declare multiple candidates and tasks, v0.1.0 does not automatically execute a complete benchmark matrix.</p>
<p>That is an important distinction between the current implementation and the longer-term direction of the project.</p>
<hr />
<h1>Separating the task from the acceptance criteria</h1>
<p>One design decision I find particularly useful is separating:</p>
<p><strong>What we ask the agent to do</strong></p>
<p>from</p>
<p><strong>How we determine whether the result is acceptable.</strong></p>
<p>The task contains the natural-language development request.</p>
<p>The contract contains deterministic engineering policy.</p>
<p>A simplified contract based on the project example looks like this:</p>
<pre><code class="language-yaml">version: 1

project:
  name: sample-fastapi-api

baseline:
  agent: codex

candidates:
  - gemini
  - kiro

rules:
  tests_must_pass: true
  build_must_pass: true

  forbidden_paths:
    - ".github/workflows/**"
    - "infra/production/**"

  required_paths:
    - "src/orders/**"

  changed_files:
    max: 8
    include_ignored: false

  forbidden_dependencies:
    - requests

tasks:
  - fixtures/tasks/add-pagination.yaml
</code></pre>
<p>The corresponding task can then describe the requested behaviour — for example, adding cursor-based pagination while preserving the existing API response structure.</p>
<p>Task-level rules can tighten repository-level policy.</p>
<p>For example, if the repository allows eight changed files but the selected task allows only six, AgentCompat uses the stricter limit.</p>
<p>Required and forbidden path policies also accumulate rather than allowing a task to weaken the repository-level contract.</p>
<p>This helps establish an important boundary:</p>
<blockquote>
<p><strong>Natural-language requirements become deterministic guarantees only when tests or explicit rules actually enforce them.</strong></p>
</blockquote>
<p>For example, saying <em>“do not introduce new runtime dependencies”</em> in the prompt is broader than configuring a rule that only forbids adding one specific package.</p>
<p>A contract should never be assumed to enforce more than it actually checks.</p>
<hr />
<h1>A common interface for different coding agents</h1>
<p>AgentCompat currently provides adapters for:</p>
<ul>
<li><p>Codex</p>
</li>
<li><p>Gemini</p>
</li>
<li><p>Kiro</p>
</li>
</ul>
<p>Each adapter follows a small common interface built around preparing the workspace and executing the task.</p>
<p>Conceptually:</p>
<pre><code class="language-python">prepare(workspace)

execute(task, workspace)
</code></pre>
<p>The implementation then normalises useful execution information such as:</p>
<ul>
<li><p>timestamps</p>
</li>
<li><p>process exit code</p>
</li>
<li><p>stdout</p>
</li>
<li><p>stderr</p>
</li>
<li><p>invocation details</p>
</li>
<li><p>adapter metadata</p>
</li>
</ul>
<p>The agents themselves are still invoked differently.</p>
<p>For example, the current Codex adapter uses <code>codex exec</code>, Gemini uses its headless prompt execution mode, and Kiro uses <code>kiro-cli chat</code> in non-interactive mode.</p>
<p>The adapters also use different approval and tool-trust settings, so normalising their output does not mean they are operating under identical conditions. That difference needs to be considered when interpreting the results.</p>
<hr />
<h1>Repeatable repositories, but not a hermetic sandbox</h1>
<p>Another major part of the experiment is workspace management.</p>
<p>AgentCompat requires a Git repository containing at least one commit.</p>
<p>It captures the source <code>HEAD</code> and creates independent temporary clones from that commit.</p>
<p>The clones:</p>
<ul>
<li><p>start from the captured source commit</p>
</li>
<li><p>use detached <code>HEAD</code></p>
</li>
<li><p>remove Git remotes</p>
</li>
<li><p>do not inherit uncommitted source changes</p>
</li>
<li><p>contain an AgentCompat workspace marker</p>
</li>
<li><p>are cleaned up after execution</p>
</li>
</ul>
<p>The candidate therefore does not inherit changes made by the baseline.</p>
<p>This gives both agents a much cleaner starting point than manually reusing the same working directory.</p>
<p>There is another useful implementation detail: Git changes are compared against the original captured commit.</p>
<p>If an agent creates its own Git commit, those modifications do not disappear from AgentCompat's change reporting.</p>
<p>However, these workspaces provide <strong>repository separation</strong>, not complete system isolation.</p>
<p>There is currently no VM or container execution layer.</p>
<p>Agents may still share host-level state such as:</p>
<ul>
<li><p>environment variables</p>
</li>
<li><p>installed tools</p>
</li>
<li><p>provider authentication</p>
</li>
<li><p>user configuration</p>
</li>
<li><p>caches</p>
</li>
<li><p>network access</p>
</li>
</ul>
<p>Removing Git remotes also does not mean the process has no network access.</p>
<p>So it would be inaccurate to call the current execution environment hermetic or security-isolated.</p>
<p>That is an area for future development.</p>
<hr />
<h1>Deterministic acceptance</h1>
<p>The principle behind the evaluator is straightforward:</p>
<blockquote>
<p><strong>The agent can be non-deterministic in how it solves the problem, while acceptance can remain deterministic.</strong></p>
</blockquote>
<p>That does not mean every external component magically becomes deterministic.</p>
<p>A flaky test is still flaky.</p>
<p>An unavailable service can still fail.</p>
<p>The point is that the <strong>acceptance logic itself is explicit and inspectable</strong> rather than asking another LLM whether the generated code “looks correct”.</p>
<p>Tasks can configure verification commands such as:</p>
<pre><code class="language-text">python -m pytest -q
</code></pre>
<p>AgentCompat runs these commands directly and records:</p>
<ul>
<li><p>command output</p>
</li>
<li><p>exit status</p>
</li>
<li><p>timeout state</p>
</li>
<li><p>observed success or failure</p>
</li>
</ul>
<p>The evaluator can also enforce repository policies such as:</p>
<ul>
<li><p>required paths</p>
</li>
<li><p>forbidden paths</p>
</li>
<li><p>maximum changed files</p>
</li>
<li><p>dependency rules</p>
</li>
<li><p>required tests</p>
</li>
<li><p>required build checks</p>
</li>
</ul>
<p>This creates a clearer acceptance boundary around otherwise probabilistic agent behaviour.</p>
<hr />
<h1>A subtle but important limitation: agents can modify tests</h1>
<p>Verification currently runs inside the same writable workspace that the agent modified.</p>
<p>This means the coding agent can potentially modify the tests before AgentCompat executes them.</p>
<p>For early experimentation this is acceptable, but it is not the strongest possible acceptance boundary.</p>
<p>A more robust future architecture would include an <strong>immutable external acceptance suite</strong> that the coding agent cannot modify.</p>
<p>This is one of the clearest examples of why evaluating an agent requires evaluating the harness around it as well.</p>
<hr />
<h1>File policies and generated artifacts</h1>
<p>Another interesting problem emerged around generated files.</p>
<p>An agent may create caches, package metadata or other artifacts as part of execution.</p>
<p>Should all of those files count against a changed-file limit?</p>
<p>The answer depends on what the measurement is intended to represent.</p>
<p>AgentCompat distinguishes between:</p>
<p><strong>What appeared in the workspace</strong></p>
<p>and</p>
<p><strong>What should consume the configured change budget.</strong></p>
<p>Ignored artifacts can remain visible as evidence while being excluded from the file-count budget.</p>
<p>Forbidden-path checks remain separate.</p>
<p>This prevents the reporting system from hiding potentially useful evidence simply because an artifact does not count toward one particular metric.</p>
<p>That distinction turned out to be surprisingly important when comparing stored experiment results.</p>
<hr />
<h1>Dependency changes need trustworthy observations</h1>
<p>Dependency policy is another area where I wanted the harness to rely on its own evidence rather than blindly trusting the coding agent.</p>
<p>When dependency rules are enabled, AgentCompat takes a dependency snapshot before execution and compares it with the candidate's final state.</p>
<p>The implementation supports a range of Python dependency formats and can reason about things such as:</p>
<ul>
<li><p>direct dependency additions</p>
</li>
<li><p>dependency removals</p>
</li>
<li><p>version changes</p>
</li>
<li><p>source changes</p>
</li>
<li><p>lockfile changes</p>
</li>
<li><p>required lockfile co-updates</p>
</li>
<li><p>selected forbidden dependencies</p>
</li>
</ul>
<p>The important architectural point is not the number of supported formats.</p>
<p>It is this:</p>
<blockquote>
<p><strong>Dependency policy is evaluated from observations made by the harness, not from claims supplied by the agent.</strong></p>
</blockquote>
<p>There are still boundaries.</p>
<p>A changed lockfile proves that the lockfile changed.</p>
<p>It does not prove that a resolver produced a semantically correct dependency graph.</p>
<p>Again, the evidence should not be interpreted more strongly than the check actually allows.</p>
<hr />
<h1>PASS and FAIL need context</h1>
<p>AgentCompat's final result is currently intentionally simple:</p>
<pre><code class="language-text">PASS
FAIL
</code></pre>
<p>The CLI uses these exit codes:</p>
<table>
<thead>
<tr>
<th>Exit code</th>
<th>Meaning</th>
</tr>
</thead>
<tbody><tr>
<td><code>0</code></td>
<td>Passing compatibility result</td>
</tr>
<tr>
<td><code>1</code></td>
<td>Agent execution succeeded, but a blocking candidate check failed</td>
</tr>
<tr>
<td><code>2</code></td>
<td>Configuration, agent execution or another caught run/reporting error</td>
</tr>
</tbody></table>
<p>The result also contains execution details and diagnostic evidence.</p>
<p>What the project <strong>does not yet have</strong> is a comprehensive unified result taxonomy such as:</p>
<pre><code class="language-text">CONTRACT_FAIL
AGENT_ERROR
INFRA_ERROR
TIMEOUT
NOT_RUN
</code></pre>
<p>That distinction matters.</p>
<p>Consider these two outcomes:</p>
<h3>Case A</h3>
<p>The coding agent executes successfully, changes the repository, but the resulting implementation fails the contract tests.</p>
<h3>Case B</h3>
<p>The coding agent never executes because authentication fails.</p>
<p>Those should not carry the same interpretation when studying agent capability.</p>
<p>The current reports contain enough evidence to investigate many of these cases, but richer failure classification is an important next step.</p>
<hr />
<h1>An example: the pagination experiment</h1>
<p>The repository includes a pagination task and stored Codex/Kiro result reports.</p>
<p>The sample Orders API itself exists as a <strong>maintainer-local fixture</strong> and is not tracked as part of a fresh clone of the main repository, so these checked-in results should be treated as recorded observations rather than a benchmark anyone can reproduce from the public repository without recreating the fixture.</p>
<p>The documented experiment follows the general pattern:</p>
<pre><code class="language-bash">agentcompat validate agent-contract.yaml

agentcompat run \
  --repo fixtures/repos/orders-api \
  --baseline codex \
  --candidate kiro \
  --contract agent-contract.yaml \
  --task fixtures/tasks/add-pagination.yaml \
  --json-output results.json
</code></pre>
<p>AgentCompat then:</p>
<ol>
<li><p>loads the task</p>
</li>
<li><p>merges repository and task rules</p>
</li>
<li><p>captures the source commit</p>
</li>
<li><p>creates independent baseline and candidate workspaces</p>
</li>
<li><p>executes the baseline</p>
</li>
<li><p>executes the candidate</p>
</li>
<li><p>runs configured verification</p>
</li>
<li><p>collects repository changes</p>
</li>
<li><p>evaluates candidate contract rules</p>
</li>
<li><p>produces terminal and optional JSON reporting</p>
</li>
</ol>
<p>One stored result records a passing candidate with two relevant modified files.</p>
<p>Another older report records a failure caused by the file-count policy because generated artifacts were included differently.</p>
<p>The useful lesson is <strong>not which agent won</strong>.</p>
<p>The useful lesson is that:</p>
<blockquote>
<p><strong>Measurement policy changes what the verdict means.</strong></p>
</blockquote>
<p>Results produced under different policies should not be treated as interchangeable benchmark samples.</p>
<hr />
<h1>What AgentCompat CI actually measures</h1>
<p>This distinction is important enough to state explicitly.</p>
<p>AgentCompat v0.1.0 does <strong>not</strong> currently establish semantic equivalence between the baseline implementation and the candidate implementation.</p>
<p>The baseline runs and provides execution/reporting information.</p>
<p>Candidate rules determine candidate contract compliance.</p>
<p>So a PASS means something closer to:</p>
<blockquote>
<p><strong>The candidate satisfied the configured blocking acceptance checks for this task.</strong></p>
</blockquote>
<p>It does not mean:</p>
<blockquote>
<p>The candidate produced exactly the same implementation as the baseline.</p>
</blockquote>
<p>And it certainly does not mean:</p>
<blockquote>
<p>This coding agent is universally better than another coding agent.</p>
</blockquote>
<p>That narrower interpretation makes the result much more defensible.</p>
<hr />
<h1>What building this taught me</h1>
<p>The project has already changed the way I think about coding-agent evaluation.</p>
<h2>Model capability is only one variable</h2>
<p>Observed agent performance is closer to:</p>
<pre><code class="language-text">Foundation Model
      +
Agent Harness
      +
Repository Context
      +
Tools
      +
Permissions
      +
Task
      +
Validation
      =
Observed Result
</code></pre>
<p>Changing any of those layers can influence the outcome.</p>
<hr />
<h2>Acceptance criteria need precise semantics</h2>
<p>Statements such as:</p>
<blockquote>
<p>“The build passed.”</p>
</blockquote>
<p>sound clear until we ask what <strong>build</strong> means.</p>
<p>In one task, the configured build command may only parse Python files for syntax errors.</p>
<p>That is useful evidence.</p>
<p>But it is not equivalent to validating packaging, deployment or runtime behaviour.</p>
<p>Engineering evaluation should describe exactly what was measured.</p>
<hr />
<h2>Observation and enforcement are different</h2>
<p>Sometimes information is useful to record even when it should not affect a verdict.</p>
<p>Generated caches are a good example.</p>
<p>They may be irrelevant to the changed-file budget but still valuable diagnostic evidence.</p>
<p>Keeping those concepts separate makes results easier to understand.</p>
<hr />
<h2>The harness itself needs tests</h2>
<p>A benchmark or evaluation framework is software.</p>
<p>Its conclusions are only as trustworthy as the machinery producing them.</p>
<p>AgentCompat's own test suite covers behaviours including:</p>
<ul>
<li><p>workspace handling</p>
</li>
<li><p>stricter task-rule merging</p>
</li>
<li><p>adapter execution</p>
</li>
<li><p>committed agent changes</p>
</li>
<li><p>dependency observation</p>
</li>
<li><p>metadata replacement</p>
</li>
<li><p>conditional dependency behaviour</p>
</li>
<li><p>baseline execution behaviour</p>
</li>
</ul>
<p>The evaluation framework itself needs deterministic validation just as much as the generated code does.</p>
<hr />
<h2>Reproducibility has layers</h2>
<p>Capturing a Git SHA and sharing the same task dramatically improves repeatability.</p>
<p>But stronger reproducibility would also require capturing or controlling:</p>
<ul>
<li><p>model versions</p>
</li>
<li><p>CLI versions</p>
</li>
<li><p>dependency versions</p>
</li>
<li><p>tool permissions</p>
</li>
<li><p>environment configuration</p>
</li>
<li><p>external provider state</p>
</li>
</ul>
<p>Reproducibility is not a binary property.</p>
<p>It is something we progressively improve.</p>
<hr />
<h1>Current limitations</h1>
<p>AgentCompat CI is still an experimental project.</p>
<p>The current limitations include:</p>
<ul>
<li><p>one baseline/candidate pair at a time</p>
</li>
<li><p>one selected task per run</p>
</li>
<li><p>no statistically meaningful benchmark suite yet</p>
</li>
<li><p>no semantic comparison against the baseline implementation</p>
</li>
<li><p>tests remain editable by the coding agent</p>
</li>
<li><p>repository clones are not a security sandbox</p>
</li>
<li><p>no structured model/version capture</p>
</li>
<li><p>no normalised token accounting</p>
</li>
<li><p>no populated cost metrics</p>
</li>
<li><p>Python-focused dependency analysis</p>
</li>
<li><p>no native GitHub Actions integration in the main project</p>
</li>
<li><p>no JUnit/SARIF reporting yet</p>
</li>
<li><p>no durable patch archive after workspace cleanup</p>
</li>
</ul>
<p>Being explicit about these limits is important.</p>
<p>The goal is not to make AgentCompat appear more mature than it is.</p>
<p>The goal is to build a stronger evaluation boundary incrementally.</p>
<hr />
<h1>Where I want to take it next</h1>
<p>Several extensions now seem particularly valuable.</p>
<h3>Immutable acceptance tests</h3>
<p>Move critical validation outside the agent-editable workspace.</p>
<h3>Richer failure classification</h3>
<p>Distinguish contract failures from agent, authentication, infrastructure and timeout failures.</p>
<h3>Environment capture</h3>
<p>Record agent CLI versions, model information and other reproducibility metadata.</p>
<h3>Multi-agent execution</h3>
<p>Run multiple candidates against the same task automatically.</p>
<h3>Historical regression tracking</h3>
<p>Compare how agent versions behave against a stable set of engineering contracts over time.</p>
<h3>Cost-per-successful-task metrics</h3>
<p>Once correctness is measured reliably, metrics such as tokens, execution time, retries and cost become much more useful.</p>
<h3>CI integration</h3>
<p>GitHub Actions, pull-request reporting and machine-readable formats such as JUnit or SARIF could eventually turn AgentCompat into a repeatable part of engineering workflows.</p>
<hr />
<h1>Architecture overview</h1>
<pre><code class="language-mermaid">flowchart TD

    REPO["Git Repository&lt;br/&gt;Captured Commit"] --&gt; WORKSPACE["Workspace Manager"]

    CONTRACT["Contract YAML"] --&gt; RUNNER["AgentCompat Runner"]
    TASK["Task YAML"] --&gt; RUNNER

    RUNNER --&gt; WORKSPACE

    WORKSPACE --&gt; BASELINE["Baseline Workspace"]
    WORKSPACE --&gt; CANDIDATE["Candidate Workspace"]

    RUNNER --&gt; ADAPTER["Agent Adapter"]

    ADAPTER --&gt; CODEX["Codex"]
    ADAPTER --&gt; GEMINI["Gemini"]
    ADAPTER --&gt; KIRO["Kiro"]

    CODEX --&gt; BASELINE
    GEMINI --&gt; CANDIDATE
    KIRO --&gt; CANDIDATE

    BASELINE --&gt; VERIFY1["Verification"]
    CANDIDATE --&gt; VERIFY2["Verification"]

    VERIFY2 --&gt; OBSERVE["Candidate Evidence"]

    OBSERVE --&gt; EVALUATE["Deterministic Evaluators&lt;br/&gt;Tests • Build • Paths • Files • Dependencies"]

    EVALUATE --&gt; RESULT["Compatibility Result&lt;br/&gt;PASS / FAIL + Evidence"]

    VERIFY1 --&gt; RESULT

    RESULT --&gt; OUTPUT["Terminal Report&lt;br/&gt;Optional JSON"]
</code></pre>
<hr />
<h1>Final thought</h1>
<p>The question that originally motivated this project was:</p>
<blockquote>
<p><strong>Can an AI coding agent write the code?</strong></p>
</blockquote>
<p>That is still an interesting question.</p>
<p>But as coding agents become more capable, I think the more important engineering question is becoming:</p>
<blockquote>
<p><strong>Can we build a system around coding agents that makes their work reproducible, testable and safe to accept?</strong></p>
</blockquote>
<p>AgentCompat CI is my experiment around that problem.</p>
<p>The agent is allowed to be creative in how it solves the task.</p>
<p>The engineering system around it needs to be much stricter about deciding whether the result should be accepted.</p>
<p>That boundary between <strong>probabilistic generation and deterministic validation</strong> is the part I find most interesting.</p>
<p>AgentCompat CI is open source, and I plan to continue exploring the contract format, evaluation model, agent integrations and reproducibility boundaries as the coding-agent ecosystem evolves.</p>
<p><strong>GitHub:</strong> <a href="https://github.com/varun-jose/agentcompat.ci">https://github.com/varun-jose/agentcompat.ci</a></p>
]]></content:encoded></item></channel></rss>