Online edition for BLOGE
0.9.8-RC1· facts verified 2026-09-15 · 中文
Chapter 25 — Policy, Fixture, and Assurance
Chapter promise: You will separate what must be verified, how external behavior is controlled, and what minimum evidence is required. Removing a protected Case, exceeding Fixture consumption, or allowing a real effect will stop at the verification boundary instead of producing a false green result.
Learning goals
- Separate the responsibilities of Scenario, Policy, Fixture, and
VerificationExecutionProfile. - Choose the next action from
FAIL,INVALID, orINCOMPLETE. - Use
verifyGoverned(Path)for Requirements andverifyFixtureFidelity(Path)for Fixture contracts. - Reproduce three one-variable failures and diagnose the earliest reason code.
Three declarations guard one execution entrance
A team can make the loan tests green by deleting manual-review, widening a Fixture until every request succeeds, or letting an undeclared effect reach the real ledger. None of those changes edits an assertion, yet each shrinks or contaminates the proof.
The orange entrance is preflight. Scenario, Policy, and Fixture must agree before the verifier creates customer bootstrap state and enters the real BLOGE parser, compiler, and engine. Rejected configuration does not execute customer code first and append a warning later.
Scenario declares a Case input, action, and Expectations: what this run will observe.
Policy protects required Suites, Cases, Requirements, and minimum assurance: what cannot silently disappear.
Fixture names the node call or effect port it controls, its behavior, and consumption range: how external behavior is bounded.
VerificationExecutionProfile fixes logical time, random and ID seeds, harness timeout, and persistence mode. Declared host capabilities are bound inputs, not isolation evidence.
Protect the manual-review Case first
The starter Policy protects all three decision Cases:
requiredSuites:
- suiteId: loan-approval-decisions
requiredCases: [auto-approve, auto-reject, manual-review]
minimumDepth: L2
minimumBusinessExpectations: 6
minimumReplayAssurance: CONTRACT_CONTROLLED
maximumUnverifiedEffects: 0
Run the governed entry point:
VerificationGovernedReport report = ScenarioVerifier.builder()
.bootstrap(caseContext -> loanVerificationEnvironment(caseContext))
.projectRoot(projectRoot)
.policy(projectRoot.resolve("src/test/bloge/verification-policy.yaml"))
.build()
.verifyGoverned(projectRoot.resolve(
"src/test/bloge/scenarios/loan-approval.scenario.yaml"));
requiredCases prevents a Case from disappearing. Requirement satisfaction also depends on requirementObligations and requirementBindings: only passing BUSINESS_CONTRACT Expectations contribute Requirement evidence. Merely listing a requirementRef does not satisfy it.
A Fixture is not a global mock
Use NODE_CALL to replace an Operator invocation. Use EFFECT_PORT to retain the Operator's calculation and control only its external access. The target types are not interchangeable.
schemaVersion: 1
fixtureSetId: funding-effect
rules:
- ruleId: book-once
target:
type: EFFECT_PORT
portId: ledger.book
parentNodeId: bookDisbursement
inputEquals: {applicationId: LA-FUND-1}
behavior:
type: RETURN
value: {status: booked}
consumption: {minimum: 1, maximum: 1}
Zero matches, ambiguous matches, under-consumption, over-consumption, and unbound effects fail closed. CI_SAFE is the only current profile and rejects ALLOW_REAL. Effect DELAY uses the bootstrap TimeSource; the Fixture does not wait on wall-clock time with Thread.sleep.
Keep assurance separate from fidelity
A Case can be a business PASS while Fixture fidelity remains DECLARED_SYNTHETIC. A VerificationFixtureFidelityProvider supplies contracts keyed by fixtureSetId/ruleId; the verifier checks the Schema and optional adapter observations. The provider cannot return PASS or award itself a level.
VerificationFidelityReport fidelity = verifier.verifyFixtureFidelity(scenarioPath);
The first local-provider ceiling is PROVIDER_ATTESTED_ADAPTER. ADAPTER_CONTRACT_VERIFIED additionally requires the contract source, adapter implementation and configuration, and governance identity to enter source-bound evidence. Without a provider, the lower DECLARED_SYNTHETIC level means missing fidelity evidence, not a business execution failure.
Run three one-variable attacks
Use the same manual-review Case and restore the input after every attack. Otherwise the second result cannot be attributed to one change.
| One changed fact | Earliest reliable observation | Customer code? | Recovery |
|---|---|---|---|
| Remove a Policy-protected Case | Candidate Policy weakening: POLICY_REGRESSION; missing Scenario Case: REQUIRED_CASE_MISSING | No | Restore the Case; do not weaken the baseline. |
Invoke a Fixture rule beyond maximum | The next resolution fails closed as CONTROL_RULE_OVER_CONSUMED; verifier diagnostics expose FIXTURE_OVER_CONSUMED:<set>/<rule> | Execution has started; the extra real call is not allowed through | Fix the call count or the approved bound. |
Change behavior to ALLOW_REAL under CI_SAFE | REAL_EXECUTION_FORBIDDEN while compiling the Fixture | No real port call | Keep a test double, or move the test to an explicitly isolated profile when such a profile exists. |
The timing distinction matters. Case presence and ALLOW_REAL are knowable before execution. Over-consumption is not: the verifier must observe the extra invocation before it can reject it. Calling all three “preflight checks” would hide where the safety actually lives.
The focused RC1 run on 2026-09-14 at commit cc38fbe5 covered PolicyContinuityValidatorTest (11), FixtureBehaviorCompilerTest (2), and VerificationExecutionProfileTest (2): 15 tests passed. BehaviorActionTest added 7 execution-control tests, including a two-response sequence whose third invocation raises CONTROL_RULE_OVER_CONSUMED. The source adapter in ScenarioVerifier.controlReasons translates the completion diagnostic to FIXTURE_OVER_CONSUMED:<ruleReference>.
Let status choose the next action
FAIL — the business answer is wrong. The contract was valid and execution
completed, but a business or temporal Expectation did not match. Inspect the
implementation, input, or approved answer before changing Policy.
INVALID — the verification declaration is wrong. Scenario, Policy,
Fixture, DSL, or capability composition is invalid. Repair the declaration;
retrying the same input is not useful.
INCOMPLETE — the run did not finish. Timeout, resource, adapter, or
evidence capture stopped the run. Preserve diagnostics, repair the environment,
then retry from a clean run.
Start with the earliest reason code:
REQUIRED_CASE_MISSING: a Policy-required Case disappeared.FIXTURE_UNDER_CONSUMED:<fixtureSetId>/<ruleId>: the minimum consumption was not reached.FIXTURE_OVER_CONSUMED:<fixtureSetId>/<ruleId>: calls exceededmaximum.REAL_EXECUTION_FORBIDDEN:CI_SAFEencounteredALLOW_REAL.FIXTURE_TARGET_ZERO_MATCH/FIXTURE_TARGET_AMBIGUOUS: the target did not bind exactly one controlled call site.
Lab: create three failures, one at a time
Restore each factor before starting the next round.
- Remove
manual-reviewfromloan-approval.scenario.yaml. The governed run should stop before customer bootstrap withINVALIDandREQUIRED_CASE_MISSING. Restore the Case; do not lower Policy. - Set
maximum: 1on a Fixture rule that is consumed twice. ExpectFIXTURE_OVER_CONSUMED:<fixtureSetId>/<ruleId>. Inspect the attempt and target instead of making consumption unbounded. - Change an effect behavior to
ALLOW_REAL. UnderCI_SAFE, expectINVALIDandREAL_EXECUTION_FORBIDDEN. Stop. A required real adapter belongs in a separately isolated and explicitly declared boundary.
Record the change, status, first reason code, whether bootstrap ran, and the recovery action. A terminal screenshot alone is not reviewable evidence.
Transfer: high-value refund control
For an e-commerce refund flow, let Policy protect the high-value manual-review
Case, let a Fixture control only payment.refund, and let CI_SAFE forbid the
real payment adapter. Delete the Case, consume the Fixture twice, and allow the
real port in three separate runs. The useful output is where each run stops,
not whether the console eventually turns green.
Chapter boundary
BUSINESS_CONTRACTcovers business outcomes;STRUCTURAL_CONTRACTcovers node, invocation, Fixture-consumption, and compensation facts.INVOCATIONandEFFECT_INPUTare observation selectors, not production-adapter certification.- Fixture success does not prove production HTTP, database, or message-protocol compatibility.
VerificationEffectResolverFingerprintProviderbinds resolver configuration; naturally changing runtime state does not belong in that configuration digest.
Experiment acceptance card
- Expected and observed: Policy, Fixture, and Assurance constrain action, simulation, and evidence strength separately.
- Failure and recovery: Remove a case, over-consume, or switch to ALLOW_REAL; repair from the reason.
- Proof boundary: Proves a controlled entry, not production equivalence of a simulator.
- Exercise contract: Manual-review case; attack one control at a time; deliver three receipts; stop when each reason has one action.
Summary
Policy prevents silent scope reduction, Fixture controls external behavior, and the execution profile fixes reproducibility inputs. Interpret a business PASS or FAIL only after policy/profile preflight succeeds and Fixture-consumption checks complete. The next chapter applies the same discipline to suspension, signals, resume, and logical time.
Next: Chapter 26 — Durable and Temporal Verification
Coding Agent: Open the versioned task guide.