NOULI

Examples

Personal loan approval

In this recorded run, the model records the corrected income correctly but does not carry it into the affordability review. The graph preserves that result. Steps 8 and 9 explain the mismatch and the calculation a reviewer should check.

The problem

A loan officer is reviewing a request for a 6000 USD personal loan. The bank also offers a smaller 3000 USD alternative. A good repayment record is only one part of the review: either offer must leave enough money after living expenses, existing debts, and the new installment. During the review, corrected income verification arrives.

The OCC Installment Lending handbook describes reviewing repayment capacity after obligations and living expenses. The applicant, loan quotes, and thresholds here are fictional. They demonstrate selected review steps, not a complete underwriting or compliance process.

What we will do

We will keep verified cash flow, repayment history, and product policy in three separate histories. We will blend cash flow with policy to assess affordability, blend repayment history with policy to assess account performance, then combine both reviews into a recommendation. After income changes, we will create a new affordability review and recommendation while keeping the earlier results available.

Before you start

Configure a provider and model, then run the commands in order in the same shell. Nouli reads credentials from your shell or the .env in your current directory. Each decision calls your configured provider and may incur charges.

The outputs below were captured with typesafe/jev-1.14.0. They are a recorded run, not guaranteed results. Probabilities, session IDs, and model answers may differ when you run the commands.

Set a session prefix for this walkthrough. Change it before repeating the example so the new sessions have unique names:

example=loan
show the steps as

Open the first session with nouli open cashflow, then type each step's lines at the prompt. A question sends the turn.

01Record verified household cash flow

Start with the verified income and existing expenses. This session has no product policy yet, so its question asks only about money available before a new loan payment.

$ nouli open cashflow
new session "cashflow" · /help for commands

cashflow › Fictional application L-101, initial verification at 09:00: verified recurring net income is 5000 USD per month. Essential living expenses are 3000 USD and payments on existing debts are 600 USD. These expenses exclude any proposed new loan. There are no other obligations. All figures are documented for this sample.
cashflow › ?cashflow: What monthly amount remains before a new loan payment? [1400 USD, 2000 USD, Request missing cash-flow records]
  turn 1 · 1 fact · 1 question
  cashflow    ▶ 1400 USD                         ████████████████████ 1.00
                2000 USD                                              0.00
                Request missing cash-flow recor…                      0.00
nouli --format text new "$example-cashflow" \
  'Fictional application L-101, initial verification at 09:00: verified recurring
net income is 5000 USD per month. Essential living expenses are 3000 USD and
payments on existing debts are 600 USD. These expenses exclude any proposed new
loan. There are no other obligations. All figures are documented for this
sample.' \
  -q 'cashflow: What monthly amount remains before a new loan payment? [1400 USD,
    2000 USD,
    Request missing cash-flow records]'

Output

  turn 1 · 1 fact · 1 question
  cashflow    ▶ 1400 USD                         ████████████████████ 1.00
                2000 USD                                              0.00
                Request missing cash-flow recor…                      0.00
  typesafe/jev-1.14.0 · session 01a1878e-1bfa-74c1-a042-ac9efeade77f · turn 01a1878e-1bfc-73ad-a6c6-10f9ab64157a

The initial monthly remainder is 5000 - 3000 - 600 = 1400 USD. This is a cash-flow fact for the later affordability review, not approval of a loan.

02Review repayment history

Record repayment performance separately. We use a score with three ordered levels so the later review can retain both the answer and its scale.

cashflow › /new history
  new session "history"
history › Fictional application L-101: the verified credit record covers 48 scheduled monthly payments. Every payment was on time. There are no defaults or delinquent balances, and the record is complete for this review.
history › ?history: How strong is the documented repayment performance? <Adverse payment history, Mixed payment history, Consistently timely payments>
  turn 1 · 1 fact · 1 question
  history       expected 2.00 of 2   ▁▁█
                Adverse payment history 0.00 · Mixed payment history 0.00 · Consistently timely pay…
nouli --format text new "$example-history" \
  'Fictional application L-101: the verified credit record covers 48 scheduled
monthly payments. Every payment was on time. There are no defaults or
delinquent balances, and the record is complete for this review.' \
  -q 'history: How strong is the documented repayment performance? <Adverse payment history,
    Mixed payment history,
    Consistently timely payments>'

Output

  turn 1 · 1 fact · 1 question
  history       expected 2.00 of 2   ▁▁█
                Adverse payment history 0.00 · Mixed payment history 0.00 · Consistently timely pay…
  typesafe/jev-1.14.0 · session 01a1878e-1c03-7318-94b0-5aa4573c002b · turn 01a1878e-1c05-7735-9cef-4958b1adb77f

The returned score is 2, the highest level on this rubric. A score can be fractional; it is an expected position on the supplied scale, not necessarily a selected category.

03Record the request and sample product policy

Record the two quoted products and the sample bank policy. The policy requires both repayment evidence and an affordability check, and it will be shared by both review branches.

history › /new policy
  new session "policy"
policy › Fictional bank policy for application L-101: the applicant requests a 6000 USD personal loan with a quoted all-in monthly installment of 250 USD. A smaller 3000 USD loan has a quoted all-in installment of 150 USD. Either offer requires at least 1000 USD remaining each month after living expenses, existing debt payments, and the proposed installment. Repayment records must be complete with no defaults, no current delinquency, and at least 24 timely scheduled payments. Missing evidence requires manual review. Prefer the requested loan if both gates pass; otherwise recommend the smaller loan if both gates pass for it; otherwise refer for manual review. No funds have been advanced.
policy › ?policy: What must a loan recommendation consider? [Both affordability and documented repayment history, Repayment history alone, Income alone]
  turn 1 · 1 fact · 1 question
  policy      ▶ Both affordability and document… ████████████████████ 1.00
                Repayment history alone                               0.00
                Income alone                                          0.00
nouli --format text new "$example-policy" \
  'Fictional bank policy for application L-101: the applicant requests a 6000 USD
personal loan with a quoted all-in monthly installment of 250 USD. A smaller
3000 USD loan has a quoted all-in installment of 150 USD. Either offer requires at
least 1000 USD remaining each month after living expenses, existing debt
payments, and the proposed installment. Repayment records must be complete
with no defaults, no current delinquency, and at least 24 timely scheduled
payments. Missing evidence requires manual review. Prefer the requested loan
if both gates pass; otherwise recommend the smaller loan if both gates pass
for it; otherwise refer for manual review. No funds have been advanced.' \
  -q 'policy: What must a loan recommendation consider? [Both affordability and documented repayment history,
    Repayment history alone,
    Income alone]'

Output

  turn 1 · 1 fact · 1 question
  policy      ▶ Both affordability and document… ████████████████████ 1.00
                Repayment history alone                               0.00
                Income alone                                          0.00
  typesafe/jev-1.14.0 · session 01a1878e-1c0c-74fb-89c7-db72e28ef4d4 · turn 01a1878e-1c0d-7672-9324-08c8572c4152

The answer identifies the two required checks. The 1000 USD monthly remainder and quoted installments are sample bank rules, not regulatory formulas.

04Review affordability for both loan sizes

Blend the cash-flow and policy sessions to evaluate each quoted installment. Repeated --from supplies both source histories to a new decision.

policy › /blend cashflow policy as affordability
  new session "affordability" from cashflow + policy · no standing questions
affordability › Apply the sample product policy to the latest verified cash-flow record. Subtract each quoted installment separately, since these are alternative offers, not two concurrent loans. Compare the remainder with the 1000 USD sample threshold.
affordability › ?affordability: Which quoted loans satisfy the sample affordability policy? [Both quoted loans meet the affordability threshold, Only the 3000 USD loan meets the affordability threshold, Neither quoted loan meets the affordability threshold, Required affordability evidence is missing]
  turn 1 · 1 fact · 1 question
  affordabil… ▶ Both quoted loans meet the affo… █████████████████▊   0.89
                Only the 3000 USD loan meets th… █▎                   0.06
                Neither quoted loan meets the a… ▊                    0.04
                Required affordability evidence… ▎                    0.01
nouli --format text new "$example-affordability" --from "$example-cashflow" --from "$example-policy" \
  'Apply the sample product policy to the latest verified cash-flow record.
Subtract each quoted installment separately, since these are alternative
offers, not two concurrent loans. Compare the remainder with the 1000 USD sample
threshold.' \
  -q 'affordability: Which quoted loans satisfy the sample affordability policy? [Both quoted loans meet the affordability threshold,
    Only the 3000 USD loan meets the affordability threshold,
    Neither quoted loan meets the affordability threshold,
    Required affordability evidence is missing]'

Output

  turn 1 · 1 fact · 1 question
  affordabil… ▶ Both quoted loans meet the affo… █████████████████▊   0.89
                Only the 3000 USD loan meets th… █▎                   0.06
                Neither quoted loan meets the a… ▊                    0.04
                Required affordability evidence… ▎                    0.01
  typesafe/jev-1.14.0 · session 01a1878e-1c15-77a4-8e4a-38a4ba7c2414 · turn 01a1878e-1c17-7088-af09-87a69b1d7152

At the initial income, the remainders are 1150 USD for the requested loan and 1250 USD for the smaller alternative. Both exceed the sample 1000 USD threshold.

05Review the credit-history gate

Blend the independent repayment record with the same policy. This branch checks history requirements without treating payment performance as proof of affordability.

affordability › /blend history policy as credit-review
  new session "credit-review" from history + policy · no standing questions
credit-review › Apply the sample policy requirements for repayment records only. Do not infer affordability from this review.
credit-review › ?credit_review: Does the documented repayment record pass the sample history gate? [The complete record meets the history requirements, The record fails the history requirements, Required history evidence is missing]
  turn 1 · 1 fact · 1 question
  credit_rev… ▶ The complete record meets the h… ███████████████████▊ 0.99
                The record fails the history re…                      0.00
                Required history evidence is mi… ▎                    0.01
nouli --format text new "$example-credit-review" --from "$example-history" --from "$example-policy" \
  'Apply the sample policy requirements for repayment records only. Do not infer
affordability from this review.' \
  -q 'credit_review: Does the documented repayment record pass the sample history gate? [The complete record meets the history requirements,
    The record fails the history requirements,
    Required history evidence is missing]'

Output

  turn 1 · 1 fact · 1 question
  credit_rev… ▶ The complete record meets the h… ███████████████████▊ 0.99
                The record fails the history re…                      0.00
                Required history evidence is mi… ▎                    0.01
  typesafe/jev-1.14.0 · session 01a1878e-1c1f-73f2-96d0-15c5be4dbb38 · turn 01a1878e-1c21-72b3-8b25-af337fa95044

The record meets the sample history gate: it is complete, includes 48 timely payments, and has no defaults or current delinquency.

06Combine both reviews into a lending recommendation

Combine the two review sessions. Each source is already a blend, so the recommendation includes cash flow, repayment history, and the shared policy.

credit-review › /blend affordability credit-review as recommendation
  new session "recommendation" from affordability + credit-review · no standing questions
recommendation › Combine the affordability and credit-history reviews using the sample product policy. A passing history gate cannot override an affordability failure. Prefer the requested 6000 USD loan if eligible; otherwise recommend the eligible 3000 USD alternative; otherwise refer for manual review. This is a recommendation for a loan officer, not an executed lending decision.
recommendation › ?recommendation: What should the loan officer review? [Recommend the requested 6000 USD loan at the quoted 250 USD installment, Recommend review of the 3000 USD alternative at the quoted 150 USD installment, Refer for manual review without recommending either loan]
  turn 1 · 1 fact · 1 question
  recommenda… ▶ Recommend the requested 6000 US… ██████████████████▋  0.93
                Recommend review of the 3000 US… ▍                    0.02
                Refer for manual review without… █                    0.05
nouli --format text new "$example-recommendation" --from "$example-affordability" --from "$example-credit-review" \
  'Combine the affordability and credit-history reviews using the sample product
policy. A passing history gate cannot override an affordability failure.
Prefer the requested 6000 USD loan if eligible; otherwise recommend the eligible
3000 USD alternative; otherwise refer for manual review. This is a recommendation
for a loan officer, not an executed lending decision.' \
  -q 'recommendation: What should the loan officer review? [Recommend the requested 6000 USD loan at the quoted 250 USD installment,
    Recommend review of the 3000 USD alternative at the quoted 150 USD installment,
    Refer for manual review without recommending either loan]'

Output

  turn 1 · 1 fact · 1 question
  recommenda… ▶ Recommend the requested 6000 US… ██████████████████▋  0.93
                Recommend review of the 3000 US… ▍                    0.02
                Refer for manual review without… █                    0.05
  typesafe/jev-1.14.0 · session 01a1878e-1c29-74a0-9e11-c2ed0edaa1d0 · turn 01a1878e-1c2c-73bf-b813-a7581646b347

The model recommends the requested loan using the initial evidence. This remains a recommendation for review; the command does not approve or disburse funds.

07Record corrected income verification

Continue the cash-flow session with corrected income of 4800 USD. The later verification explicitly replaces the earlier 5000 USD figure for subsequent decisions.

recommendation › /use cashflow
  cashflow · 1 standing question
cashflow › Fictional application L-101, corrected verification at 11:00: recurring net income is 4800 USD per month, replacing the 09:00 figure of 5000 USD. Essential living expenses remain 3000 USD and existing debt payments remain 600 USD. There are no other obligations. The proposed loan has not been approved or disbursed.
cashflow › ?cashflow: What monthly amount now remains before a new loan payment? [1200 USD, 1400 USD, Request missing cash-flow records]
  turn 2 · 1 fact · 1 question · re-asked 1
  cashflow    ▶ 1200 USD                         ██████████████████▋  0.93   → was 1400 USD 1.00
                1400 USD                         █▎                   0.06
                Request missing cash-flow recor… ▎                    0.01
nouli --format text add "$example-cashflow" \
  'Fictional application L-101, corrected verification at 11:00: recurring net
income is 4800 USD per month, replacing the 09:00 figure of 5000 USD. Essential
living expenses remain 3000 USD and existing debt payments remain 600 USD. There are
no other obligations. The proposed loan has not been approved or disbursed.' \
  -q 'cashflow: What monthly amount now remains before a new loan payment? [1200 USD,
    1400 USD,
    Request missing cash-flow records]'

Output

  turn 2 · 1 fact · 1 question · re-asked 1
  cashflow    ▶ 1200 USD                         ██████████████████▋  0.93   → was 1400 USD 1.00
                1400 USD                         █▎                   0.06
                Request missing cash-flow recor… ▎                    0.01
  typesafe/jev-1.14.0 · session 01a1878e-1bfa-74c1-a042-ac9efeade77f · turn 01a1878e-1c37-74f9-913a-68206c37d8d1

The model returns 1200 USD, which matches the corrected remainder: 4800 - 3000 - 600 = 1200 USD. The earlier 1400 USD answer is shown as the previous turn.

08Create an updated affordability review

Create a new affordability blend from the updated cash-flow session and the original policy. The earlier affordability decision remains saved with its original sources.

cashflow › /blend cashflow policy as affordability-updated
  new session "affordability-updated" from cashflow + policy · no standing questions
affordability-updated › Apply the sample product policy to the latest verified cash-flow record. Subtract each quoted installment separately, since these are alternative offers, not two concurrent loans. Compare the remainder with the 1000 USD sample threshold.
affordability-updated › ?affordability_updated: Which quoted loans satisfy the sample affordability policy now? [Both quoted loans meet the affordability threshold, Only the 3000 USD loan meets the affordability threshold, Neither quoted loan meets the affordability threshold, Required affordability evidence is missing]
  turn 1 · 1 fact · 1 question
  affordabil… ▶ Both quoted loans meet the affo… ██████████████▋      0.73
                Only the 3000 USD loan meets th… ███                  0.15
                Neither quoted loan meets the a… ██▎                  0.11
                Required affordability evidence… ▎                    0.01
nouli --format text new "$example-affordability-updated" --from "$example-cashflow" --from "$example-policy" \
  'Apply the sample product policy to the latest verified cash-flow record.
Subtract each quoted installment separately, since these are alternative
offers, not two concurrent loans. Compare the remainder with the 1000 USD sample
threshold.' \
  -q 'affordability_updated: Which quoted loans satisfy the sample affordability policy now? [Both quoted loans meet the affordability threshold,
    Only the 3000 USD loan meets the affordability threshold,
    Neither quoted loan meets the affordability threshold,
    Required affordability evidence is missing]'

Output

  turn 1 · 1 fact · 1 question
  affordabil… ▶ Both quoted loans meet the affo… ██████████████▋      0.73
                Only the 3000 USD loan meets th… ███                  0.15
                Neither quoted loan meets the a… ██▎                  0.11
                Required affordability evidence… ▎                    0.01
  typesafe/jev-1.14.0 · session 01a1878e-1c3e-7128-9cc4-9f49f8c3cde8 · turn 01a1878e-1c41-7496-a1b8-0d8505cd3e3a

Review finding: the model still says both loans qualify. With corrected income, the requested installment leaves 950 USD and the smaller installment leaves 1050 USD. Only the smaller loan meets the sample threshold.

09Reconsider the offer using the updated review

Combine the updated affordability review with the unchanged repayment-history review to obtain a new recommendation.

affordability-updated › /blend affordability-updated credit-review as recommendation-updated
  new session "recommendation-updated" from affordability-updated + credit-review · no standing questions
recommendation-updated › Combine the affordability and credit-history reviews using the sample product policy. A passing history gate cannot override an affordability failure. Prefer the requested 6000 USD loan if eligible; otherwise recommend the eligible 3000 USD alternative; otherwise refer for manual review. This is a recommendation for a loan officer, not an executed lending decision.
recommendation-updated › ?recommendation_updated: What should the loan officer review now? [Recommend the requested 6000 USD loan at the quoted 250 USD installment, Recommend review of the 3000 USD alternative at the quoted 150 USD installment, Refer for manual review without recommending either loan]
  turn 1 · 1 fact · 1 question
  recommenda… ▶ Recommend the requested 6000 US… ████████████████▍    0.82
                Recommend review of the 3000 US… █▍                   0.07
                Refer for manual review without… ██▎                  0.11
nouli --format text new "$example-recommendation-updated" --from "$example-affordability-updated" --from "$example-credit-review" \
  'Combine the affordability and credit-history reviews using the sample product
policy. A passing history gate cannot override an affordability failure.
Prefer the requested 6000 USD loan if eligible; otherwise recommend the eligible
3000 USD alternative; otherwise refer for manual review. This is a recommendation
for a loan officer, not an executed lending decision.' \
  -q 'recommendation_updated: What should the loan officer review now? [Recommend the requested 6000 USD loan at the quoted 250 USD installment,
    Recommend review of the 3000 USD alternative at the quoted 150 USD installment,
    Refer for manual review without recommending either loan]'

Output

  turn 1 · 1 fact · 1 question
  recommenda… ▶ Recommend the requested 6000 US… ████████████████▍    0.82
                Recommend review of the 3000 US… █▍                   0.07
                Refer for manual review without… ██▎                  0.11
  typesafe/jev-1.14.0 · session 01a1878e-1c49-74d5-ad40-071d6563ed87 · turn 01a1878e-1c4c-73fe-b861-b59cdea5f935

Review finding: the model continues to recommend the requested loan. Under the supplied sample policy, the smaller alternative is the eligible recommendation. This run shows why a saved graph supports inspection and why model recommendations need independent checks of numerical conditions.