June 17, 2026 · 6 min read

When a PR contradicts the ticket: catching intent drift before it ships

A ticket says 100 requests; a later refactor sets it to 50. Both shipped, nobody reopened the ticket, and now your code and your intent disagree. Here's why this 'intent drift' is more expensive than a bug, why no single tool catches it, and how Stoney surfaces the contradiction for a human to resolve.

A ticket says "free tier gets 100 requests per day." Six months and forty PRs later, a refactor lands that sets the free-tier limit to 50. Both are real decisions made by real people. The ticket was never reopened. The PR was reviewed and merged. Nothing was wrong with either change in isolation — but now your code says one thing and the document that authorized it says another, and nobody knows which one is supposed to win.

That's intent drift: the slow divergence between what a ticket asked for and what the code actually does. It's not a bug — the code runs fine. It's a contradiction, and contradictions are invisible to every tool that only looks at one side.

Why code and tickets drift apart

Tickets and code live in different systems, on different clocks, owned by different people:

The result is a codebase where the "why" and the "what" have silently diverged — and you only find out when a customer holds you to the version you documented and your API does something else.

Why a contradiction is more expensive than a bug

A bug is a deviation from intended behavior — you fix it and move on. A contradiction is worse, because there's no agreed intended behavior to return to. When code says 50 and the ticket says 100:

  1. Support can't answer the customer. The docs, the ticket, and the running system disagree. Every escalation becomes an investigation.
  2. The fix is a decision, not a patch. Someone senior has to determine which value is correct, which means reconstructing context from a year ago.
  3. It surfaces at the worst time. Usually in an audit, a customer dispute, or an incident — never on a quiet Tuesday when it would be cheap to resolve.

Why your existing tools don't catch it

Contradiction detection requires correlating two signals that no single tool holds together:

Catching "this PR contradicts the ticket" means reading the code, the PR, and the ticket together and noticing when they disagree. That correlation is the entire point of an API rule registry.

How Stoney surfaces a contradiction

Stoney builds the rule registry by correlating your code, PRs, and Jira tickets, so each rule carries the ticket that authorized it. When a new change sets a value that disagrees with the rule on record, Stoney raises a contradiction— it shows both rules side by side, the PR check that triggered it, and a single decision: keep the existing rule and flag the change, or accept the new value and supersede the old rule. The contradiction doesn't resolve itself silently in favor of whatever merged last. A human decides, with both versions and their provenance in front of them.

This is the difference between "the last write wins" and "the right write wins." (For how synthesis ties rules to tickets, see the documentation.)

Getting started

Contradiction detection is most useful once Stoney has both signals — your code and the tickets that authorized your rules. Connecting Jira takes one OAuth click after the GitHub App is installed. The free tier is enough to install, synthesize rules, and see the first contradictions Stoney finds in your own history:

  1. Install the Stoney GitHub App on a repo.
  2. Connect Jira so rules carry the ticket that authorized them.
  3. Review the registry — and the contradictions Stoney already found between your code and your tickets.

See pricing or start free. To understand the registry the whole thing is built on, start with what an API rule registry is.