Who this runbook is for
Controllers, FP&A leads, finance ops engineers, and audit reviewers running an accounting close where AI agents (or humans, or scheduled jobs) interact with the GL, vendor master, sub-ledgers, or close checklists. The runbook reads top-to-bottom in three passes:- Operational pass — what each step does to your close calendar.
- Wire pass — the exact API requests / responses behind each step.
- Evidence pass — what the auditor sees when they ask “show me every agent action in the period.”
Scenarios this runbook supports
Each scenario maps to a runnable example inatlasent-examples/accounting-close/.
The flow
Vocabulary
1. Register the action class
A close-cycle org typically registers:journal_entry.approve— author / approve a JE before it postsjournal_entry.post— write the JE to the GL (separate from approval; can be in a locked period)reconciliation.certify— sign off on a sub-ledger reconciliationaccount_balance.adjust— manual adjustment to an account balancevendor_master.update— change vendor data; high-risk fields gated separatelysubledger.lock/period.close— lock the period for writeperiod.emergency_override— controlled, time-bound unlock with multi-party approval
POST /v1/action-classes.
2. Evaluate the proposed action
The agent or operator’s proposed action is sent to/v1/evaluate
before any state changes in your system of record:
Example
allow response:
deny carries deny_code (short machine code) and deny_reason
(operator-readable). A hold or escalate returns no permit; the
caller must wait for the human reviewer or approval signal to
release the decision.
The audit row for this decision is written before the response
returns. Denials and holds are part of the proof chain — they
cannot be omitted, edited, or reordered without invalidating the
chain.
3. Verify the permit before execution
Before changing state in your subledger, verify the permit. This catches clock skew, replay, and revocation in the window between issue and execute:200 ⇒ still valid. 410 ⇒ expired or consumed; do not proceed.
In the SDKs:
4. Execute the action
This is the only step AtlaSent does not perform. Your system of record applies the journal entry, posts the reconciliation, locks the subledger, mutates the vendor master. Capture the executed payload’s hash (the same canonical JSON-Canonicalization-Scheme hash described in Proof verification). You’ll hand it back to consume.5. Consume the permit
Single call. Binds the executed payload to the issued permit:payload_hash returns 409 payload_binding_mismatch. Use this as
your “someone changed the JE between approval and posting” signal.
On success, the linked proof row is updated:
execution_status→executedexecution_hash→ the supplied payload hashexecuted_at→ server time
audit_hash and signature were written at evaluate
time and are unchanged.
6. Replay & audit visibility
Two surfaces:- Console. Every decision is visible at
/auditand on the action’s detail page, with the full canonical decision object, the matched policy version, and the linked permit and execution. - Programmatic.
GET /v1/proofs/exportreturns a self-contained bundle that an auditor can verify offline using the public keys embedded in the bundle. See Proof verification for the algorithm.
GET /v1/decisions/{id} returns the canonical
decision object with its proof linkage.
Reversibility, overrides, and tamper-evident evidence
Three principles every controller and audit reviewer should internalise:Permits are single-use and TTL-bound
A permit authorises one execution, within a named time window, against a specific resource. Replays return410. Expired
permits cannot be revived. There is no “save the permit for later”
path; if the action doesn’t run inside the TTL, the operator must
re-evaluate.
Locked periods stay locked unless a controlled override is issued
The period lock, the
PERIOD_LOCKED denial, and the automatic re-lock
described in this section are implemented by the reference example
scripts together with your policy and system of record. They are not a
built-in AtlaSent runtime feature. AtlaSent evaluates each request,
issues and verifies the permit, and records the outcome in the audit
chain.period.close writes a lock row. Once the lock is in place, every
journal_entry.post against that period denies with PERIOD_LOCKED
— including agent attempts, scheduled job attempts, and operator
attempts. There is no “force post” flag.
The only path through is a period.emergency_override, which:
- requires two named approver roles (e.g. CFO + audit committee chair). One human cannot self-approve.
- requires an
audit_reference(e.g. internal-audit ticket ID) on the request body. - requires a
materiality_assessmentin plain language. Stored on the decision row, not in Slack. - issues a permit that is single-use, TTL-bound (typically 60–120 minutes), scoped to a specific JE or set of JEs. The permit cannot be reused for a different JE in the same period.
- after TTL expiry, the example re-locks the period. There is no manual “leave the door open” path.
The audit chain is tamper-evident and offline-verifiable
Every event — denials, holds, the override request, both approvals, the issued permit, the executed JE, the consume, the auto re-lock — is appended to a SHA-256 hash-linked Ed25519-signed chain. An auditor walks the chain offline using only the published public key. Tampering is detectable; omission is detectable; reordering is detectable. What an auditor cannot do: edit the chain, omit the override request, or claim the period was never unlocked. The full chain of custody is preserved. What an auditor can do: download a self-contained export bundle and verify it years later, with no need to trust AtlaSent’s server at audit time.What close-operations teams get
- Execution-time authorization. Every protected action is evaluated before the ERP / GL is touched. Denied requests never reach the system of record.
- Separation of duties. Roles + named approvers are policy primitives, not conventions. An AP clerk cannot do a controller’s job; one controller cannot self-approve.
- Deterministic gate. Same inputs, same policy version, same decision. Replayable for diligence.
- Single-use, TTL-bound permits. Replays are rejected, not retried. Expired permits cannot be revived.
- Tamper-evident audit. The proof chain detects after-the-fact edits, reorderings, or omissions without trusting AtlaSent at audit time.
- Operator-shaped escalation.
holdandescalateroute to a reviewer queue with the full action context and the policy reason. - Reversibility on overrides. Override permits are scoped and time-bound; the reference example re-locks the period when the TTL elapses.
- Controlled overrides with tamper-evident evidence. Overrides do not hide the original deny. The audit chain shows lock → unlock-under- override → re-lock with the full approver provenance.
- Offline replay. An exported bundle is valid evidence years later with only the public key.
Worked timeline
Worked example — journal entry approval
A 100,000 delegation threshold.Worked example — vendor master mutation
AP clerk and controller both attempt to change the bank routing number on vendor V-7821. Bank routing is a high-risk field (separation-of-duties policy applies).Worked example — emergency override of a locked period
Q1 2026 was closed on May 5. On May 10, internal audit discovers a $50,000 misclassification. The reclass JE has to post inside the already-locked period.Worked example — period close
End-of-month / end-of-quarter close.journal_entry.post
against 2026-04 denies with PERIOD_LOCKED. To post inside the locked period, the
operator must use the emergency-override path (above).
Run this scenario:
Related
- Examples:
atlasent-examples/accounting-close/— runnable scripts for every scenario above - Quickstart → Evaluate an action
- Quickstart → Verify a permit
- Proof verification
- Audit chain
- Glossary