Skip to main content

Online edition for BLOGE 0.9.8-RC1 · facts verified 2026-09-15 · 中文

Chapter 24 — Your First Loan Business Verification

Promise: You will turn one business-owner-approved loan decision into an executable Scenario, trace every Expectation through the real graph, and read the verification evidence produced by BLOGE 0.9.8-RC1. You will also know where verification must stop when the business answer is missing.

Learning goals

By the end of this chapter, you can:

  1. Separate “the program completed” from “the business result is correct.”
  2. Express a rule as given / when / then, with then pointing to observable business output or structural fact.
  3. Trace one evidence chain across Scenario, graph, output mapping, Policy, and Report.
  4. Cover decisions, manual review, retry, fallback, and compensation with a small set of representative Cases.
  5. Stop automation when the business oracle is missing instead of letting engineering invent policy.

This chapter adds one variable

Earlier chapters mostly asked, “Can the graph run as designed?” This chapter adds one question: Is the business answer produced by that run correct?

Those are different verdicts. Every node may complete without an exception while a customer who requires manual review is automatically approved. The runtime says execution succeeded; the policy owner says the decision is wrong.

Business verification is therefore not a synonym for more unit tests. It connects an approved answer, a real graph path, and reviewable evidence.

Predict first: which path should a low-risk application take?

The loan policy owner approves one representative example: application LA-VERIFY-1 is low risk and should be automatically approved. Before reading the test, predict the observable facts:

ObservationPredictionWhy HTTP 200 is insufficient
Risk decisionauto_approveProves the routing decision
Approval statusapprovedProves the approval branch produced a business result
Reject nodeSKIPPEDProves the mutually exclusive branch did not run

The third fact catches a structural defect in which approve and reject both execute even if one final field still reads approved.

Figure 24-1: a business story becomes a repeatable verification Scenario

Five assets, five questions

An auditable chain uses five small assets with distinct responsibilities:

AssetQuestion answeredThis chapter's instance
Business oracleWhat result counts as correct?Low-risk applications auto-approve
ScenarioWhich input, action, and observations?loan-approval.scenario.yaml
GraphWhich nodes and branches actually run?loan-approval.bloge
PolicyWhich Cases and evidence depth are mandatory?verification-policy.yaml
ReportWhat did this particular run observe?target/bloge-verification/

The business owner supplies the answer, engineering translates it into executable observations, and BLOGE runs the graph and preserves the evidence.

Translate one rule into Given / When / Then

The real Scenario declares ownership, graph source, and Case identity before its three-part contract. This excerpt keeps only auto-approve:

- caseId: auto-approve
title: Low-risk application is auto-approved
requirementRefs: [LOAN-DECISION-001]
oracle:
type: APPROVED_EXAMPLE
sourceRef: starter-policy:auto-approve
owner: loan-policy-owner
given:
context:
applicationId: LA-VERIFY-1
caseName: auto-approve
when:
action: EXECUTE
then:
outcome: SUCCESS
expectations:
- actual: {kind: BUSINESS_OUTPUT, outputId: riskDecision}
matcher: EQUALS
expected: auto_approve
- actual: {kind: BUSINESS_OUTPUT, outputId: approvedStatus}
matcher: EQUALS
expected: approved
- actual: {kind: NODE_STATUS, nodeId: reject}
matcher: EQUALS
expected: SKIPPED

Do not memorize YAML first. Ask three business questions:

  • given: Which real-world application shape does this Case describe?
  • when: What should the system do? Here it executes the real graph.
  • then: Which observations are enough for the owner to say the answer is right?

oracle identifies the source, type, and owner of the expected answer. APPROVED_EXAMPLE means an owner-approved representative case, not a policy inferred by BLOGE.

Trace the graph: where do Expectations get facts?

Figure 24-2: the auto-approve evidence path from input to Report

The Case follows this causal chain:

  1. FetchLoanApplication constructs deterministic application data from caseName=auto-approve.
  2. credit, fraud, income, and blacklist read the application and emit independent risk facts.
  3. AggregateRisk combines them and emits decision=auto_approve.
  4. The graph enters only approve; reject and manual review must not run.
  5. outputs map node internals to stable business outputs such as riskDecision and approvedStatus; the verifier compares expected and actual values.

That is why the Scenario uses two kinds of assertion:

  • BUSINESS_OUTPUT checks a business result such as approval status.
  • NODE_STATUS checks execution structure such as the reject branch being skipped.

Stable business outputs can survive internal graph refactoring. Reach into structure only when mutual exclusion, retry, fallback, or compensation is itself part of the contract.

Run real verification

From the book root:

cd submodule/bloge
mvn -pl bloge-starter-loan-approval -am \
-Dtest='LoanApprovalApplicationTest,LoanApprovalBusinessScenarioTest,LoanApprovalOperatorFlowTest' \
-Dsurefire.failIfNoSpecifiedTests=false test

On 2026-09-14, BLOGE commit cc38fbe5, version 0.9.8-RC1, produced:

LoanApprovalApplicationTest 1 passed
LoanApprovalOperatorFlowTest 3 passed
LoanApprovalBusinessScenarioTest 7 passed
Total 11 passed, 0 failed

Those seven dynamic Scenarios are three decision rules and four funding-resilience rules, not seven method-return tests. The report summary adds:

Suite: loan-approval-decisions
Status: PASS
Cases: 3/3 passed
Executed nodes: 10/10
auto-approve depth=L2 effectSafety=PORT_GUARDED replay=CONTRACT_CONTROLLED
Requirement LOAN-DECISION-001 satisfied=true cases=1/1

The machine-readable result for auto-approve is:

{
"caseId": "auto-approve",
"effectSafety": "PORT_GUARDED",
"realEffectPortIds": [],
"reasonCodes": [],
"replayAssurance": "CONTRACT_CONTROLLED",
"status": "PASS",
"unverifiedOperatorRefs": [],
"verificationDepth": "L2"
}

Read the labels as bounded facts, not slogans:

  • L2 means graph-Scenario execution evidence, not production acceptance.
  • PORT_GUARDED says effect ports were controlled at the verification boundary; empty realEffectPortIds means no real external effect port was reached.
  • CONTRACT_CONTROLLED describes contract-controlled replay conditions, not universal production reproducibility.
  • Empty reasonCodes and unverifiedOperatorRefs mean no additional degradation reason or unverified Operator reference was recorded.

Expand one Case into a decision coverage map

One auto-approval Case supports the declared assertions for one policy region. This decision Suite samples three mutually exclusive regions:

CaseBusiness shapeRequired resultResult that must be excluded
auto-approveLow riskAutomatic approvalReject branch skipped
auto-rejectHigh riskAutomatic rejectionApprove branch skipped
manual-reviewBoundary risk or facts needing reviewHuman review with final statusAutomatic approve skipped

This is not case-count theatre. Removing one Case leaves one policy region without an approved answer.

Funding adds a harder question: what should remain after failure?

The funding Suite progresses from choosing a branch to validating the business world after a failure:

CaseReal-world mappingKey evidence
funding-successFund and notify normallyfundingStatus=notified
transient-booking-retriedLedger service briefly failsFirst attempt schedules retry; second succeeds
booking-fallback-usedRetry exhausts and approved fallback appliesThird invocation records FALLBACK_APPLIED
notification-failure-compensatedFunds booked, then notification fails terminallyGraph fails; booking reverses; funds release

The last Case has a deliberately non-successful graph outcome. The correct business behavior is to fail explicitly and compensate reversible effects. A Scenario with then.outcome: FAILURE can itself pass verification.

Stop when the business answer is missing

Suppose a product manager says, “Manual review can be more lenient for high-net-worth customers.” This is not an executable oracle. It does not define:

  • how high-net-worth is determined;
  • which risk dimensions can move, and by how much;
  • whether the final answer is approve, reject, or human discretion;
  • who owns that standard.

Do not guess an expected value or infer correctness from the current code. Mark the Scenario as awaiting clarification, record the missing rule and owner, and stop the release-gate decision.

Stop rule: Without a traceable business oracle, you may verify what the system did, but not claim the business result is correct.

Do not guess when the Maven entry point fails

The RC1 Maven verification entry point requires a usable test classpath. If it cannot build one, it reports:

TEST_CLASSPATH_UNAVAILABLE: cannot execute BLOGE verification

That is an environment/toolchain failure, not a failed business Case. Repair dependency or reactor scope, then rerun. Never report PASS because an old report directory exists when verification did not execute.

What this chapter proves—and does not prove

The evidence supports these claims:

  • Three loan decisions and four funding Scenarios pass at the pinned commit.
  • auto-approve leaves machine-readable business outputs, branch exclusion, and Requirement mapping.
  • No real external effect port was reached; replay conditions were contract-controlled.

It does not prove:

  • every possible input combination is correct;
  • the policy itself is wise or legally compliant;
  • production databases, brokers, and external services are accepted;
  • a future version will produce the same result.

Business verification does not stamp a system “correct forever.” It makes one conclusion answerable: who defined the answer, which input ran, which path executed, what was observed, and which version made it true.

Transfer the method to another industry

For an ecommerce refund:

  • given: order delivered three days ago, unopened product, amount 199;
  • when: execute the refund-eligibility graph;
  • then: refundDecision=auto_approve, refund branch runs, human-review branch is skipped;
  • oracle: a refund-policy example approved by the after-sales owner.

Vocabulary and answers change; the chain remains: business oracle → Scenario → graph → observations → Report.

Lab: change one variable

Copy auto-approve and change only caseName to manual-review. Predict three facts before comparing the repository's official Case:

  1. What is riskDecision?
  2. Which final status appears?
  3. Which automatic branch must be SKIPPED?

If your answer conflicts with the owner's approved example, do not edit expected merely to get green. Determine whether implementation is wrong, the example is stale, or policy changed.

Experiment acceptance card

  • Expected and observed: The low-risk loan satisfies Given/When/Then and reports 3/3 passed.
  • Failure and recovery: Remove the golden answer or fail the plugin; restore approved facts or the build, and stop on missing facts.
  • Proof boundary: Proves a fixed case and graph contract, not complete policy or signed release.
  • Exercise contract: Auto-approve case; change one field; deliver path, expectation, and report; stop when attributable without guessing.

Exact fact entry points

The next chapter, Chapter 25 — Policy, Fixture, and Assurance, asks whether a passing Suite was executed under the intended action, dependency, and assurance boundaries.

Coding Agent: Open the versioned task guide.