Skip to content

X-03 · Confirm tag mappings

SOP: SOP_XBRL_Filing.md §6 / Step 3.0Actors: XBRL Preparer (xbrl-preparer@spade.local) — holds CONFIRM_TAG_MAPPING. Synonym-save requires ADD_MAPPING_SYNONYM (Reviewer / Senior / Admin). Pre-state: Filing at MAPPING_IN_PROGRESS with XbrlTagMapping rows, all unconfirmed (or auto-confirmed where Phase 3 cross-product applied). Post-state: Every XbrlLineItem has an XbrlTagMapping with confirmedById != NULL and confirmedAt set. Filing is ready for validation.

0. Prerequisites

  • Filing at MAPPING_IN_PROGRESS (see X-02 or X-02b).

1. Steps

1.1 Walk the mappings UI

Open the Mappings tab. Master-detail layout:

  • Left pane — list of XbrlLineItem rows. Filter by statement (balance_sheet, income_statement, cash_flow, equity_changes, notes) and by confirmation status (unconfirmed / confirmed). Each row shows source page + line + the current elementId suggestion + a confidence chip.
  • Right pane — element-confirmation panel for the selected line item. Shows the current top suggestion, the alternatives[] list, an explanation, and an element search box (filtered by entry point + statement section).

1.2 Confirm a row (top suggestion)

http
POST /ops/xbrl/filings/<filingId>/mappings/<lineItemId>
Content-Type: application/json
Authorization: Bearer <xbrl-preparer-jwt>

{ "elementId": "sg-as_TotalAssets" }

The handler:

  1. Asserts CONFIRM_TAG_MAPPING.
  2. Asserts elementId exists in the pinned taxonomyVersion via TaxonomyLookup. (Rule 1: only access elements through the loader.)
  3. Updates the XbrlTagMapping row: elementId set, confirmedById = <staff user>, confirmedAt = now(), confidence = MANUAL.
  4. Emits AuditEvent xbrl.mapping.confirmed.

1.3 Save as synonym (reviewer / senior / admin only)

If the row's label is canonical enough to be worth saving for future filings:

http
POST /ops/xbrl/filings/<filingId>/mappings/<lineItemId>
Content-Type: application/json
Authorization: Bearer <xbrl-reviewer-jwt>

{ "elementId": "sg-as_TotalAssets", "saveAsSynonym": true }

Additional handler steps:

  1. Asserts ADD_MAPPING_SYNONYM (the caller must hold this; XBRL_PREPARER cannot save synonyms).
  2. Appends {label_pattern, target_element_id: elementId, confidence: HIGH} to mapping_library.json.
  3. Emits AuditEvent xbrl.mapping.synonym_added with {label, elementId, staffUserId}.

1.4 Unconfirm a row

http
DELETE /ops/xbrl/filings/<filingId>/mappings/<lineItemId>
Authorization: Bearer <xbrl-preparer-jwt>

Clears confirmedById and confirmedAt. The mapping remains (with the previous elementId as the current suggestion) so the next confirmation is one click. Audit event xbrl.mapping.unconfirmed.

NOTE

Unconfirming a row after the filing reached VALIDATION_PASSED transitions the filing back to MAPPING_IN_PROGRESS. This is by design — the export gate must remain honest.

2. Verification

Database

sql
SELECT count(*) AS total,
       count(*) FILTER (WHERE confirmed_by_id IS NOT NULL) AS confirmed,
       count(*) FILTER (WHERE confirmed_by_id IS NULL)     AS unconfirmed
  FROM xbrl_tag_mappings WHERE xbrl_filing_id = '<filingId>';
-- expect confirmed = total when you're done

Synonym library (when save-as-synonym was used)

bash
git diff packages/xbrl/constitution/mapping_library.json
# expect the new {label_pattern, target_element_id} entry

Audit log

Event typeNotes
xbrl.mapping.confirmedOne per confirmation
xbrl.mapping.unconfirmedOne per unconfirm
xbrl.mapping.synonym_addedOne per save_as_synonym = true; actor + label + elementId in payload

3. Negative & edge cases

  • elementId not in the pinned taxonomy400 Bad Request with reason: "unknown_element". Rule 1 is enforced: there is no path to set an invalid elementId.
  • Caller without CONFIRM_TAG_MAPPING403 Forbidden.
  • saveAsSynonym = true without ADD_MAPPING_SYNONYM403 Forbidden. The confirm itself goes through; the synonym save is the part that's refused. The handler must either succeed on both or fail on both — implementation today fails the whole call to keep the audit trail unambiguous.
  • Two preparers race on the same line item — last write wins. The audit log preserves both attempts. Re-load before confirming a second mapping.
  • Element ID becomes invalid after a constitution update — the row's stored elementId is preserved (history of what was confirmed) but the validation engine flags the filing on the next run.
  • Reverting confirmation after VALIDATION_PASSED — filing returns to MAPPING_IN_PROGRESS. To export, validate again.

Next

Proceed to X-04 · Run validation.

Internal use only — BreezyCorp