Skip to main content

Operating an App

An app's detail page is its value surface — it answers "what did the app decide, and what happens next", not "how is it wired". The centerpiece is the verdict matrix: one row per subject (each load, invoice, or case the selected run decided), one column per rule, each cell showing that rule's outcome for that subject — passed, failed, indeterminate, or not applicable. A run selector switches between recent runs, filters narrow the matrix to failing or non-auto subjects, and the matrix renders from the manifest alone even before the first run, so a new app looks like itself from minute zero.

Above the matrix, the operating strip compresses the selected run into one line of chips: verdict counts (how many approved, how many held), action counts, inconclusive and not-applicable cells, and the app's own headline metrics — every number a straight render of the run ledger, not a client-side recount. Clicking any matrix cell opens the evidence drawer: the rule's plain-language sentence, why this subject passed or failed it, and the provenance locators behind the values compared — down to the source document page when one exists.

Everything about wiring lives one click away behind Configure, organized as the four questions an operator asks. Data: which sources the app reads (its input bindings and resource grants, with pickers over your real data products and reference tables). Logic: the rule cards in plain language — add a sentence, let the compiler ground it in the app's bound fields, and cards that cannot be grounded stay visibly pending with the reason rather than silently deciding. Actions: what the app may execute, plus thresholds like a confidence floor or an amount ceiling that routes big decisions to human approval. Access: connected clients (which API keys may read or operate the app, for your own agents) and a copy-ready MCP config snippet.

Editing is language-first here too: describe a change — "raise the tolerance to 150 units" — and the platform proposes typed edit operations with a preview of the manifest after the change; you apply them explicitly. In the current UI, saving logic publishes immediately: rules take effect on the next run, with versions appending under the hood so the ledger always names the exact version that decided each run. Before saving a risky change, the publish impact panel replays the draft and the live version over the same recent history and shows which subjects would flip verdict and how each rule's pass/fail footprint moves — an empty flip list is your strongest green light.

Enabling an app that executes actions on external systems is an owner decision — the platform requires a workspace owner and names the consequences. Disabling is deliberately lighter: the kill switch is one click at the operate tier, because stopping an app must always be easier than starting it.

Acceptance sets give the app a machine-checkable definition of done: label the expected verdict for known subjects ("L-2026-0851 must fail — rate mismatch above 2% never auto-bills"), set a tolerance, and check any run against the labels. The check is a pure ledger comparison — no model involved — so it is free, instant, and repeatable: the loop of editing logic, dry-running, and re-checking acceptance is how you iterate an app toward trustworthy before it ever touches live billing.

The acceptance loop via API
# Dry-run: full trace, zero side effects (works even while disabled)
curl -s -X POST "https://api.talonic.com/v1/apps/$APP_ID/runs?dry_run=true" \
  -H "Authorization: Bearer tlnc_your_api_key" -d '{}'

# Score the run against the labeled expectations
curl -s https://api.talonic.com/v1/apps/$APP_ID/acceptance/check \
  -H "Authorization: Bearer tlnc_your_api_key"
# → { "evaluated": 12, "matched": 12, "score": 1, "tolerance": 0, "pass": true, ... }
Publish impact — what a draft would change
{
  "runsCompared": 42,
  "flips": [
    { "runId": "8c41f3aa-…", "subjectKey": "L-2026-0851", "from": "failed", "to": "passed" }
  ],
  "ruleDeltas": [
    { "ruleId": "quantity-tolerance",
      "name": "Hold any load whose quantity exceeds 150 units.",
      "passesBefore": 198, "passesAfter": 205, "failsBefore": 9, "failsAfter": 2 }
  ],
  "summary": { "totalSubjects": 214, "flippedSubjects": 1 }
}

Frequently asked questions

What do the four cell states in the verdict matrix mean?+
Passed: the rule held for this subject. Failed: it did not — the reason and evidence are in the cell's drawer. Indeterminate: the rule could not be decided from the data (a missing field, an unresolved fuzzy comparison); indeterminate never silently passes. Not applicable: the rule's applies-to filter excluded this subject.
Why is a subject not auto-approved even though every rule passed?+
Auto requires substance, not just absence of failure: enough substantive rules must have genuinely passed. A subject whose passes are vacuous — for example, nothing on either side of a reconciliation — rolls up as passed but stays non-auto, so an empty comparison can never auto-bill.
How do I test a logic change safely?+
Three tools compose: the publish impact panel diffs draft vs live over the same recent history (which subjects flip, which rules move); dry runs execute the full engine with zero side effects, even on a disabled app; and the acceptance check scores any run against your labeled expectations. Green on all three before you save a money-touching change.
Can my own agent operate an app instead of the UI?+
Yes — that is the design. The UI is a client of the public /v1/apps API with no private capabilities, and every enabled app is also published as an MCP tool. Grant an API key read or operate on the app under Configure → Access, copy the MCP config snippet, and your agent sees and does what you see and do.