Skip to content

Last reviewed: 2026-08-01

Accounting Import Run Contract

Canonical object: AccountingImportRun

Canonical payload object: AccountingImportPayload

Purpose: - preserve one authorized, reviewable accounting-file intake attempt before transaction parsing or workflow routing; - preserve the exact accepted source bytes and intake context; - detect exact intake replay without treating file identity as transaction-level idempotency.

AccountingImportRun required fields: - id - company id - actor id - source system - profile key - profile version - source file name - media type - payload byte length - payload hash - intake identity hash - BooksPlus acceptance time - status - created timestamp - updated timestamp

AccountingImportRun optional fields: - default currency - machine identity - correlation id

AccountingImportPayload required fields: - import run id - exact payload bytes - byte length - content hash - media type

Allowed statuses: - received - parsed - held_for_review - completed - rejected

Slice 1 intake result values: - created - exact_replay

Protected actions: - accounting_import_run.stage

Rules: - Import-run identity is scoped by company. - Staging requires company and actor context, ordinary authorization, and an append-only audit event. - accounting_import_run.stage does not require a reason or step-up confirmation. - BooksPlus stamps acceptance time at the application boundary. - Required text values are trimmed and must not be blank. - Optional default currency, when supplied, is a three-letter uppercase ISO 4217 code. - Payload bytes must be nonempty and must not exceed the application-supplied safety limit. - Payload hash is the lowercase hexadecimal SHA-256 hash of the exact accepted bytes. - Intake identity hash is the lowercase hexadecimal SHA-256 hash of a deterministic, length-delimited representation of company id, normalized source system, normalized profile key, normalized profile version, payload hash, and normalized default currency with an explicit null marker. - Actor, file name, media type, acceptance time, machine identity, and correlation id do not affect exact-replay identity. - Exact intake identity is unique by company and intake identity hash. - Exact replay returns the existing run with result exact_replay and does not duplicate payload storage. - A linked new replay attempt is created only when a later accepted audit policy requires it. - Exact file replay is distinct from transaction-level idempotency. Later parsing and workflow intake must still evaluate source-event identity and normalized meaning. - Slice 1 creates runs only in received status. Later slices own transitions beyond received. - Authorization denial and validation or storage failure do not create a persisted import run. - A run header and payload are persisted atomically. - Payload bytes are immutable after staging. - Import-run headers may be listed without loading payload bytes. - An import run is intake and review history. It is not Source Document identity, a Summary Accounting batch, a journal entry, or formal report truth. - Staging must not parse transaction rows, classify workflows, create Source Documents or Summary Accounting batches, prepare journal entries, or create ledger effects.

Audit rules: - audit target type is accounting_import_run; - audit target id is the durable import-run id; - creating a run emits a succeeded event; - exact replay emits a succeeded event whose reason identifies the replay; - denied authorization emits a denied event; - validated intake that cannot be persisted emits a failed event; - audit events preserve company, actor, action, target, result, and correlation context when supplied; - audit reason text must not include raw payload contents.

Persistence expectations: - PostgreSQL stores run headers separately from the one-to-one immutable payload row; - the payload table uses import-run id as both primary key and foreign key; - deleting a run through ordinary application behavior is not supported; - database uniqueness enforces concurrent exact-replay identity; - header and payload insertion use one database transaction.

Validation expectations: - ids are nonempty; - required strings are nonblank after normalization; - acceptance, created, and updated timestamps are present; - updated timestamp is not before created timestamp; - payload byte length matches the exact payload; - payload and intake hashes match their canonical calculations; - optional currency matches ^[A-Z]{3}$; - persisted status and result values use the snake_case contract values above.

Related truth: - accounting-import-candidate.contract.md - ../accounting/summary-accounting.md - security/audit-event-contract.md - company.contract.md - ../decisions/accepted/0007-provider-agnostic-import-boundaries.md - ../decisions/accepted/0022-reviewable-accounting-file-intake.md - company-conversion-run.contract.md