XBRL filing status machine
An XBRL filing is one ACRA filing for a single client + period (e.g. ACME's period ending 31 Dec 2024). It moves through eight states. The taxonomy version is pinned at creation and is immutable.
What each state means
| State | Meaning | Lock semantics |
|---|---|---|
DRAFT | Filing created. Period, entry point, entity type, taxonomy version captured. No documents yet | Header editable; no line items or mappings |
DOCUMENTS_INGESTED | DOCX/PDF parsed; XbrlLineItem rows inserted with (statement, label, valueCurrent, valuePrior) | Line items can be edited; mapping suggestions about to fire |
MAPPING_IN_PROGRESS | Suggestion engine has produced XbrlTagMapping rows (all with confirmedById = NULL) | Staff confirms or overrides each mapping; new synonyms may be added to the shared library |
VALIDATION_PASSED | The 144-rule validation engine ran with no severity=ERROR failures | Export becomes available — but ONLY if every mapping is also confirmed (separate gate); reverting any confirmation drops back to MAPPING_IN_PROGRESS |
VALIDATION_FAILED | At least one severity=ERROR rule failed | Export hard-blocked. Staff fixes mappings, re-runs validation |
EXPORTED | BizFinx XLSX or XBRL XML produced. Artifact persisted to S3, link in the filing detail page | Filing can be marked filed, or back-routed to mapping for further edits |
FILED | Staff has marked the filing as accepted by ACRA. ACRA filing reference + filed-at timestamp captured | Sealed for editing; archive is the only forward path |
ARCHIVED | Filing closed | Sealed; no further changes |
The export gate
VALIDATION_PASSED is necessary but not sufficient for export. The gate (in packages/xbrl/src/export-gate.ts) checks all of:
- The filing has at least one line item.
- Validation has been run at least once.
- No
XbrlValidationResultrow hasseverity = ERRORANDpassed = false. - No
XbrlTagMappingrow hasconfirmedById IS NULL.
A failure of any check raises XbrlExportBlockedError, which the API translates to HTTP 422 with a typed reason (NO_LINE_ITEMS, NO_VALIDATION_RUN, VALIDATION_ERROR_PRESENT, UNCONFIRMED_TAG_MAPPING). There is no override path — these are the cursorrules non-negotiables.
Why VALIDATION_PASSED can return to MAPPING_IN_PROGRESS
A reviewer may notice an incorrect confirmed mapping after validation passed. Reverting that confirmation is allowed — it returns the filing to MAPPING_IN_PROGRESS and forces a re-validation before any export becomes possible again. This keeps the gate honest.
Why MARK_XBRL_FILED is restricted
EXPORTED → FILED records the regulator-facing acknowledgement (ACRA filing reference). Only XBRL_REVIEWER and PLATFORM_ADMIN hold the MARK_XBRL_FILED action — even Senior Accountants who can do everything else short of filing. The boundary deliberately matches the human accountability boundary: whoever marks the filing is the one taking responsibility with the regulator.
Where these transitions happen
| Transition | Triggered by |
|---|---|
DRAFT → DOCUMENTS_INGESTED | ingest-fs-document and extract-line-items worker handlers complete |
DOCUMENTS_INGESTED → MAPPING_IN_PROGRESS | suggest-tag-mappings handler |
MAPPING_IN_PROGRESS → VALIDATION_PASSED / _FAILED | run-xbrl-validation handler outcome |
VALIDATION_FAILED → MAPPING_IN_PROGRESS | Implicit on the next mapping change (no explicit transition needed) |
VALIDATION_PASSED → EXPORTED | generate-bizfinx-xlsx or generate-xbrl-xml handler succeeds (gated) |
EXPORTED → FILED | POST /ops/xbrl/filings/:id/mark-filed (XBRL Reviewer / Platform Admin only) |
FILED → ARCHIVED | Staff-triggered archive |
Implementation
State transitions live in packages/xbrl/src/status-transitions.ts, enforced by canTransitionXbrlFiling(from, to). The valid set per current state is queryable via getNextXbrlFilingStatuses(from) for UI rendering.
Related
- FS engagement status machine — the upstream engagement that may feed this filing
- Architecture — XBRL & FS integration — full design rationale, including the five non-negotiable rules