# Frozen Intercompany definition and exact data contract

D30-F04-A03. Root ratified this exact API before code. The14 FX/4 worksheet independent math cases are already frozen. This package follows full FX delivery. Trusted extraction receipts are host inputs, not cryptographic certificates. Root's final adapter binds actual Trial-Balance rows/raw balances and frozen heads.

## API, profile and scalar types

`build_elimination_worksheet(request, member_snapshots, context)` / `buildEliminationWorksheet(request, memberSnapshots, context)`. Pure JSON, no I/O or book mutation. Every key set below is exact. Strict IDs match `[A-Za-z0-9][A-Za-z0-9._:-]{0,63}`. Real YYYY-MM periods/year0001..9999 and UTC millisecond stamps use the FX scalar profile. Raw balance is canonical signed debit−credit string, at most60 magnitude digits; zero only0/no−0. Sequence integers canonical nonnegative≤30digits. Sum outputs can have more digits; no floats, amount tolerance or rounding. Worksheets are not Stage1 journals, so its per-leg/journal-leg-count limits are not misrepresented as consolidated balance limits.

Request exactly `{schema_version,worksheet_id,group_id,period,knowledge_cutoff,basis_id,policy_id,profile,pair_specs}`. Schema `d30-intercompany-elimination-v1`, profile `ifrs10-reciprocal-usd-v1`; IDs strict, K no earlier than last UTC millisecond of the requested month. UTC close convention is a teaching/host profile, not a universal market time. All source bases functionalUSD, common policy/period. No control assessment, partial acquisition/disposal period, investment-entity exception or currency conversion is inferred.

pair_specs array≤256, each exactly `{pair_id,kind,left_position_ref,right_position_ref}`. kind `receivable_payable` expects leftrole receivable/rightrole payable; kind `income_expense` expects leftincome/rightexpense. position_ref exactly `{ledger_id,entity_id,evidence_id,position_id}`. Both scopes are distinct supplied member entities and match their member ledger mapping. Repeated pair ID or reuse of an exact position reference across any specs rejects, not a second elimination. Left/right role orientation is explicit; no automatic swapping or amount-only discovery.

## Context and independent member receipt bindings

Context exactly `{group,member_receipts,accounts}`.

group exactly `{schema_version,group_id,basis_id,policy_id,period,knowledge_cutoff,profile,members,available_at,receipt_ref}`. Schema `d30-consolidation-group-v1`, profile `supplied-controlled-full-period-usd-v1`; IDs/scope/period/K equal request; group.available_at≤K. members array2..16 of exactly `{ledger_id,entity_id}`, unique entity IDs. The host supplies already determined controlled full-period membership and uniform accounting policy basis; this is not an ownership/control algorithm or proof of those assertions.

member_receipts array contains exactly one independent trusted base receipt per declared member. Each is exactly `{schema_version,evidence_id,ledger_id,entity_id,period,currency,basis,knowledge_cutoff,observed_at,head_sequence,receipt_ref}`. Schema `d30-close-source-v1`, currencyUSD, basisfunctional-usd; period/K=request and observed_at≥K; scope matches a supplied member. This registry identifies the current extracted receipt at the chosen K/frozen head. The algorithm must not derive this independent binding from the supplied position array itself. Missing registry member→MISSING_MEMBER_RECEIPT; extra/nonmember scope rejects. No signature, source authenticity or absence of undisclosed journals is established by strings.

accounts array≤2048 seven-field Stage1 records `{account_id,ledger_id,entity_id,currency,account_type,normal_side,status}`. Unique composite(scope,account_id), allowing the same local account_id in different entities. Account enums/normal sides are Stage1's. Each extracted position's mapped account must be USD, same member ledger/entity, and have the type/normal side for its role: receivable asset/debit, payable liability/credit, income income/credit, expense expense/debit. Both active and closed source accounts may have historical balances; worksheet reporting does not post to a closed legal-entity account.

## Supplied immutable member snapshots

Each member_snapshots element has the exact11 base receipt fields above, extended by exactly `{policy_id,available_at,position_count,positions}`. All11 base fields must equal its independently supplied member receipt; source currency/basis/policy/period/K must match this request. available_at is the close extraction receipt, so measurement_at≤available_at≤observed_at and available_at≤K. Missing/future unavailable required member→MISSING_MEMBER_SNAPSHOT/SNAPSHOT_NOT_AVAILABLE, no partial worksheet. Exact duplicate evidence delivery→DUPLICATE_SNAPSHOT; same evidence_id changed content→SNAPSHOT_ID_CONFLICT. Two different evidence IDs for one member cannot choose by input order; reject DUPLICATE_MEMBER_SNAPSHOT. Additional nonmember snapshots reject.

position_count canonical string0..128 equals positions.length; each member≤128 positions. The count/schema check is not authenticity proof: host adapter must extract the complete declared dedicated-counterparty-account slice from the validated Trial Balance. Position exactly `{position_id,account_id,counterparty_entity_id,pair_id,role,raw_balance_minor,position_basis_ref}`. Strict IDs; role one of four above; raw signed≤60digits. position_id unique per member. One whole account may occur only once per member and must be dedicated to that pair/counterparty. The core seven-field catalog does not itself know counterparties: the extracted position's metadata is a trusted accounting assertion, later checked by the host against its dedicated account mapping. Never claim a general aggregate Trial Balance can distinguish several counterparties in one control account. No arbitrary allocation of an account across pair specs.

Validate all supplied snapshot/position/account shapes and bindings before pair arithmetic. Source snapshots remain unchanged. Different snapshots are distinct input evidence; a later correction has a new evidence identity. No historical object is updated in place.

## Pair evaluation and complete bounded worksheet policy

Normalize presentation by pair_id; snapshot/member order by entity_id then ledger_id. IDs order output only, never discover a match. A stale ref evidence_id or missing position gives pair diagnostic STALE_POSITION_REFERENCE/POSITION_NOT_FOUND, no silent fallback. When both found, require source pair_id=specpairid, expected roles and reciprocal counterparty IDs (leftcounterparty=rightentity and vice versa). External counterparty never becomes intragroup merely because amount matches. Wrong identity/roles/counterparty produces an unresolved diagnostic and no amount-based proposal.

Expected normal raw signs: receivable/expense≥0; payable/income≤0. Legitimate contra balances are unsupported by this bounded pair profile, not a reason to reverse a legal book silently. With identity/roles supported, residual=leftraw+rightraw. Nonzero→UNEQUAL_RECIPROCAL_BALANCES, no plug. Zero/zero→ZERO_RECIPROCAL and no legs. Equal nonzero→MATCHED_RECIPROCAL. Reverse both source positions in the consolidation worksheet: positive raw emits credit; negative raw emits debit. Debit leg first then credit. Entity/account/source dimensions remain visible, but this is not one cross-entity Stage1 journal.

All source positions whose counterparty is another supplied member must be covered once by an explicit pair spec. Any unassigned intragroup row blocks final worksheet completeness (UNASSIGNED_INTRAGROUP_POSITION). This prevents an empty/partial pair_specs list from claiming that an otherwise supplied internal slice was eliminated. A row whose counterparty is outside the supplied controlled group remains unassigned with EXTERNAL_COUNTERPARTY and is never eliminated; it does not block the bounded internal worksheet. Self-counterparty is malformed UNSUPPORTED_SELF_COUNTERPARTY.

**All-or-nothing final worksheet:** if any pair is unresolved/unsupported or any internal position unassigned, expose source/pair diagnostics but worksheet:null and rollup:null. Pair results may contain conditional matched legs to explain arithmetic; they are not a final accepted worksheet. A ready worksheet requires all declared pairs matched/zero and all supplied internal positions covered. Structural/coverage failures withhold all diagnostics. No forced suspense/rounding/FX plug. No claim of complete consolidated statements, investment elimination, unrealized profit, tax, NCI or blanket elimination of IAS21 FX differences.

## Exact output contract

Always exactly `{status,code,scope,member_sources,pair_results,unassigned,worksheet,rollup}`.

Structural/coverage failure: status rejected or indeterminate, scope:null,member_sources:[],pair_results:[],unassigned:[],worksheet:null,rollup:null. Indeterminate codes MISSING_MEMBER_RECEIPT,MISSING_MEMBER_SNAPSHOT,SNAPSHOT_NOT_AVAILABLE,GROUP_NOT_AVAILABLE. On complete evaluated evidence with unresolved pairs: statusindeterminate/code WORKSHEET_UNRESOLVED, scope/member_sources/pair_results/unassigned present; worksheet/rollup null. Ready: statusok/code ELIMINATION_WORKSHEET_READY.

scope exactly `{worksheet_id,group_id,period,knowledge_cutoff,currency,basis,basis_id,policy_id}`. member_sources is a detached array of whole supplied current snapshots, canonical order. Source input strings do not prove actual book completeness; host adapter supplies that trust and binding.

Each pair result exactly `{pair_spec,status,code,left_position,right_position,residual_minor,proposed_legs}`. pair_spec detached input; position views null or exactly `{position_ref,position}` with detached exact source fields. status matched/zero/unresolved/unsupported. Code MATCHED_RECIPROCAL,ZERO_RECIPROCAL,STALE_POSITION_REFERENCE,POSITION_NOT_FOUND,PAIR_IDENTITY_MISMATCH,PAIR_ROLE_MISMATCH,COUNTERPARTY_MISMATCH,UNSUPPORTED_POSITION_SIGN,UNEQUAL_RECIPROCAL_BALANCES. Residual null before trustworthy pair identity/roles/signs, otherwise signed string. proposed_legs empty except matched pair's conditional two legs.

Leg exactly `{ledger_id,entity_id,account_id,side,amount_minor,position_ref,pair_id}`; side debit/credit, amount positive magnitude≤60digits, references scoped as above. These are consolidation worksheet legs, never passed as an entity journal by this API. No zero legs. All mutable views detached from inputs AND from each other.

unassigned array entries exactly `{position_ref,reason}`, reason EXTERNAL_COUNTERPARTY or UNASSIGNED_INTRAGROUP_POSITION. Order memberentity/accountposition. All supplied position rows are visible either in paired diagnostics or unassigned; invalid/stale specs do not fabricate a consumed row.

worksheet null or exactly `{worksheet_id,currency,basis,legs,debit_minor,credit_minor,residual_minor}`; legs concatenated canonical pair order/debit-first, debit/credit totals exact strings, residual0. Only a bounded worksheet proposal; no accepted/posting/authorization identity.

rollup null or exactly four entries in role order receivable,payable,income,expense: `{role,combined_before_raw_minor,worksheet_raw_delta_minor,combined_after_raw_minor}`. Sum all supplied position rows by role (including retained external counterparties); worksheet delta uses debitpositive/creditnegative; after=before+delta. These are role totals for the supplied slice, not full financial statements or an overall balanced legal-entity Trial Balance. External rows remain after elimination.

## Strict error order and independent acceptance

Strict request/profile/spec IDs/duplicate reference consumption → context/group/member registry/accounts → all source snapshot shapes/duplicates/current bindings/clocks/positions/catalogrole integrity → missing required sources → pair evaluation → internal coverage → final worksheet/rollup. Main reject codes INVALID_SCHEMA,UNSUPPORTED_SCHEMA,INVALID_IDENTIFIER,INVALID_PERIOD,INVALID_TIMESTAMP,KNOWLEDGE_BEFORE_CLOSE,UNSUPPORTED_PROFILE,INVALID_PAIR_SPEC,DUPLICATE_PAIR_ID,POSITION_REUSED,PAIR_SCOPE_MISMATCH,INVALID_CONTEXT,INVALID_GROUP,GROUP_SCOPE_MISMATCH,INVALID_MEMBER_RECEIPT,INVALID_ACCOUNTS,INVALID_SNAPSHOT,DUPLICATE_SNAPSHOT,SNAPSHOT_ID_CONFLICT,DUPLICATE_MEMBER_SNAPSHOT,SOURCE_RECEIPT_MISMATCH,SOURCE_BASIS_MISMATCH,SNAPSHOT_CLOCK_VIOLATION,INVALID_POSITION_COUNT,INVALID_POSITION,DUPLICATE_POSITION,DUPLICATE_CONTROL_ACCOUNT,INVALID_RAW_BALANCE,ACCOUNT_ROLE_MISMATCH,UNSUPPORTED_SELF_COUNTERPARTY.

Before-code literal oracle: loan+100000/−100000, service−2400/+2400, mismatchresidual100/no legs, zero/no legs; combined matched debits/credits102400. Add independent complete expectations for late receipt, stale identity, omitted internal pair, external retained amount, reused position, role/sign mismatch, source/order permutation and detached views. At least24 synthetic source positions and12 explicit pairs will support the full lab. Root exact freeze preceded implementation and derivatives.


## Extraction freshness and eligibility clarification

Receipt head_sequence means the visible whole-group journal position p at K, not a later validated history head h. A historical p<h cannot attest current close; the host adapter requires p equal to the frozen current close head and exact equality with passed Trial-Balance raw lines. Income/expense roles assert eligible reciprocal intragroup charge positions from a trusted dedicated-account mapping; broad account_type alone does not establish economic eligibility or authorize elimination of FX-effect accounts. The reporting interval/closing policy must align across members; a cumulative closing account balance is not automatically a current-month flow. Returned source positions are sorted by position_id in detached copies for delivery invariance, while input arrays remain unchanged.
