---
id: CAP-ACC-REC-009
title: Allocate settlement money to one explanation
feature: FEAT-ACC-REC-02
product_area: accounting
module: reconciliation
revision: 2
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - 'react-console acceptance inventory CAP-ACC-REC-004 (claims, releases and authoritative acceptance)'
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - >-
    services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§2: claims, releases, concurrency by
    version)
  - 'services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D6 (architecture §3.4 U2, U3, U7)'
  - >-
    services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold;
    INV-02, INV-05, INV-07, INV-19)
purpose: Preparers need selections that remain coherent under concurrent work.
outcomes:
  - Allocations prevent two explanations from using one effect.
  - Committed holdings determine the difference.
  - Version checks protect concurrent preparation.
concepts:
  - CON-ACC-REC-003
  - CON-ACC-REC-002
actors:
  - ACT-ACC-017
  - ACT-ACC-018
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: accounting.reconciliation-batches.update
    where_checked: api
    scope: tenant
  - key: accounting.reconciliation-batches.update
    where_checked: console
    scope: tenant
rules:
  - id: BR-CAP-ACC-REC-009-01
    proved_by: [ATS-ACC-REC-009-01, TST-ACC-REC-059]
    statement: >-
      A claim uses the read version and one to five hundred item references, reporting all ineligible,
      resolved, incompatible or already-held-here items together.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      every problem at once with 400, naming each item;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      an item already claimed in this batch with 400;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      more than 500 items with 400;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#writes
      no claim after the refusals
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (plan approved 2026-10-22 10:40 ET; §2
      scope)
  - id: BR-CAP-ACC-REC-009-02
    proved_by: [ATS-ACC-REC-009-02, TST-ACC-REC-027, TST-ACC-REC-034, TST-ACC-REC-075]
    statement: >-
      An item has only one active claim across draft and finalized reconciliations; competing attempts yield
      one winner and identify the existing holder and preparer to the other.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/reconciliation-batches/claim-concurrency.integration.spec.js#refuses
      the second with 409 item_held naming the first batch and its preparer;
      services-accounting:modules/reconciliation/tests/integration/services/reconciliation-batches/claim-concurrency.integration.spec.js#lets
      the first claim succeed;
      services-accounting:modules/reconciliation/tests/integration/services/reconciliation-batches/claim-concurrency.integration.spec.js#leaves
      exactly one active claim of the item;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      a second draft’s claim of an item another draft holds;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      a draft’s claim of an item a finalized batch holds;
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-matching.e2e.spec.js#refuses a claim
      of an item another batch holds with 409 item_held, naming that batch and its preparer
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold;
      INV-05)
  - id: BR-CAP-ACC-REC-009-03
    proved_by: [ATS-ACC-REC-009-03, ATS-ACC-REC-009-11, ATS-ACC-REC-009-12, ATS-ACC-REC-010-11, TST-ACC-REC-036, TST-ACC-REC-074, TST-ACC-REC-083]
    statement: >-
      Difference equals claimed money minus payout money in integer minor units, yielding Draft with no
      claims, In Progress with a nonzero difference and Balanced with a zero difference while open.
    kind: calculation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-batches.table.integration.spec.js#generates
      the difference as claimed items less payouts, the brief’s sign;
      services-accounting:modules/reconciliation/tests/unit/rules/batch-status.spec.js#is a draft with nothing
      claimed, whatever its difference;
      services-accounting:modules/reconciliation/tests/unit/rules/batch-status.spec.js#is in progress with a
      claim and a difference short of zero;
      services-accounting:modules/reconciliation/tests/unit/rules/batch-status.spec.js#is balanced with a
      claim and a difference of exactly zero;
      services-accounting:modules/reconciliation/tests/integration/services/reconciliation-batches/brief-example.integration.spec.js#is
      in progress once the 42 captures and the refund are claimed, 27500 over the payout
    origin: 'services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D6 (architecture §3.4 U7)'
    examples:
      positive: '43 items of 10,000.00 against 9,725.00 read +275.00, in progress.'
      negative: A balanced reconciliation is not finalized.
  - id: BR-CAP-ACC-REC-009-04
    proved_by: [ATS-ACC-REC-008-12, ATS-ACC-REC-009-04, TST-ACC-REC-027, TST-ACC-REC-059]
    statement: >-
      Claims preserve matching strength, explanation, source batch and claimant; each claim or release
      operation advances version once and writes audit history.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#stores
      the tier and the reasons the ranking gives each claim, and its operational batch;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#balances
      the batch with the two claims, one version on;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#records
      batch.items-claimed with the ids, the amount and the versions;
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-matching.e2e.spec.js#stores each
      claim with its tier, its explanation, its operational batch and who claimed it
    origin: none
  - id: BR-CAP-ACC-REC-009-05
    proved_by: [ATS-ACC-REC-009-05, TST-ACC-REC-059]
    statement: >-
      Release removes money from current totals but keeps the claim with release time, actor and reason,
      freeing the item for reuse; manual entries use removal instead.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#keeps
      the released claim as history, with its time, actor and reason;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#takes
      the released claim out of the totals, one version on;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#lets
      the released item be claimed again;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      to release an item the batch does not claim with 400;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      to release a manual item as a claim with 400
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (plan approved 2026-10-22 10:40 ET; §2
      scope)
  - id: BR-CAP-ACC-REC-009-06
    proved_by: [ATS-ACC-REC-009-06, TST-ACC-REC-059]
    statement: >-
      Authoritative acceptance claims the processor-linked payout-reference and settlement-grouping candidates
      together; repeating it with no new candidate preserves the version.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#claims
      the tier 1 and tier 3 candidates and nothing else;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#changes
      the totals and the version in the same command;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#claims
      nothing more when accepted again, leaving the version as it was
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D6 (architecture §3.4 U3: Accept All covers
      authoritative matches only)
  - id: BR-CAP-ACC-REC-009-07
    proved_by: [ATS-ACC-REC-009-07, TST-ACC-REC-027, TST-ACC-REC-034, TST-ACC-REC-059]
    statement: Claims change only an open reconciliation at its current version; stale edits fail.
    kind: validation
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      a claim in a batch that is not open with 409 batch-not-open;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-allocations.integration.spec.js#refuses
      a claim at a version that is not the batch’s with 409 StaleObject;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      a claim into a finalized batch;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      the release of a finalized batch’s claim;
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-matching.e2e.spec.js#refuses a claim
      at a version already moved on with 409
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold;
      INV-08)
  - id: BR-CAP-ACC-REC-009-08
    proved_by: [ATS-ACC-REC-009-08, TST-ACC-REC-034, TST-ACC-REC-036]
    statement: >-
      A claim covers the complete item and preserves one unit, merchant and currency between item and
      reconciliation.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      a claim of part of an item (RHF35);
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      an item of another merchant account and currency;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      an item of another business unit;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-batches.table.integration.spec.js#refuses
      a 10,001st claim
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold;
      INV-02)
  - id: BR-CAP-ACC-REC-009-09
    proved_by: [ATS-ACC-REC-009-08, TST-ACC-REC-034, TST-ACC-REC-036]
    statement: A reconciliation cannot contain more than ten thousand claims.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-batches.table.integration.spec.js#refuses
      a 10,001st claim;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      an item of another merchant account and currency;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      an item of another business unit;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-allocations.table.integration.spec.js#refuses
      a claim of part of an item (RHF35)
    origin: >-
      services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold;
      INV-19)
  - id: BR-CAP-ACC-REC-009-10
    proved_by: [ATS-ACC-REC-009-09, TST-ACC-REC-027]
    statement: >-
      Update permission governs claim, release and authoritative acceptance; read-only callers cannot use
      them.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-matching.e2e.spec.js#refuses the
      reader a claim with 403
    origin: 'services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§2: permissions)'
  - id: BR-CAP-ACC-REC-009-11
    proved_by: []
    statement: >-
      Save Draft sends only differences from the persisted draft, processing releases and removals before new
      claims and manual entries.
    kind: policy
    enforced_at:
      - console
    must_prove: false
    provenance: test
    source: >-
      react-console:lib/accounting/reconciliation/adapter.test.ts#releases and removes before it claims and
      adds, and sends only what differs
    origin: none
scenarios:
  - id: SC-CAP-ACC-REC-009-01
    given: The sample draft has forty-three candidates totaling ten thousand dollars.
    when: Claim those effects.
    then: Difference is positive two hundred seventy-five dollars and status is In Progress.
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-scenario.e2e.spec.js#step 5: claims
      the 43 items, 27500 over the payout (claimed − payout, INV-07)
  - id: SC-CAP-ACC-REC-009-02
    given: Two captures carry the deposit’s processor reference.
    when: Accept authoritative matches.
    then: Both receive the strongest matching rank and balance the explanation.
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-matching.e2e.spec.js#claims the two
      captures carrying PX-1083 at tier 1, balancing RB-10001
edge_cases:
  - id: SC-CAP-ACC-REC-009-03
    given: Two open drafts compete for one settlement item.
    when: Claim concurrently.
    then: One allocation succeeds and the other reports its holder.
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/reconciliation-batches/claim-concurrency.integration.spec.js#leaves
      exactly one active claim of the item
constraints: []
depends_on:
  - CAP-ACC-REC-008
related:
  - CAP-ACC-REC-010
  - CAP-ACC-REC-011
journeys:
  - JNY-ACC-REC-001
open_questions: []
evidence:
  - >-
    Examined supporting service material: matching.routes.ts (claimReconciliationItems,
    releaseReconciliationItems, acceptAuthoritativeCandidates), matching.schemas.ts,
    services/persistence/reconciliation-allocations.ts, reconciliation-batch-totals.ts, rules/batch-status.ts;
    db/reconciliation-batch-links.table.ts, reconciliation-batches.table.ts; tests integration
    reconciliation-allocations*, claim-concurrency, brief-example, db allocations and batches table specs,
    unit/rules/batch-status.spec.js, e2e/reconciliation-matching.e2e.spec.js.
  - >-
    Examined supporting console material: lib/accounting/reconciliation/adapter.ts (planSync), store.tsx
    (syncDraft), adapter.test.ts; components/accounting/reconciliation/workspace/matching.tsx, summary.tsx.
controls: [TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-DAT-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005]
exercised_by: [FAS-ACC-REC-02-01, FAS-ACC-REC-02-02, FAS-ACC-REC-02-03, FAS-ACC-REC-02-04, FAS-ACC-REC-02-05]
suites: [TST-ACC-REC-027, TST-ACC-REC-034, TST-ACC-REC-036, TST-ACC-REC-059, TST-ACC-REC-074, TST-ACC-REC-075, TST-ACC-REC-083]
---

# Allocate settlement money to one explanation

## Purpose

Preparers need selections that remain coherent under concurrent work.

## How It Works

A preparer chooses the settlement effects that belong to the deposit. Rhythm checks the item set and the current draft before committing allocations. Claims retain the evidence behind selection, and release preserves the earlier allocation as history. The console saves differences in an order that frees obsolete holdings before adding new ones. Another holder or stale version prevents an unsafe update.

## Relationships

Draft creation supplies the workspace, manual entries add processor adjustments and finalization approves the complete allocation.
