Blog
Treat business facts as versioned dependencies
A reference architecture for agents that know when to proceed, when to ask and when to stop.
The input contract is weaker than the tool contract
We give agent tools structured schemas: customer IDs, dates, amounts, allowed operations. But the fact used to fill a field often arrives as an unstructured sentence with little history. The API can validate that an amount is numeric. It cannot infer that the amount is the approved rate for this customer, term and date.
A safer architecture treats a business fact as a versioned dependency of the action. This is a proposed design pattern, not a claim that Ember currently ships the schema or APIs described below.
A fact needs identity, scope and evidence
A fact record should identify the entity and attribute, then state the conditions under which the value applies. For a renewal rate, that might include the customer, currency, contract period and effective dates. Without scope, two different but valid values can look like a contradiction.
Keep source references, source observation times, valid-time boundaries, the resolving person or rule, and a revision identifier. Distinguish when the system learned something from when it became true. An agreement discovered today may have been effective last month.
Keep status separate from value. A record can be supported, conflicted, missing, expired or superseded. 'Unknown' is a valid result. A free-form confidence score must not erase a conflict between two otherwise credible sources.
Resolve uncertainty through a state machine
Ingestion produces candidate claims, not instant truth. Normalize entity IDs, currencies, units and time intervals before comparing candidates. Apply explicit source-precedence rules only within their declared scope. If a rule cannot resolve the disagreement, assign an owner and ask a bounded question with the evidence attached.
A response becomes a new revision after the responder's authority and the answer's scope are checked. Silence does not promote a candidate to supported. An expired deadline can leave the fact unresolved and the dependent action paused.
Human input alone is not enough either. The person can misunderstand the question or answer outside their remit. Capture exactly what they confirmed, allow correction, and retain the competing evidence rather than overwriting history. LangGraph's pause, persistence and resume mechanisms are one way to implement the execution boundary; they do not supply these business rules for you. [3]
Check dependencies again at the point of action
An agent should request a fact with its intended use and decision time, not merely ask for a string. A supported response can include the revision and evidence references. A conflict should return candidates and a reason execution is blocked, rather than a best-effort value disguised as a final answer.
When the agent drafts an action, bind it to the fact revision it used. Before committing, verify that the required facts are still supported and that their revisions have not changed. This is an optimistic-concurrency pattern: if the agreement changed after the draft was prepared, revalidate the draft instead of sending it unchanged.
Source changes should mark dependent resolutions for review when they invalidate the supporting assumptions. Invalidation needs business rules. A new email does not always revoke an agreement, but a new accepted amendment might. A time-to-live can limit exposure; it cannot replace understanding what changed.
A shared answer must not become a permission bypass
A derived fact can reveal sensitive source material even when it contains no quote. Reusing it across agents therefore requires its own access decision. Treat evidence, resolved values and human answers as governed data, not as a cache that every tool may read.
Decide which audiences can see the value, which can inspect the evidence, and which can only learn that an unresolved dependency prevents an action. Glean's permission-mirroring model is a useful documented example of treating access as part of retrieval. [4] A resolution layer should preserve that discipline rather than flatten it away.
Measure the loop, not just the generated answer
Test with contradictory records, delayed synchronization, conditional proposals, missing owners, ambiguous entities and a fact changing between draft and send. Measure conflicts missed, unnecessary escalations, resolution latency, questions per owner and downstream reuse. Then inspect the actual actions taken, not just whether the answer sounded right.
Optimizing only for completion rewards guessing. Optimizing only for escalation turns every task into a queue. The engineering objective is narrower: complete work when its dependencies are supported, and make the remaining uncertainty cheap for the right person to resolve.
That is why the data plane matters. More capable agents can carry a wrong fact farther. A dependable agent needs a fact layer that carries evidence, authority, time and uncertainty with the value, all the way to the point where the action counts.