Skip to content

Use cases

View Markdown

The cases below are agent decisions with a real cost when the answer is wrong. They follow the same three steps:

  1. Find the starting record. The user asks in their own words. Search by meaning finds the recall notice, the payment or the advisory.
  2. Prove the answer by path. A SPARQL query follows the stored links from that record. The rows it returns are the evidence.
  3. 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

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.

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.

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.

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 key and write both source records against it.
  • Each source names the clause differently. Declare ChangeOfControlClause and AssignmentConsentClause as types with super_types: ["ConsentClause"]. The graph stores both links as rdfs:subClassOf statements. 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.

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.

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.

Each decision above stores the same three things, all as ordinary records:

  • The decision record. Set its based_on_commit_seq to the served_at_seq of the query response. Store the outcome as a controlled value; allowed_values enforces the list.
  • A link from the decision to its subject, with an evidence string. 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_seq returns the rows the agent read. The latest data shows the corrected state.