Use cases
The cases below are agent decisions with a real cost when the answer is wrong. They follow the same three steps:
- Find the starting record. The user asks in their own words. Search by meaning finds the recall notice, the payment or the advisory.
- Prove the answer by path. A SPARQL query follows the stored links from that record. The rows it returns are the evidence.
- Record the decision. The agent stores its outcome with the commit it read. Anyone can replay the query later against the same data.
Each case names the records to store, the query that answers it and what to record. All of them work with JSON records and the SDKs. Build with JSON records walks through the first case end to end. Load your data shows how a database and your documents become such records.
The queries use the prefixes for names you declare in JSON. Add these lines at the top of each query. Core concepts explains them.
PREFIX dclass: <https://littlebigbrain.com/class/>PREFIX dr: <https://littlebigbrain.com/r/>PREFIX dp: <https://littlebigbrain.com/p/>PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>| The agent must decide | Pattern | Answered by |
|---|---|---|
| Which batches and sites were exposed to a recalled lot | Chain of unknown length, identity across systems | Property paths, keyed entities |
| Whether a payment needs escalation | Chain to a designated party, as of the payment date | Property paths, retained commits |
| Which journal entries lacked independent approval | A required fact is absent | FILTER NOT EXISTS |
| Which agreements need consent for an acquisition | One concept under several source labels, control chains | Class hierarchy, subclass entailment |
| Which services were exposed to a vulnerability | Dependency paths through many unrelated records | Bounded property paths |
| Which claims belong to one fraud ring | Records connected through shared things | Alternation and inverse paths |
Recall exposure
Section titled “Recall exposure”Question. A supplier recalls one ingredient lot. Which released batches contain its material, and which active study sites received those batches?
Records. IngredientLot, IntermediateLot, ReleasedBatch, StudySite
with the subtype ActiveStudySite, and RecallNotice.
Links. PRODUCED_FROM between lots and batches, RECALLS from the notice
and RECEIVED_BATCH from a site. Give lots a key from the manufacturing
system. A lot recorded under a supplier id and an ERP id then stays one record.
Query. dr:produced_from+ follows the genealogy however deep it goes.
The activestudysite type leaves a closed site out of the report.
SELECT ?batchNumber ?site WHERE { ?lot dp:lot_number "ZH-VAL-2018-07" . ?batch a dclass:releasedbatch ; dr:produced_from+ ?lot ; dp:batch_number ?batchNumber . OPTIONAL { ?siteNode a dclass:activestudysite ; dr:received_batch ?batch ; rdfs:label ?site . }}Afterwards. Store an AgentDecision whose based_on_commit_seq is the
served_at_seq of the response. The full walkthrough, with schema, writes,
validation, and replay, is Build with JSON records.
Payment escalation
Section titled “Payment escalation”Question. Does transaction TXN-884 require escalation, and which beneficiary, control, and designation chain proves it?
Records. Transaction, Party and Designation. Store the designation’s
listed_at as a date_time field.
Links. PAID_TO from a transaction to its beneficiary. CONTROLLED_BY
between parties. DESIGNATED_UNDER from a party to a sanctions designation.
Query. Walk zero or more control links, then look for a designation. An
ASK returns the yes or no; the SELECT form returns the chain.
SELECT ?beneficiary ?owner ?designation WHERE { ?txn dp:transaction_id "TXN-884" ; dr:paid_to ?beneficiary . ?beneficiary dr:controlled_by* ?owner . ?owner dr:designated_under ?designation .}Afterwards. Screening runs at a moment in time. Store the response’s
served_at_seq with the decision. A reviewer may ask what the list held on the
payment date. Replay the query with as_of_commit_seq to answer.
A designation added the next day is absent from the replay. That is the correct answer to “what did the agent know”. See Replay an answer.
Quarter-close audit
Section titled “Quarter-close audit”Question. Which material journal entries in the quarter lacked independent approval? The policy in force at the time sets the rules.
Records. JournalEntry with amount (f64) and posted_at
(date_time), Person, and Policy with effective_from and
effective_to.
Links. POSTED_BY and APPROVED_BY from an entry to a person.
SCOPED_BY from an entry to its policy.
Query. A missing approval is an absent fact. In a graph, absence means
“not recorded”. A query asks for it with FILTER NOT EXISTS. The independence
test compares the two people.
SELECT ?entry ?amount WHERE { ?entry a dclass:journalentry ; dp:amount ?amount ; dr:posted_by ?poster . FILTER(?amount >= 250000) FILTER NOT EXISTS { ?entry dr:approved_by ?approver . FILTER(?approver != ?poster) }}The threshold comes from the policy in force on the posting date. Join the
entry to its policy. Then compare posted_at with the policy window, with the
same datatype on both sides. FILTER comparisons and
datatypes
explains why a mismatched datatype silently drops the row.
Afterwards. The audit finding cites the commit it was computed from. Read
the published conformance report at the same time. Keep its validated_at_seq
with the finding, so the record also names the rules in force.
Acquisition consent
Section titled “Acquisition consent”Question. A company is being acquired. Which active agreements require counterparty consent?
Records. Agreement, Company, and clause types. Contract data has two
common problems.
- One company appears under a contract id in one system and a registry id in
another. Give the record one
keyand write both source records against it. - Each source names the clause differently. Declare
ChangeOfControlClauseandAssignmentConsentClauseas types withsuper_types: ["ConsentClause"]. The graph stores both links asrdfs:subClassOfstatements. See Add a type hierarchy.
Query. Ask for the parent type with entailment: "subclass", and the
subtypes match. dr:controlled_by+ follows any number of ownership links. It
finds a counterparty anywhere inside the acquired group.
SELECT ?agreement ?counterparty WHERE { ?agreement a dclass:agreement ; dp:status "active" ; dr:has_clause ?clause ; dr:counterparty ?counterparty . ?clause a dclass:consentclause . ?counterparty dr:controlled_by+ ?acquired . ?acquired dp:registry_id "HRB-123456" .}OWL can go one step further. It can declare requiresConsentFor as a derived
link. The agent’s query is then a single pattern with the proof attached. That
rule is a Turtle document. See Reasoning & inference.
Afterwards. Store the decision with its served_at_seq. The registry may
later merge two companies. The earlier read stays reproducible.
Vulnerability exposure
Section titled “Vulnerability exposure”Question. On the day an advisory is published, which customer-facing services embed the affected library version?
Records. Service with a customer_facing boolean, Artifact with
version, and Advisory.
Links. DEPENDS_ON from a service to its artifacts, and between
artifacts. AFFECTS from an advisory to an artifact version. A real corpus
holds hundreds of unrelated service paths. The query must leave them out.
Query. Start at the advisory. Then walk the dependencies backwards to the
services that reach it. ^dr:depends_on+ reads “one or more DEPENDS_ON
links, followed in reverse”.
SELECT DISTINCT ?service WHERE { ?advisory dp:cve_id "CVE-2021-44228" ; dr:affects ?artifact . ?artifact ^dr:depends_on+ ?service . ?service a dclass:service ; dp:customer_facing true .}Paths run under the same read limits as any query. A very large dependency graph returns a typed limit error. It never returns a partial list. Keep the start fixed, as above, so the walk starts from one record.
Afterwards. Pin the query to the commit that held the dependency graph on disclosure day. A deployment the next week changes the latest data. The pinned read still returns the exposure list as it stood.
Claims investigation
Section titled “Claims investigation”Question. Which open claims belong to a coordinated repair-shop ring?
Records. Claim with status, Device, PayoutAccount and Repairer.
Links. FILED_FROM to a device, PAID_TO to an account, REPAIRED_BY to
a repairer.
Query. Two claims are connected when they share any of the three. The path below takes a link forward, then a link in reverse. It steps from a claim to a shared thing and back to another claim.
SELECT DISTINCT ?claim ?other WHERE { ?claim a dclass:claim ; dp:status "open" . ?claim (dr:filed_from|dr:paid_to|dr:repaired_by)/^(dr:filed_from|dr:paid_to|dr:repaired_by) ?other . ?other a dclass:claim ; dp:status "open" . FILTER(?claim != ?other)}Repeat the alternation with + to follow the ring through several shared
things. For large networks, page the result with LIMIT and OFFSET. Keep the
start claim fixed.
Afterwards. Store the investigation with the commit it read. A device may turn up in a new claim later. You can reopen the case, and the earlier network is still queryable at its own commit.
What every case records
Section titled “What every case records”Each decision above stores the same three things, all as ordinary records:
- The decision record. Set its
based_on_commit_seqto theserved_at_seqof the query response. Store the outcome as a controlled value;allowed_valuesenforces the list. - A link from the decision to its subject, with an
evidencestring. The evidence stays on the fact. The change log shows when it was added. - Nothing overwritten. Later corrections are new commits. The replay with
as_of_commit_seqreturns the rows the agent read. The latest data shows the corrected state.