DEV Community

IdoGol24
IdoGol24

Posted on

Weir - deterministic unit tests for AI agents (no LLM)

Your agent's logs can say "success" while the run was quietly hijacked - untrusted content at step 2 steering a tool call at step 6 - and the industry's default answer is pointing a second LLM at the first one.

I built Weir to be the deterministic opposite: it reads the OpenTelemetry traces you already have and answers two questions:

  • How much of your agent's behavior your telemetry can actually prove
  • Whether a forbidden flow happened (shown as a witness path you can fail CI on)

Same input, byte-identical answer, no LLM in the loop, nothing leaves your machine.

Try it out:

pip install weir-scan && weir gauge --sample
Enter fullscreen mode Exit fullscreen mode

License: Apache-2.0

GitHub logo IdoGol24 / weir

Weir - unit tests for your agents

Weir - unit tests for your agents

Weir is a CI gate for AI agents.

CI PyPI License: Apache-2.0

Terminal recording: weir scan reports a verdict-grade finding with a witness path, then exits 1

It reads the OpenTelemetry traces your agent already emits and fails the build when sensitive data reaches a sink it should not reach.

Weir asks a structural question:

Did sensitive data flow through the agent to a sink it should never have reached?

Your agent already answers that question in the traces it emits. Weir reconstructs the session graph, tracks taint through it, and shows the evidence node by node.

flowchart LR
  A["traces your agent<br/>already emits"] --> B{"weir gauge"}
  B -->|"coverage too low"| C["names the exact<br/>instrumentation switch"]
  C -.->|"flip it, re-run"| B
  B -->|"coverage sufficient"| D{"weir scan"}
  D -->|"no forbidden flow"| E["exit 0"]
  D -->|"forbidden flow"| F["exit 1 + witness path<br/>n2 → n3 → n4 → n5 → n6"]
Loading

Try it in two minutes

pip install weir-scan
weir gauge your-export.jsonl   # or: weir gauge

The roadmap is completely in the open. I'd genuinely like to know where it breaks on your exports!

Top comments (10)

Collapse
 
reidmarlow profile image
Reid Marlow

For agent tests I like splitting the trace checks into invariants and witnesses. Invariants catch the boring regressions, like a tool call that should never see untrusted text. Witness paths are better for CI because they tell you exactly which span crossed the boundary. Same reason I distrust LLM judges for this layer.

Collapse
 
idogol24 profile image
IdoGol24

Agreed!
In Weir the invariant is the rule - plain data (source class, sink, propagation mode) and the witness is what makes a violation count. The span that crossed is what we all need.

In this tool I currenly have one teaching rule ships today, broader set is next (Hopefully with the help of the OSS cummunity)

Which instrumentation are you on? Curious whether weir gauge names the right capture switch for your export.

Collapse
 
idogol24 profile image
IdoGol24

Let me know what you think! how do you test your agents?

Collapse
 
anasbuilds997 profile image
anassBld

We use it specifically at the external side-effect boundary. In our setup, autonomous agents propose mutations (API writes, browser interactions, git commits) that pass through deterministic validation gates before execution.

Where Weir's static trace verification shines for us is catching parameter contamination: verifying that unvalidated text from tool observations or external web scraping didn't flow into mutation payloads without passing through explicit schema checks or human confirmation invariants.

Most eval frameworks test whether the LLM "meant" the right thing; treating execution traces as deterministic data flow lets us treat safety and correctness as code-level invariants rather than probabilistic prompt scoring.

Excited to see the community adoption pick up—definitely keep me posted as new patterns or benchmarks emerge!

Collapse
 
deanlee profile image
Dean Lee

Determinism is the right instinct here. The useful test is the witness path. If a CI failure can point to the exact untrusted-content hop that changed the later tool call, a human reviewer has something cheaper than vibes to inspect.

Collapse
 
idogol24 profile image
IdoGol24 • Edited

Thats the whole point :)
One addition: each join in the witness states its evidence tier (explicit id, span nesting, or content-mined), and a finding that crosses a content-mined join never reaches verdict grade - so the reviewer also knows how much weight each link carries before they inspect it. Curious where the gauge lands if you point it at one of your real exports 😁

Collapse
 
anasbuilds997 profile image
anassBld

The distinction between invariant verification and witness paths is spot on.

Relying on LLM-as-a-judge for trace inspection introduces the very non-determinism you're trying to eliminate in CI. If an eval passes 9 out of 10 times because of temperature or prompt variance, you don't have a test suite—you have a stochastic smoke alarm.

Separating the joins into explicit IDs vs span nesting vs content-mined is especially critical for tool-heavy pipelines. In our experience with multi-step autonomous workflows, content-mined joins are where silent regressions hide during schema migrations. Having the witness path flag the exact span that crossed the security or mutation boundary gives the engineer an immediate causal link rather than an abstract score.

Curious: how do you handle state reconciliation when an agent encounters partial tool execution failures (e.g. network timeout after write)? Does the invariant engine capture compensatory rollbacks or just mark the dangling span as a violation?

Collapse
 
idogol24 profile image
IdoGol24

Weir doesn't model execution state - there are no rollback semantics in the engine, deliberately.

It scans what the trace proves about flow. So for timeout-after-write, two cases:

  • if the write span was emitted and tainted content reached it, that's a finding - a compensating rollback can't retract a flow that already happened (you can't un-exfiltrate).
  • If the trace is truncated and the span dangles, that's an evidence problem, not a violation - Weir doesn't invent findings from missing spans;

Reduced provable coverage is what weir gauge surfaces, with the reason stated. Whether the saga compensated correctly is a different tool's job.

If you have a real export where these collide, I'd genuinely like to run it.

Collapse
 
anasbuilds997 profile image
anassBld

That framing makes complete sense and is a crucial distinction. Treating the side-effect span as a point-in-time fact (if tainted flow reached an external write, the mutation/exfiltration occurred) avoids the trap of assuming downstream compensations erase security or integrity findings.

And surfacing truncated traces as reduced provable coverage rather than synthesizing false negatives matches strict evidence discipline: missing telemetry is unknown coverage, not proof of invariant compliance.

Appreciate the clarification on Weir's design boundaries—it keeps the engine grounded in deterministic verification without conflating static trace analysis with distributed saga coordination.

Collapse
 
idogol24 profile image
IdoGol24

Sure! I am super excited that you got my point :)
Let me know if and how you use it! I am currently trying to showcase it to the comuunity!