Most feature checklists for custom ERP development read like a sales brochure: "real-time dashboards," "mobile-first UX," "AI-powered insights." None of those survive contact with an auditor. The questions a controller gets asked in a SOC 1 walkthrough are narrower and older: who posted this journal, under what authority, against which open period, with what evidence it reconciles to the bank. If the system cannot answer that in minutes, it does not matter how modern the front end looks.
This piece lists the features a custom build (or a heavily configured platform pretending to be one) has to ship with before it earns a place inside the close. The bar is the same whether the build is in-house, outsourced, or an agentic ERP: the ledger has to be defensible, the controls have to be enforced in the schema rather than the UI, and the automation layer has to be answerable. Everything below is scored against that bar.
The Deterministic Ledger Core
The non-negotiable foundation is a double-entry ledger that enforces balance at the database layer, not at the application layer. Debits equal credits as a constraint, not a convention. Journals are typed (standard, recurring, adjusting, reversing, intercompany), each with a required source document reference. Posting is transactional: a journal either lands in full or not at all. There is no partial state the UI can hide.
What disqualifies a candidate here is a schema that treats the GL as a reporting layer over operational tables. If the ledger is derived from invoices, payments and expense claims rather than being the system of record, every reconciliation becomes a question about which upstream table was true at which moment. Agentic systems make this worse, not better: an AI that writes directly into balances leaves no deterministic artifact to re-run. The right pattern, covered in detail in what an agent cannot do, is for agents to propose journals that the ledger validates and posts, with the agent never holding write authority on the balances themselves.
An Immutable, Append-Only Audit Log
Separate from the ledger, the system needs a dedicated audit log that captures every state-changing event: journal posted, approval granted, vendor master edited, period locked, user permission changed. The log is append-only, enforced at the storage layer, with hash chaining so a deleted row is detectable. SOX Section 404 expects companies to demonstrate internal controls and keep verifiable logs for roughly seven years; a log that the application can rewrite does not meet that bar regardless of what the retention policy claims.
Each record needs the actor (human or agent), the credential used, the before and after values, the originating request ID, and a cryptographic hash of the payload. The reason to insist on actor identity down to the agent instance is practical: IBM's 2025 Cost of a Data Breach Report found that 97% of AI-related breaches occurred at organizations without proper AI access controls. If an AP agent can act, the log has to record which agent, under which policy version, at which time.
A Period-Lock Engine That Blocks Writes
Closing a period has to mean something structural. The period-lock engine marks a period as closed and refuses any posting dated into it, with narrow, logged exceptions for authorized reopens. The lock is enforced at the posting API, not at the report level. Reports that look clean while late journals still trickle into the prior month are the single most common cause of restated management accounts.
The engine needs three capabilities: soft-close (block ordinary posting, allow adjustments by a named role), hard-close (block all posting including adjustments), and reopen (require dual authorization, write a reason code, and surface a diff on the next trial balance). Agent authority has to respect the lock on the same footing as a human user. An AP agent that can backdate an invoice into a closed period is not an automation feature; it is an audit finding waiting to be written.
Reconciliation as a First-Class Subledger
Reconciliation cannot be a spreadsheet exercise bolted on at month-end. The system needs a subledger of reconciliation items: each bank line, each sub-ledger entry, each unmatched exception carried with age, owner, and proposed treatment. Matches are proposed by rule or by agent, approved by a human (or auto-approved below a documented threshold), and posted as journals the ledger validates like any other.
The reason this feature belongs on a must-have list rather than a nice-to-have is covered in closing faster is mostly a reconciliation problem: close duration is almost entirely a function of how long unmatched items sit before someone acts on them. Daily reconciliation proof, generated as a signed artifact at the end of each business day, converts the close from a two-week forensic exercise into a confirmation of a continuously reconciled state.

An Explicit Approval Graph
Approvals need to be modeled as a graph, not a sequence of if-statements buried in workflow code. Nodes are approvers (users, roles, or agents operating under delegated authority). Edges carry the conditions: amount thresholds, GL account scopes, vendor categories, entity boundaries, segregation-of-duties constraints. The graph is versioned, so a payment approved under last quarter's policy can be traced to the exact rule set that applied at the time.
The graph has to encode the controls an auditor already expects:
- Separation of duties between requester, approver, and poster, enforced in the schema rather than in UI hints
- Threshold escalation with the right ceiling for each role, not a single global number
- Delegation with an expiry and a logged chain of custody
- Agent authority bounded by the same graph, with lower thresholds and tighter scopes than their human counterparts
How to calibrate those agent thresholds is a problem in its own right; the trade-offs are worked through in approval thresholds for an AP agent.
An Event Bus and Idempotent Integrations
Every state change in the ledger emits an event: invoice posted, payment cleared, period closed, journal reversed. Downstream systems (payroll, procurement, revenue recognition, consolidation) subscribe to those events rather than polling tables. The bus is the backbone of the agentic layer, because agents are event-driven consumers: a reconciliation agent wakes on "bank line received," not on a cron.
Integrations into and out of the ledger have to be idempotent. The same bank file replayed twice must not create duplicate journals. The same vendor invoice fetched twice from an email inbox must dedupe on a stable key. Idempotency is a property of the integration contract, not something to handle in retry logic. Related ownership questions, such as who wins a conflict between CRM and ERP on customer master data, are worked through in two-way sync is an ownership decision.
An Agent Authority Registry
If the system includes agents (and most new builds will, whether they are called that or not), their authority has to be registered as data, not as code. The registry lists each agent, its role, the policies it operates under, the thresholds and scopes it is bounded by, the human owner who can revoke it, and the version of its instructions in effect. Every action the agent takes carries a reference to the registry entry that authorized it.
This matters because agent authority is the control auditors do not yet have a template for. Deloitte's work on cloud ERP internal controls frames the general problem: controls have to move with the workload, and the evidence of their operation has to be portable. For agents, that means a registry a controller can read, filter by risk, and change without a deployment. The practical shape of the trade-off between architectures is worth drawing out.
Role-Based Access, Enforced at the Data Layer
Access control has to be modeled on NIST's RBAC definitions: permissions assigned to roles, roles assigned to users, with the ability to express mutual-exclusion constraints (the same person cannot be AP clerk and AP approver). The failure mode to avoid is permissions bolted on at the UI with the API still open. If an agent or a determined user can hit the posting endpoint directly, the UI controls are decorative.
The IBM data on multi-environment breaches is relevant here: 30% of 2025 breaches involved data distributed across multiple environments, at an average cost of $5.05 million. An ERP that spans a primary database, a data warehouse, a reporting layer and an agent runtime has to enforce the same role definitions in every one of those places, or the weakest link decides the control.
What This Looks Like in Practice
A controller evaluating a custom build, a configured platform, or an agentic ERP can run the same checklist against all three. The questions are concrete: can you show me the posting constraint in the schema, the append-only property enforced at the storage layer, the period-lock on the API, the approval graph as versioned data, the agent registry as a queryable table? If the answer to any of those is "the application enforces that," the control is at the wrong layer.
The build-versus-buy conversation changes under this lens. A custom ERP that ships all eight features is defensible but expensive to maintain; a configured legacy platform that ships four of them with middleware is cheaper to buy and more expensive to audit. An agentic ERP that was designed around these primitives from the start is the newest option and the one that requires the most careful reference checking, which is why the reference call questions worth asking matter so much. The right answer depends on the finance team, the regulatory posture, and the appetite for owning the roadmap. The wrong answer is to pick a platform that scores well on dashboards and badly on the eight features above, and to discover the gap at the first SOX walkthrough.
For teams running this evaluation now, a structured free assessment maps the current stack against the same checklist and surfaces where the controls live today. The useful output is not a score. It is a list of which features are enforced in the schema, which are enforced in the application, and which are enforced only by the person who remembers to check.
