跳到正文
DEV Community· Seyed Alireza Alhosseini·· 4 小時前AI 評分48

AI 程式碼審查員如何記住尚未發生的漏洞:Counterfactual Wiki 提案

What If Your AI Code Reviewer Remembered Bugs That Haven’t Happened Yet!

AI 導讀

Counterfactual Wiki 提議讓 AI 程式碼審查員找出程式碼中的假設,在隔離環境中實驗並重現可能的故障,再把證據與回歸測試一併儲存。日後審查相關改動時,審查員可重新執行實驗,檢查是否重現已記錄的故障。這是面向 Greptile 的建議產品方向,並非現有功能的描述。

正文

Your tests are green.

Your AI reviewer approves the pull request.

The change ships.

Three hours later, a customer gets charged twice.

The bug wasn’t hidden in a complicated algorithm. It lived in an assumption nobody wrote down:

“This operation must happen before that one.”

What if your AI code reviewer could discover that assumption, deliberately break it in a sandbox, and remember the resulting failure—before a customer ever experienced it?

That’s the idea behind the Counterfactual Wiki.

Not a record of what went wrong.

A memory of what could go wrong, backed by executable evidence.

The missing layer between documentation and testing

Documentation describes how a system is supposed to work.

Tests check selected behaviors.

Incident reports explain how the system actually failed.

But there is a gap between those three:

Where do we store plausible failures that we have reproduced experimentally, but that have never happened in production?

A document can describe them, but the description can drift.

A test can catch them, but the reason behind the test can disappear.

An incident report usually arrives too late to prevent the first incident.

The proposal is to connect all three:

Build a codebase knowledge system that discovers assumptions, challenges them in isolated experiments, and stores the resulting evidence alongside executable checks.

For a tool like Greptile, this would be an extension of the living-wiki idea discussed earlier—not simply more context for a reviewer, but context the reviewer can actively test.

To be clear: this is a proposed product direction, not a claim about an existing Greptile feature.

Introducing the Counterfactual Wiki

A counterfactual asks:

“What would happen if something were different?”

For code review, that becomes:

“What small, plausible change would violate an important property of this system?”

The workflow would look like this:

Read the code and its history
             ↓
Identify a candidate assumption
             ↓
Create a controlled change in a sandbox
             ↓
Try to reproduce a meaningful failure
             ↓
Store the evidence and a regression check
             ↓
Use that memory when reviewing future changes

The important word is evidence.

An agent saying “this might be unsafe” is a hypothesis.

An agent producing a minimal failing scenario gives a developer something concrete to inspect.

The wiki should preserve that distinction.

A concrete example: the harmless payment optimization

Imagine a pull request with this description:

Reduce payment latency by recording the request identifier after the payment completes.

The change looks small:

# Before
reserve_request(request_id)
charge_customer(payment)
mark_completed(request_id)
# After
charge_customer(payment)
record_request(request_id)

A conventional review might discuss error handling or naming.

Our proposed reviewer would ask a different question:

Is reserving the request identifier before charging part of the duplicate-prevention mechanism?

Then it would investigate.

In an isolated environment, using a simulated payment provider, it could:

  1. Submit two concurrent requests with the same identifier.
  2. Pause both executions immediately before the charge.
  3. Release them together.
  4. Observe whether both reach the simulated charging operation.
  5. Compare the original implementation with the proposed change.

If the experiment reproduces duplicate charging, the review comment could look like this:

This change appears to break duplicate-request protection.

In a controlled concurrency test, two requests with the same identifier both reached the charge operation before either recorded the identifier.

The original implementation blocked the second request in this scenario.

Attached: the execution trace and a proposed regression test.

That is a different conversation from:

“Please double-check concurrency.”

It is also narrower than claiming the agent has proved the entire payment system correct. It has demonstrated one specific failure under stated conditions.

What goes into the wiki?

Not a wall of AI-generated prose.

Each discovery becomes a structured Failure Card.

title: Duplicate charging under concurrent retries

status: reproduced_in_sandbox

candidate_invariant:
  A repeated request must not create a second charge.

relevant_components:
  - request reservation
  - payment execution
  - retry handling

trigger:
  Two concurrent requests share the same request identifier.

experimental_change:
  Move request recording after payment execution.

observed_result:
  Both requests reach the simulated charge operation.

artifacts:
  - minimal reproducer
  - execution trace
  - proposed regression test

scope:
  Controlled test environment with a simulated payment provider.

limitations:
  Does not establish behavior for every deployment configuration.

The exact schema is less important than the separation between:

  • What the agent suspects.
  • What the experiment demonstrates.
  • What remains unknown.

A simulated failure must never quietly become a “historical incident” in the system’s memory.

The interesting part: remembering hypothetical incidents

Now imagine another pull request six weeks later.

Different author.

Different file.

Different optimization.

But it touches the same duplicate-prevention boundary.

The reviewer retrieves the Failure Card and asks:

Does this change reopen the failure mode we reproduced before?

It can rerun the relevant experiment rather than generate a fresh warning from scratch.

That creates a feedback loop:

Assumption → Experiment → Failure → Memory → Targeted review

The organization accumulates two distinct kinds of knowledge:

Observed history

“This failed in production. Here is what happened.”

Experimental history

“This failed in a controlled simulation. Here are the conditions and evidence.”

Both are useful.

They should never be confused.

Isn’t this just mutation testing?

There is an obvious resemblance.

The proposal deliberately introduces changes and checks whether a failure becomes visible.

But the intended unit of memory is not merely a changed expression or a surviving mutation.

It is a meaningful system assumption, connected to:

  • The code that depends on it.
  • The experiment that challenged it.
  • The behavior that broke.
  • The check that can detect a recurrence.
  • The future changes that should trigger another review.

The concept could incorporate mutation testing, property-based testing, fault injection, or concurrency testing. It does not need to replace them.

The proposed product layer is the connection between those experiments, a codebase knowledge system, and the pull-request workflow.

The wiki becomes an index of executable reasoning—not a substitute for the underlying testing techniques.

Why generating more tests is not enough

An agent could generate hundreds of tests and still miss the assumption that matters.

For this product, the objective should not be:

“How many tests did we create?”

It should be:

“Which important failure can we now detect that we could not detect before?”

That changes how work gets prioritized.

A useful experiment needs a clear chain:

Important property
        ↓
Plausible way to violate it
        ↓
Observable consequence
        ↓
Repeatable detection

Without that chain, the system risks becoming an expensive machine for producing test-shaped text.

Start with one boundary, not the entire codebase

I would not launch this as:

“An autonomous agent that discovers every hidden assumption in your software.”

That promise is too broad to evaluate honestly.

I would start with one narrow problem:

Tenant isolation in a multi-tenant application.

The initial system would examine changes affecting:

  • Tenant-scoped queries.
  • Authorization checks.
  • Cache keys.
  • Background jobs that access tenant data.

It would use synthetic tenants and synthetic records, then attempt specific cross-tenant access scenarios in an isolated environment.

An illustrative discovery might be:

Removing the tenant identifier from this cache key allows a value written for tenant A to be returned to tenant B in the attached test.

Small scope.

Concrete consequence.

Repeatable evidence.

That is a more credible starting point than universal autonomous review.

The hard part is deciding what “wrong” means

Making a system behave differently is easy.

Proving that the new behavior violates an intended requirement is harder.

An agent might infer:

“This list must always be sorted.”

But perhaps ordering is irrelevant.

It might assume:

“This operation must be synchronous.”

But perhaps asynchronous execution is intentional.

The product therefore needs an assumption lifecycle:

Candidate assumption
        ↓
Supporting code or documentation
        ↓
Experimental result
        ↓
Developer confirmation or rejection
        ↓
Maintained knowledge

Developer feedback should refine the memory, not merely dismiss a comment.

“This is expected behavior” is valuable information.

“This property matters only for enterprise accounts” is valuable information.

“This was true before the migration” is valuable information.

A wiki that cannot revise its assumptions will eventually become a confident archive of obsolete beliefs.

Safety has to be part of the architecture

A system designed to break things must have strict boundaries.

For the proposed version:

  • No production credentials.
  • No real customer data.
  • No live charges or external side effects.
  • Restricted network access.
  • Disposable execution environments.
  • Explicit compute and time budgets.
  • Human review before adopting generated fixes or changing requirements.

Experiments should be reproducible and inspectable.

If an agent cannot explain what it changed, what it ran, and what it observed, its warning should not be treated as a confirmed finding.

What would success look like?

Not more comments.

Not a larger wiki.

Not a spectacular demo where an agent discovers a bug deliberately planted for it.

I would evaluate the prototype using:

Metric What it would tell us
Confirmed findings per reviewed change Whether experiments discover relevant defects
False-positive rate Whether developers can trust the output
Reproduction reliability Whether findings survive reruns
Cost per confirmed finding Whether the workflow is economically useful
Review latency Whether experimentation fits the development process
Reuse of existing Failure Cards Whether accumulated memory helps with later changes

The key experiment would compare this approach with an ordinary review workflow on the same set of changes.

Does the additional machinery find enough meaningful failures to justify its cost and delay?

That is a question to measure—not a benefit to assume.

The product idea in one sentence

Give an AI reviewer a memory of failures it has experimentally reproduced, then let it use that memory to challenge future changes.

A living wiki helps an agent understand what a system does.

A Counterfactual Wiki would help it investigate what the system must not do.

The ambition is not to predict every incident.

It is to make selected failure modes concrete, testable, and reusable before they become somebody else’s bad day.

Because the most useful thing an AI reviewer could say might not be:

“This code looks correct.”

It might be:

“I tried to break this assumption. Here is exactly what happened.”

created by https://almodarresieh.github.io/

來源:DEV Community · dev.to