Online edition for BLOGE
0.9.8-RC1· facts verified 2026-09-15 · 中文
Chapter 27 — Contract Sensitivity: Can the Suite Reject a Wrong Answer?
Chapter promise: Turn one green loan Case into a controlled negative experiment, then distinguish a
KILLEDwitness from aSURVIVEDblind spot without confusing either result with exhaustive mutation coverage.
Learning goals
- Explain why “candidate equals expected” does not prove that the contract rejects nearby wrong answers.
- Use
verifyContractSensitivity(Path)against one governedBUSINESS_CONTRACTExpectation. - Read
KILLED,SURVIVED, report status, and source-bound evidence as separate facts. - Design one-variable witnesses that a business owner can review.
The same green Case can hide two very different contracts
The low-risk loan Case expects APPROVE, and the graph returns APPROVE. Now imagine two matchers:
- exact: actual must equal
APPROVE; - broad: actual must merely be different from
DECLINE.
Both pass today. Only the first rejects REVIEW. A positive example establishes that one point matches; sensitivity asks whether a selected wrong answer crosses the contract boundary.
Change the expected answer, not the running system
The sidecar names the exact governed Expectation and replaces only its expected value:
schemaVersion: 1
sensitivityId: loan-decision-witnesses
scenario: loan-approval.scenario.yaml
mutants:
- mutantId: low-risk-must-not-review
requirementRef: LOAN-DECISION-001
caseId: auto-approve
expectationId: decision-approved
kind: EXPECTATION_VALUE_REPLACED
replacementExpected: REVIEW
VerificationContractSensitivityReport result =
verifier.verifyContractSensitivity(sensitivityPath);
BLOGE executes the baseline Case once. It then projects the real observation onto the alternate expected value. It does not patch production code, rerun a different Operator, or invent a business rule. That isolation matters: if both the implementation and Oracle changed, a failure would no longer identify contract sensitivity.
Observe the transition, not just the final badge
The RC1 test ContractSensitivityTest.passesOnlyWhenEveryRequiredWitnessIsKilled uses an exact EQUALS Expectation. The graph still observes APPROVE; replacing expected with REVIEW is rejected, so the witness is KILLED, the report is PASS, and reasonCodes is empty.
The companion test sealsASurvivingWitnessAsARecheckableSensitivityFailure starts from a broader “not review” style contract and replaces expected with DECLINE. The same observation is still accepted. The witness becomes SURVIVED, the report becomes FAIL, and the published artifact remains independently recheckable as SOURCE_BOUND evidence.
| Observation | Witness outcome | Report | Meaning |
|---|---|---|---|
| alternate expected is rejected | KILLED | PASS only if every required witness is killed | the contract notices this selected wrong answer |
| alternate expected is still accepted | SURVIVED | FAIL | the matcher or Oracle boundary is too broad for this witness |
| plan points to a missing/unsupported target | NOT_EVALUATED | INVALID | the experiment itself is not valid |
The important asymmetry is deliberate: a surviving witness is useful failure evidence. It should not disappear because the business Case happened to be green.
Design witnesses from business mistakes
Do not enumerate random strings. Start from a mistake the business can name:
- Pick one protected decision, such as “low-risk applications must not enter manual review.”
- Keep Scenario, Policy, Fixture, graph, execution profile, and source commit fixed.
- Replace one expected value with one plausible wrong answer.
- Ask the owner whether the witness represents a real decision boundary.
- Keep the witness in version control only after that review.
For loan approval, useful witnesses include REVIEW for an auto-approve Case and APPROVE for a blacklist Case. A nonsense value may test serialization while teaching nothing about the business contract.
Lab: make one witness survive
- Run the low-risk Case and record its baseline
PASSand actualAPPROVE. - Add the
REVIEWreplacement above; verify that the exact matcher yieldsKILLED. - Change only the matcher to a broader condition that also accepts
REVIEW. - Run the same sidecar again; record
SURVIVEDandCONTRACT_MUTANT_SURVIVED:<mutantId>. - Restore the exact matcher and rerun. The witness must return to
KILLED. - Save the artifact receipt outside the run directory and ask another reader to verify it.
This is a two-run, one-variable experiment: the witness is fixed, and only contract strictness changes. That makes the result explainable.
Transfer: discount-rule sensitivity
For retail pricing, replace an expected 10% loyalty discount with 30% while
keeping the cart and implementation fixed. An exact amount matcher should kill
that witness; a matcher that checks only discount > 0 will let it survive.
The result measures whether the contract rejects this chosen pricing error, not
whether every promotion interaction is covered.
Chapter boundary
- Sensitivity covers only author-declared mutations; it is not mutation coverage of all rules or outputs.
- A
KILLEDwitness proves rejection of one selected wrong answer, not correctness over an input domain. - A
SURVIVEDwitness locates an ambiguity; it does not decide whether the matcher or business Oracle should change. - Source-bound publication makes the result recheckable; it does not turn the tool into the business owner.
Experiment acceptance card
- Expected and observed: One observation becomes KILLED under an exact contract and SURVIVED under a loose one.
- Failure and recovery: Loosen one expectation so the witness survives; restore the exact answer.
- Proof boundary: Proves sensitivity to a declared witness, not discovery of every blind spot.
- Exercise contract: Green case and one witness; change one expectation; deliver the transition; stop when the bad witness is KILLED.
Summary
A green example says “this answer matched.” A killed witness adds “this selected wrong answer would not have matched.” A surviving witness exposes where the contract is too permissive. Chapter 28 changes the question again: instead of one hand-picked wrong answer, it explores a bounded input domain and reduces a real failure.
Next: Chapter 28 — Bounded Property Verification and Useful Counterexamples
Coding Agent: Open the versioned task guide.