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:
- Separate “the program completed” from “the business result is correct.”
- Express a rule as
given / when / then, withthenpointing to observable business output or structural fact. - Trace one evidence chain across Scenario, graph, output mapping, Policy, and Report.
- Cover decisions, manual review, retry, fallback, and compensation with a small set of representative Cases.
- 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:
| Observation | Prediction | Why HTTP 200 is insufficient |
|---|---|---|
| Risk decision | auto_approve | Proves the routing decision |
| Approval status | approved | Proves the approval branch produced a business result |
| Reject node | SKIPPED | Proves 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.
Five assets, five questions
An auditable chain uses five small assets with distinct responsibilities:
| Asset | Question answered | This chapter's instance |
|---|---|---|
| Business oracle | What result counts as correct? | Low-risk applications auto-approve |
| Scenario | Which input, action, and observations? | loan-approval.scenario.yaml |
| Graph | Which nodes and branches actually run? | loan-approval.bloge |
| Policy | Which Cases and evidence depth are mandatory? | verification-policy.yaml |
| Report | What 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?
The Case follows this causal chain:
FetchLoanApplicationconstructs deterministic application data fromcaseName=auto-approve.credit,fraud,income, andblacklistread the application and emit independent risk facts.AggregateRiskcombines them and emitsdecision=auto_approve.- The graph enters only
approve;rejectand manual review must not run. outputsmap node internals to stable business outputs such asriskDecisionandapprovedStatus; the verifier compares expected and actual values.
That is why the Scenario uses two kinds of assertion:
BUSINESS_OUTPUTchecks a business result such as approval status.NODE_STATUSchecks 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:
L2means graph-Scenario execution evidence, not production acceptance.PORT_GUARDEDsays effect ports were controlled at the verification boundary; emptyrealEffectPortIdsmeans no real external effect port was reached.CONTRACT_CONTROLLEDdescribes contract-controlled replay conditions, not universal production reproducibility.- Empty
reasonCodesandunverifiedOperatorRefsmean 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:
| Case | Business shape | Required result | Result that must be excluded |
|---|---|---|---|
auto-approve | Low risk | Automatic approval | Reject branch skipped |
auto-reject | High risk | Automatic rejection | Approve branch skipped |
manual-review | Boundary risk or facts needing review | Human review with final status | Automatic 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:
| Case | Real-world mapping | Key evidence |
|---|---|---|
funding-success | Fund and notify normally | fundingStatus=notified |
transient-booking-retried | Ledger service briefly fails | First attempt schedules retry; second succeeds |
booking-fallback-used | Retry exhausts and approved fallback applies | Third invocation records FALLBACK_APPLIED |
notification-failure-compensated | Funds booked, then notification fails terminally | Graph 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-approveleaves 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:
- What is
riskDecision? - Which final status appears?
- 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
- Loan decision graph
- Loan decision Scenario
- Funding resilience Scenario
- Verification Policy
- Dynamic Scenario adapter
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.