Action history
Read outbound action rows for your workspace, filter Outcome-unknown rows awaiting reconcile, and reconcile them.
createKernelClient(...).actionHistory lists and reads action_outbound_request
rows: the outbound units a kernel Action queued, dispatched or is waiting to
reconcile. It answers the question operators could not otherwise answer —
which rows are Outcome unknown, holding a target, and need a decision —
without out-of-band knowledge.
Unlike actionApprovals, this read is scoped to the whole workspace, not to
one ontology: an outbound unit is not itself an ontology object, so there is
no ontology to pick.
The list is newest first. When hasMore is true, pass nextCursor back as
cursor to read the rows created before the last one on the page.
const page = await ontology.actionHistory.list({
status: "outcome_unknown",
});
for (const row of page.items) {
console.log(row.effectId, row.status, row.target, row.canReconcile);
}
const row = await ontology.actionHistory.get({ effectId: page.items[0].effectId });Filters
| Filter | Meaning |
|---|---|
status | One lifecycle status (requested through reconciled_failed, including outcome_unknown). |
target | The exact target the outbound unit is bound to. |
source | The exact destination (link or simulation) the unit dispatches through. |
createdAfter / createdBefore | ISO 8601 bounds on createdAt. |
cursor / limit | Keyset pagination, newest first, bound to the filter and your clearance. |
What a row carries
| Field | Meaning |
|---|---|
effectId | The row's id — the handle action.outbound.reconcile takes. |
status, verificationState | The outbound lifecycle (@scrydon/common/security ACTION_OUTBOX_STATUS) and its delivery verification. |
operation, target, source, destinationMode | What the unit does, against what, through what, and how (simulation or link). |
requestedBy, requestedByCaller | Who asked, and whether that is you. |
parameters, parametersRedacted | The unit's parameters, visible only to the requester or an org admin — withheld wholesale otherwise, not value by value. |
lifecycleHistory | Every status transition the server recorded, append-only. |
canReconcile | True only for an org admin, and only on an Outcome-unknown row. |
Every row carries the marking of the action that admitted it, and is returned only to a reader whose clearance is at or above that marking. A row admitted under an exact-request approval is also held to that approval's marking. A row above your clearance is not returned at all: it is missing from the list, and its detail read is not found, so neither its operation, target, link nor requester is disclosed. Org admins are held to the same rule; being an admin widens what you see of a row you may read, never which rows you may read.
Reconciling an Outcome-unknown row
canReconcile on a row tells you whether you may decide it — never re-derive
this yourself from status alone, since it also requires the org-admin
decision the kernel itself made. When it is true, submit the existing
action.outbound.reconcile built-in:
await ontology.actions.submit({
actionType: "action.outbound.reconcile",
input: {
effectId: row.effectId,
outcome: "succeeded", // or "failed", or "still_unknown"
reason: "confirmed delivery out of band",
},
idempotencyKey: `reconcile-${row.effectId}-succeeded`,
});succeeded and failed move the row to its matching terminal state and
release the hold the row's target was under. still_unknown records the
attempt (it is audited, like every kernel Action) and leaves the row exactly
where it was — another admin may still reconcile it later.