ledgers schema alongside the GL — not in ingest.*. Use ntro.subledger from activities or workflow-adjacent code that already holds a data-plane connection.
Opening a handle
@register_type under ntro.subledger.types. Mutation helpers for review workflows live alongside the type (e.g. edit/reject rules) so Temporal-signalled actions can apply domain logic consistently — see UI and Temporal signals.
Core concepts
| Symbol | Purpose |
|---|---|
Row | Pydantic base for subledger rows — standard columns (id, entity_id, period, task_id, status, …). |
SubledgerStatus | Default lifecycle enum; types may specialize. |
SubledgerHandle | Lazy-bound API for query / insert / transitions for one (subledger name, entity, task). |
register_type | Associates a row model with a subledger name at import time. |
Standard column block
EveryRow subclass inherits these columns. Type-specific fields are added on top.
| Column | Type | Purpose |
|---|---|---|
id | UUID | Row PK; auto-generated UUID4 if not supplied. |
entity_id | UUID | Canonical, immutable entity identifier (UUID, not slug). |
period | Period ("YYYY-MM") | Accounting period. |
task_id | UUID | Workflow task that wrote the row (provenance). |
status | SubledgerStatus | Lifecycle marker; types may override the enum. |
source_ref | str | None | Upstream handle (e.g. "event:<uuid>", "doc:<uuid>"). |
validation_errors | list[dict] | None | Populated on rows that failed strict-type validation (NEEDS_ATTENTION flow). |
raw_payload | dict | None | The agent’s submitted dict, captured before validation. |
created_at / updated_at | datetime | Insert / update timestamps. |
Lifecycle — SubledgerStatus
Default lifecycle every platform type uses unless it overrides. Terminal states have no outgoing edges.
NEEDS_ATTENTION is the entry point for rows whose payload failed type-level validation (e.g. an extraction missing vendor). HITL fixes the typed columns and transitions to PENDING. From there the row follows the normal lifecycle.
transition(from_status, to_status) raises IllegalTransitionError on a disallowed move. Idempotent self-transitions (X → X) are also rejected — call sites should check row.status == target first if they want a no-op.
Platform types
Bundled subledger types ship underntro.subledger.types and register at import time. Each carries its own typed columns, validation rules, and propose_for_gl handoff (where applicable).
expenses
ExpenseRow — single expense receipt (vendor, amount, category, VAT). Used by expense-processor.journal_proposals
JournalProposalRow — one HITL-reviewed journal entry awaiting GL commit. Used by nav-monthly-journals.Related
Ingest outcomes & feedback
Earlier stage: ingest schema and feedback envelopes.
UI and Temporal signals
How row edits reach
ntro.subledger via workflows.Accounting capability
GL-facing helpers built on subledger proposals where applicable.
General ledgers
ntro.capabilities.gl — post BillProposal and other resources to the external GL.