talonic_submit_decision_task
Return the decision for a claimed task. The platform verifies three things transactionally before writing anything: the outcome against the task's output_contract, every evidence locator against the run's frozen input package, and the presence of a rationale. On success the task becomes submitted, the run resumes through the app's threshold checks and action layer, and the sealed record names decided_by.type: external_agent. Talonic writes the ledger; the agent never does.
| Parameter | Type | Description |
|---|---|---|
| task_id * | UUID | Claimed task ID. |
| execution_epoch * | integer | Exact epoch from the current claim. |
| outcome * | object | The decision. For a plain contract, the object its JSON Schema validates. For a `verdict_matrix` contract, `{ subjects: [{ subject_key, rule_outcomes, auto?, detail? }] }`. For a `record_set` contract, its fields-and-rows envelope. |
| evidence * | string[] | Provenance locators the decision relied on, copied verbatim from the package (or `db:` / `ref:` locators the app holds a read grant on). Up to 10,000 entries of at most 512 characters. An empty array is accepted only when the app allows unevidenced decisions. |
| rationale * | string | A short summary of why — never private chain-of-thought. At most 4,000 characters. |
| confidence | number | Optional confidence from 0 to 1; the app's confidence floor may route a low value to review. |
| service_version | string | Optional build identifier of the deciding service (at most 64 characters); recorded as `decided_by.label`. |
// talonic_submit_decision_task({
// "task_id": "11111111-1111-4111-8111-111111111111",
// "execution_epoch": 1,
// "outcome": { "approve": true },
// "evidence": [
// "dp:pppppppp-pppp-4ppp-8ppp-pppppppppppp:rrrrrrrr-rrrr-4rrr-8rrr-rrrrrrrrrrrr:invoice_total",
// "dp:pppppppp-pppp-4ppp-8ppp-pppppppppppp:rrrrrrrr-rrrr-4rrr-8rrr-rrrrrrrrrrrr:supplier_name"
// ],
// "rationale": "Total matches the purchase order and the supplier is on the approved list.",
// "confidence": 0.93
// })
{
"id": "11111111-1111-4111-8111-111111111111",
"run_id": "22222222-2222-4222-8222-222222222222",
"status": "submitted",
"execution_epoch": 1,
"submitted_at": "2026-09-22T10:02:10.000Z",
"...": "remaining metadata as in the list"
}A refused submission is HTTP 422 with the reason (Decision violates the output contract: …, An evidence block is required …, a locator outside the package, or a malformed matrix envelope), is journaled as rejected, and changes nothing: the task stays claimed under your epoch, so fix the payload and submit again before the lease ends. A stale epoch is HTTP 409. A successful submit is terminal — corrections happen downstream in review, not by a second submit.
outcome.summary and the rationale is one line.