NOULI

Examples

Food recall response

The recorded response starts with warehouse holds and a missing customer acknowledgment. It changes to include downstream follow-up when Summit reports 12 boxes already sold.

The problem

A distributor needs to respond to the May 2022 Jif recall. It has jars in the warehouse and snack boxes already delivered to customers. A warehouse hold cannot account for products that have left the site. Later, a customer reports that some boxes were sold to end customers.

The historical scope comes from the FDA recall overview and product notice. The follow-up workflow draws on FDA recall communication guidance. Warehouse counts, shipments, customer replies, and local response rules are illustrative.

What we will do

We will keep the published recall scope, warehouse inventory, and customer distribution records separate. We will blend scope with inventory to choose a stock action, and scope with distribution records to choose outreach. Those two decisions will feed a coordinated response. A later customer reply will drive a new outreach decision and response plan.

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=recall
show the steps as

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

01Record the recall scope

Save the historical recall scope as an independent source. The lot-code rule has two conditions: the seven-digit range and the 425 suffix.

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

scope › The FDA May 2022 recall includes Jif 16 ounce creamy peanut butter, identifier 5150025516 as printed in the notice. A jar is in scope when the first seven digits of its lot code are between 1274425 and 2140425 and end in 425. The range alone is insufficient. This is the published scope for this historical example.
scope › ?scope: How should a jar be matched to this recall? [Match the product and both lot-code conditions, Use the product name alone, Request a clearer recall notice]
  turn 1 · 1 fact · 1 question
  scope       ▶ Match the product and both lot-… ████████████████████ 1.00
                Use the product name alone                            0.00
                Request a clearer recall notice                       0.00
nouli --format text new "$example-scope" \
  'The FDA May 2022 recall includes Jif 16 ounce creamy peanut butter, identifier
5150025516 as printed in the notice. A jar is in scope when the first seven
digits of its lot code are between 1274425 and 2140425 and end in 425. The
range alone is insufficient. This is the published scope for this historical
example.' \
  -q 'scope: How should a jar be matched to this recall? [Match the product and both lot-code conditions,
    Use the product name alone,
    Request a clearer recall notice]'

Output

  turn 1 · 1 fact · 1 question
  scope       ▶ Match the product and both lot-… ████████████████████ 1.00
                Use the product name alone                            0.00
                Request a clearer recall notice                       0.00
  typesafe/jev-1.14.0 · session 01a1878e-1c7a-7508-ad4f-fdb7af45176f · turn 01a1878e-1c7c-722e-a61d-599f6b5c7101

The model selects matching both product and lot conditions. Product identity alone, or the numeric range without the suffix condition, would overstate the scope.

02Review warehouse traceability

Record warehouse traceability in a new history. This question asks whether every jar has an identifiable lot, before applying recall scope.

scope › /new stock
  new session "stock"
stock › Illustrative warehouse inventory: 40 sealed jars have lot code 1352425, 10 have lot code 1352426, and 6 have unreadable lot codes. All are Jif 16 ounce creamy peanut butter, identifier 5150025516. No other jars are on hand.
stock › ?stock: Can every jar in this inventory be matched to an identifiable lot?
  turn 1 · 1 fact · 1 question
  stock         yes                              █▍                   0.07
nouli --format text new "$example-stock" \
  'Illustrative warehouse inventory: 40 sealed jars have lot code 1352425, 10
have lot code 1352426, and 6 have unreadable lot codes. All are Jif 16 ounce
creamy peanut butter, identifier 5150025516. No other jars are on hand.' \
  -q 'stock: Can every jar in this inventory be matched to an identifiable lot?'

Output

  turn 1 · 1 fact · 1 question
  stock         yes                              █▍                   0.07
  typesafe/jev-1.14.0 · session 01a1878e-1c83-7601-a75b-ca568ad11ea9 · turn 01a1878e-1c85-75ee-a441-1a2f8db9238b

P(yes)=0.07 reflects the model answer to whether every jar can be identified. Six codes are unreadable; this result is not itself a recall-scope decision.

03Review distribution and customer responses

Record shipments and customer responses separately. The 60 snack boxes were made from an earlier ingredient delivery, not from the jars still in the warehouse.

stock › /new customers
  new session "customers"
customers › Illustrative records at 09:30 on May 23, 2022: ingredient lot 1352425 was used in 60 snack boxes, batch SNACK-A. Harbor received 30 and Summit received 30. Harbor acknowledges the recall notice and confirms all 30 are isolated. Summit has not responded. There were no other shipments of this batch.
customers › ?customers: Which customer needs a response follow-up first? [Contact Harbor, Contact Summit, Contact both customers again]
  turn 1 · 1 fact · 1 question
  customers     Contact Harbor                                        0.00
              ▶ Contact Summit                   ████████████████████ 1.00
                Contact both customers again                          0.00
nouli --format text new "$example-customers" \
  'Illustrative records at 09:30 on May 23, 2022: ingredient lot 1352425 was used
in 60 snack boxes, batch SNACK-A. Harbor received 30 and Summit received 30.
Harbor acknowledges the recall notice and confirms all 30 are isolated. Summit
has not responded. There were no other shipments of this batch.' \
  -q 'customers: Which customer needs a response follow-up first? [Contact Harbor,
    Contact Summit,
    Contact both customers again]'

Output

  turn 1 · 1 fact · 1 question
  customers     Contact Harbor                                        0.00
              ▶ Contact Summit                   ████████████████████ 1.00
                Contact both customers again                          0.00
  typesafe/jev-1.14.0 · session 01a1878e-1c8c-7365-90c1-001d50a5441c · turn 01a1878e-1c8e-7729-bc83-a55a5c438b98

Harbor has acknowledged the notice and isolated its boxes. Summit has not replied, so the model selects Summit for follow-up.

04Choose a warehouse action

Blend published scope and warehouse records to choose a stock action under the sample hold policy.

customers › /blend scope stock as stock-plan
  new session "stock-plan" from scope + stock · no standing questions
stock-plan › Our example stock policy is to quarantine confirmed recalled jars and hold unreadable codes for identification. Apply the scope only to products and lots it actually covers.
stock-plan › ?stock_plan: What should the warehouse do with its stock? [Quarantine matching jars and hold unreadable codes for identification, Hold every jar pending further review, Identify unreadable codes before choosing any stock action]
  turn 1 · 1 fact · 1 question
  stock_plan  ▶ Quarantine matching jars and ho… ████████████████████ 1.00
                Hold every jar pending further …                      0.00
                Identify unreadable codes befor…                      0.00
nouli --format text new "$example-stock-plan" --from "$example-scope" --from "$example-stock" \
  'Our example stock policy is to quarantine confirmed recalled jars and hold
unreadable codes for identification. Apply the scope only to products and lots
it actually covers.' \
  -q 'stock_plan: What should the warehouse do with its stock? [Quarantine matching jars and hold unreadable codes for identification,
    Hold every jar pending further review,
    Identify unreadable codes before choosing any stock action]'

Output

  turn 1 · 1 fact · 1 question
  stock_plan  ▶ Quarantine matching jars and ho… ████████████████████ 1.00
                Hold every jar pending further …                      0.00
                Identify unreadable codes befor…                      0.00
  typesafe/jev-1.14.0 · session 01a1878e-1c95-75d9-ac95-1b04cb845ca4 · turn 01a1878e-1c98-7682-8718-7eea0fe0db26

The matching lot is held, unreadable codes are held for identification, and the identified nonmatching lot is distinguished from them. The chosen label summarizes the action; the source records retain the counts and lot codes.

05Choose a customer follow-up

Blend the same recall scope with the independent customer history to decide what outreach is needed.

stock-plan › /blend scope customers as outreach
  new session "outreach" from scope + customers · no standing questions
outreach › Apply the recall scope to ingredient lot 1352425 and the snack boxes made from it. Following recall communication guidance, establish that affected customers received and followed the notice. Under our example response policy, missing acknowledgment requires direct follow-up; reported sales require escalation and verification of downstream notification. Use the latest dated response for each customer.
outreach › ?outreach: What customer follow-up is needed now? [Ask Summit to acknowledge the notice and account for its boxes, Verify that both customers have isolated all affected boxes, Escalate reported sales to the recall lead and verify downstream notification]
  turn 1 · 1 fact · 1 question
  outreach    ▶ Ask Summit to acknowledge the n… ████████████████████ 1.00
                Verify that both customers have…                      0.00
                Escalate reported sales to the …                      0.00
nouli --format text new "$example-outreach" --from "$example-scope" --from "$example-customers" \
  'Apply the recall scope to ingredient lot 1352425 and the snack boxes made from
it. Following recall communication guidance, establish that affected customers
received and followed the notice. Under our example response policy, missing
acknowledgment requires direct follow-up; reported sales require escalation
and verification of downstream notification. Use the latest dated response for
each customer.' \
  -q 'outreach: What customer follow-up is needed now? [Ask Summit to acknowledge the notice and account for its boxes,
    Verify that both customers have isolated all affected boxes,
    Escalate reported sales to the recall lead and verify downstream notification]'

Output

  turn 1 · 1 fact · 1 question
  outreach    ▶ Ask Summit to acknowledge the n… ████████████████████ 1.00
                Verify that both customers have…                      0.00
                Escalate reported sales to the …                      0.00
  typesafe/jev-1.14.0 · session 01a1878e-1ca0-7674-9bd1-24f7046accde · turn 01a1878e-1ca3-779f-bdeb-b70fb207c50c

The model asks Summit to acknowledge the notice and account for its boxes. This addresses products already distributed, which the warehouse action cannot resolve.

06Combine stock and customer decisions

Combine the stock and outreach decisions. Both sources are blends, so this response includes the independent warehouse and customer branches.

outreach › /blend stock-plan outreach as response
  new session "response" from stock-plan + outreach · no standing questions
response › Combine the warehouse and customer decisions into a recommendation for the recall lead. A warehouse hold does not account for shipped products. Coordinate any unresolved customer or downstream follow-up alongside the stock action. Use the latest dated customer records.
response › ?response: Which response should the recall lead coordinate? [Coordinate warehouse holds only, Coordinate warehouse holds and missing customer responses, Coordinate warehouse holds and escalation of sales to end customers]
  turn 1 · 1 fact · 1 question
  response      Coordinate warehouse holds only                       0.00
              ▶ Coordinate warehouse holds and … ████████████████████ 1.00
                Coordinate warehouse holds and …                      0.00
nouli --format text new "$example-response" --from "$example-stock-plan" --from "$example-outreach" \
  'Combine the warehouse and customer decisions into a recommendation for the
recall lead. A warehouse hold does not account for shipped products.
Coordinate any unresolved customer or downstream follow-up alongside the stock
action. Use the latest dated customer records.' \
  -q 'response: Which response should the recall lead coordinate? [Coordinate warehouse holds only,
    Coordinate warehouse holds and missing customer responses,
    Coordinate warehouse holds and escalation of sales to end customers]'

Output

  turn 1 · 1 fact · 1 question
  response      Coordinate warehouse holds only                       0.00
              ▶ Coordinate warehouse holds and … ████████████████████ 1.00
                Coordinate warehouse holds and …                      0.00
  typesafe/jev-1.14.0 · session 01a1878e-1caa-7315-b3e1-ebbe51a0d5b5 · turn 01a1878e-1cae-742a-ac59-0cbda5899e8e

The coordinated response includes stock holds and follow-up for the missing customer response. The recommendation does not send notices or move inventory.

07Add the next customer response

Continue the customer history with the later reply. Summit has isolated 18 boxes and reports 12 sold; downstream notification is still unknown. The session already has a customers question, so the new -q with the same ID replaces it.

response › /use customers
  customers · 1 standing question
customers › Illustrative update at 11:00 on May 23, 2022: Summit has now acknowledged the notice. It isolated 18 SNACK-A boxes and reports that 12 were already sold to end customers. Whether those buyers have been notified is unknown. This replaces the earlier Summit nonresponse. Harbor still has all 30 boxes isolated.
customers › ?customers: What is the next action for Summit? [Confirm acknowledgment only, Escalate the 12 sold boxes and verify downstream notification, Treat the customer response as complete]
  turn 2 · 1 fact · 1 question · re-asked 1
  customers     Confirm acknowledgment only      ▎                    0.01
              ▶ Escalate the 12 sold boxes and … ███████████████████▋ 0.98
                Treat the customer response as … ▎                    0.01
nouli --format text add "$example-customers" \
  'Illustrative update at 11:00 on May 23, 2022: Summit has now acknowledged the
notice. It isolated 18 SNACK-A boxes and reports that 12 were already sold to
end customers. Whether those buyers have been notified is unknown. This
replaces the earlier Summit nonresponse. Harbor still has all 30 boxes
isolated.' \
  -q 'customers: What is the next action for Summit? [Confirm acknowledgment only,
    Escalate the 12 sold boxes and verify downstream notification,
    Treat the customer response as complete]'

Output

  turn 2 · 1 fact · 1 question · re-asked 1
  customers     Confirm acknowledgment only      ▎                    0.01
              ▶ Escalate the 12 sold boxes and … ███████████████████▋ 0.98
                Treat the customer response as … ▎                    0.01
  typesafe/jev-1.14.0 · session 01a1878e-1c8c-7365-90c1-001d50a5441c · turn 01a1878e-1cb8-7535-b38e-94a0e8358f64

The model selects escalation of the 12 sold boxes and verification of downstream notification. The earlier nonresponse stays in history but is no longer the latest customer status.

08Reassess outreach using the updated source

Create a new outreach blend from scope and the updated customer history. Updating the customer session did not rewrite the earlier outreach decision.

customers › /blend scope customers as outreach-updated
  new session "outreach-updated" from scope + customers · no standing questions
outreach-updated › Apply the recall scope to ingredient lot 1352425 and the snack boxes made from it. Following recall communication guidance, establish that affected customers received and followed the notice. Under our example response policy, missing acknowledgment requires direct follow-up; reported sales require escalation and verification of downstream notification. Use the latest dated response for each customer.
outreach-updated › ?outreach_updated: What customer follow-up is needed now? [Ask Summit to acknowledge the notice and account for its boxes, Verify that both customers have isolated all affected boxes, Escalate reported sales to the recall lead and verify downstream notification]
  turn 1 · 1 fact · 1 question
  outreach_u…   Ask Summit to acknowledge the n…                      0.00
                Verify that both customers have…                      0.00
              ▶ Escalate reported sales to the … ████████████████████ 1.00
nouli --format text new "$example-outreach-updated" --from "$example-scope" --from "$example-customers" \
  'Apply the recall scope to ingredient lot 1352425 and the snack boxes made from
it. Following recall communication guidance, establish that affected customers
received and followed the notice. Under our example response policy, missing
acknowledgment requires direct follow-up; reported sales require escalation
and verification of downstream notification. Use the latest dated response for
each customer.' \
  -q 'outreach_updated: What customer follow-up is needed now? [Ask Summit to acknowledge the notice and account for its boxes,
    Verify that both customers have isolated all affected boxes,
    Escalate reported sales to the recall lead and verify downstream notification]'

Output

  turn 1 · 1 fact · 1 question
  outreach_u…   Ask Summit to acknowledge the n…                      0.00
                Verify that both customers have…                      0.00
              ▶ Escalate reported sales to the … ████████████████████ 1.00
  typesafe/jev-1.14.0 · session 01a1878e-1cbf-71cd-b6bc-da1df9d5100a · turn 01a1878e-1cc2-76b4-862f-f1daef12e7a8

The model now selects escalation of reported sales. Acknowledgment alone is insufficient because some affected products reached end customers.

09Combine the revised decisions

Reuse the unchanged stock plan and combine it with revised outreach to form a new coordinated response.

outreach-updated › /blend stock-plan outreach-updated as response-updated
  new session "response-updated" from stock-plan + outreach-updated · no standing questions
response-updated › Combine the warehouse and customer decisions into a recommendation for the recall lead. A warehouse hold does not account for shipped products. Coordinate any unresolved customer or downstream follow-up alongside the stock action. Use the latest dated customer records.
response-updated › ?response_updated: Which response should the recall lead coordinate? [Coordinate warehouse holds only, Coordinate warehouse holds and missing customer responses, Coordinate warehouse holds and escalation of sales to end customers]
  turn 1 · 1 fact · 1 question
  response_u…   Coordinate warehouse holds only                       0.00
                Coordinate warehouse holds and …                      0.00
              ▶ Coordinate warehouse holds and … ████████████████████ 1.00
nouli --format text new "$example-response-updated" --from "$example-stock-plan" --from "$example-outreach-updated" \
  'Combine the warehouse and customer decisions into a recommendation for the
recall lead. A warehouse hold does not account for shipped products.
Coordinate any unresolved customer or downstream follow-up alongside the stock
action. Use the latest dated customer records.' \
  -q 'response_updated: Which response should the recall lead coordinate? [Coordinate warehouse holds only,
    Coordinate warehouse holds and missing customer responses,
    Coordinate warehouse holds and escalation of sales to end customers]'

Output

  turn 1 · 1 fact · 1 question
  response_u…   Coordinate warehouse holds only                       0.00
                Coordinate warehouse holds and …                      0.00
              ▶ Coordinate warehouse holds and … ████████████████████ 1.00
  typesafe/jev-1.14.0 · session 01a1878e-1cc9-723d-b2bb-df1ea7f49627 · turn 01a1878e-1ccd-7795-8314-ed035c87cfed

The response now includes downstream follow-up alongside warehouse holds. The customer update changed the response without requiring a new warehouse assessment.