The flow at 2:05, 2:06 and 2:07 pm
- 2:05 pm, app. Marina disputes the August bill in your app. The message is tied to
invoice:erp:0823throughobject_refsand is in the live layer in under a second after it reaches the API. - 2:06 pm, billing agent. It reads
context(object="invoice:erp:0823", view="task:billing", verification="no_customer"), receives the dispute throughlive, the technician visit that failed at 2:02 pm and the March credit from the history. It posts the $40 credit in the ERP and recordsaction("credit", closes=...). - 2:06 pm, ERP. The ERP emits
invoice.credited. The action and the event become one record, and the action goes fromdeclaredtoconfirmed. - 2:07 pm, call. The voice pack already says: “Another agent: $40 credit on the August bill, Billing, 2:06 pm, confirmed by the system”.
Niadra never executes an action in a system of record. Your agent acts, with its own credentials. Niadra keeps what it needs to remember and what it did.
Before you start: the source
An internal agent is a source like any other, with its own key, audience classinternal_agent and a purpose such as billing. Access to the ERP is not access to the memory: the billing agent reads invoices and disputes, not technical open items or health data. Three settings matter here:
- Scope
acton the key (an agent key ships with it) and, if you want to close the list,trusted_action_opson the source (here["credit"]): the only operations it may record and whose declared actions close open items before the system confirms them. With no list, the source records any operation, and the closing’s gates decide. Thetrackscope alone never records an action. - Verification
no_customer, the level for tasks with no customer present. It sits outside the V0 to V4 scale and is only accepted frominternal_agentsources. A pack built forno_customernever goes to the customer. - Categories released for
no_customerin the space’s policy (no_customer_allowedon the category): a task with no customer reads only what the policy releases for it. Here, theinvoicecategory, with thebillingpurpose. It holds for the invoice in the pack and for the recent turns about it inlive: the 2:05 pm dispute namesinvoice:erp:0823and is filed underinvoice.
act scope comes with the key and the no_customer ceiling with the source, both chosen in the Console or through the control API; the trusted_action_ops list goes in when the source is created, in the Console’s “Operações confiáveis” field or through the control API. The billing source created at sign-up trusts only credit: any other operation it records comes back as operation_not_allowed (403) and is not recorded. When you create an agent’s source, declare every operation it performs.
Steps
1. Open a task centered on the invoice
A task plays the role a conversation plays for service agents: it pins the pack, scopes the SDK cache, groups the events for billing and closes withtask.ended. Without it, the server closes the task after 3 minutes without events, and an event of the same task within 10 minutes reopens it; each reopen doubles the wait, up to the 10 minutes.
The task:billing view is defined by your space as a template plus a policy. It favors objects of the task type, the open items tied to them and what was said about them in conversations; it leaves out what the billing purpose does not allow.
context(object=...) resolves the invoice to its owner and returns the pack centered on it: the timeline of the object plus the customer context the task needs. The same laws hold as for a conversation: pinned by task, with ETag and a receipt of the read. A read centered on an object is compiled on demand, with no language model in the path. A read by object or by profile id, like every internal agent’s read, sees only the items that came through confirmed handles: what arrived through an unconfirmed link stays out until a person or a system of record confirms it.
2. Act in the ERP, then record the action
Post the credit through your ERP integration. Then record the action withcloses, the open item it fulfils. Name it by id, or by the object and the canonical operation the open item waits for, which is what you usually know: the credit on invoice 0823.
corrects_action_id pointing to the old one. It only counts when both actions came from the same source: another source’s (another vendor’s) stays on record and in the context.
3. Let the system of record confirm it
The action staysdeclared until an event from the system of record confirms it. Send the ERP events through the generic webhook or as system events. When invoice.credited arrives for the same object and operation within the window, the two become a single record and the action is confirmed, so the credit is never counted twice.
A declared action closes an open item when its source trusts its operation (with no list, every one; with a list, only those on it); a confirmed one always closes it. The closing rules are in Systems.
4. Understand the retroactive close
The action can arrive before the open item exists. The dispute written in the app at 2:05 pm only becomes an open item when the app session closes and is extracted, say at 2:35 pm, and the billing agent acted at 2:06 pm. When the open item is created, Niadra looks for agent actions already applied to the same object and operation within the window. If one exists, the open item is bornresolved, pointing to the action that closed it.
5. Let other agents know
Every agent that reads this customer next sees the action in “Another agent”, with its source and time. If your CRM needs to show the outcome, subscribe to theaction.recorded and open_item.closed webhooks and write it there with your own integration. See Triggers and webhooks.
An assistant that talks with your team
An internal source also serves an assistant that talks with someone at your company, such as the lawyer who asks for a filing. Name that person by the id your system gives them, withstaff("hr", "U-17") in Python or handles.staff("U-17", "hr") in TypeScript: the conversation stays internal, the agent reads what your team may read, and what the person says counts as your company’s word, marked “(team)” on the lines. A conversation with anyone else, or with someone named by phone or e-mail, reads as customer-facing, whatever the key: when in doubt, Niadra tightens. A task with no conversation stays internal.
When the team undoes a correction
Agents retract and correct facts throughfeedback(); agents never undo what the company retracted. If a retraction or a correction was a mistake, a person with the security role undoes it with POST /v1/facts/{fact_id}/restore: the fact comes back as it was, with the value, validity, evidence and confidence it had, last confirmed at the time of the restore; the correction that replaced it is retracted and gets the inverse supersedes edge; the slot settles again over the confirmed rows only; the history of the fact keeps every step. The route answers 202 and becomes a feedback.restore_fact event of the governance source, which memory applies within seconds, with an admin receipt (memory.restore_fact); the fact.restored webhook tells the subscribed endpoints, next to fact.added and fact.retracted. A fact an erasure took no longer exists: the route answers 404, because only the events of the customer hold a fact and the feedback mentions of the company never do. It refuses with 409, at once and again when memory applies it: a fact that is not retracted, one that came through an unconfirmed link, one the consolidation merged into another and a correction that the restore of the original fact undid (undone: correct the fact again). The next context of any agent carries the item again.
Delta for recurring work
Internal agents often revisit the same customers. Ask withdelta=True (delta: true) and the answer carries only what changed since this source last read in the same task; reads without a task_id share one base. “What changed since the last time YOU looked” costs tens of tokens.
Next steps
Systems, objects and actions
objects, derived state and actions in depth.
Webhooks from your systems
how
invoice.credited gets in.Voice agents
the call that knows about the credit.
Context use
how the action counts as use of the context.

