NeverGraph

The Negative Specification Compiler

mercury
demo/mercury
discover→compile→prove
Latent rules recovered
5
by IBM Bob, from evidence
Repository
mercury
demo/mercury
Selected rule
NEVER-005
high
Search
UNREACHABLE
6 states
Minimum witness
—
no live counterexample
Executable proof
NOT RUN
no proof run

NEGATIVE SPECIFICATION PRESERVED

NEVER-005UNREACHABLE

Unreachable in bounded behavioral exploration — depth ≤ 10, 6 states explored

A refunded order must never be shipped

Context-aware behavior graph

6 states · 5 transitions · forbidden when state = SHIPPED ∧ refundedAt = true

no forbidden state
counterexample path forbidden state✓ fact that arms the rule✓ other lifecycle fact

Minimum counterexample

NO COUNTEREXAMPLE

The bounded search explored 6 states without reaching a state that satisfies the forbidden condition.

Transition table

The behavior extracted from the repository as it currently ships

5 transitions
  • tr-001cancelOrderPAID → CANCELLEDsrc/services/order-service.ts:64
  • tr-002cancelOrderREFUNDED → CANCELLEDsrc/services/order-service.ts:64
  • tr-003payOrderCREATED → PAIDsrc/services/order-service.ts:26
  • tr-004refundOrderPAID → REFUNDEDsrc/services/order-service.ts:39
  • tr-005shipOrderPAID → SHIPPEDsrc/services/order-service.ts:77

No transition constrains refundedAt — the rule holds here because no path re-enters a shippable state after a refund.

Context-aware states

1 lifecycle status splits into multiple graph states by fact context

6 states / 5 statuses
statuscancelledAtpaidAtrefundedAtshippedAtverdict
CANCELLED✓✓✓—allowed
↳ CANCELLED✓✓——allowed
CREATED————allowed
PAID—✓——allowed
REFUNDED—✓✓—allowed
SHIPPED—✓—✓allowed

Graph nodes are (status, facts) tuples. Rows sharing a status are distinct states — identical lifecycle status, different history. Collapsing them to the status string alone is exactly what hides this class of violation.