Skip to content

CAP-ACC-REC-014Carry reconciliation accounting through operational posting

Markdown

CAP-ACC-REC-014

Carry reconciliation accounting through operational posting

Markdown
  • DocumentDraft
  • Product intentConfirmed
  • ImplementationObserved

KindCapabilityProduct areaAccountingModuleReconciliationRevision2

Read atservices-accounting f47cb263

The Formal Contract

The narrative above explains; the sections below are authoritative — the rules, scenarios and tests this document binds.

Outcomes
Distinct effect keys protect each requested accounting movement.Staff can distinguish current posted entries from pending requests.
Surfaces
job
Intent sources
services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D7services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D2services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold; INV-11, INV-12, INV-16)services-accounting:docs/reconciliation/brief.md#Accounting (Andrew’s product brief, 2026-10-15): reconciliation must not become a second ledger

Controls

21 controls apply, from the corpus control catalogue.

TC-IAM-001 TC-IAM-002 TC-IAM-004 TC-IAM-005 TC-IAM-006 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-DAT-004 TC-LOG-002 TC-LOG-003 TC-LOG-004 TC-LOG-005 TC-PI-003 TC-PI-005

Business Rules

11 rules, 11 to be proved before approval. A rule's product intent is derived from its origin: 11 confirmed by a product decision, the rest inheriting this capability's confirmed.

IdRuleKindEnforced atProvenance
01must prove
Confirmed
Ledger requests join the operational batch selected by the unit’s default assignment for that merchant, and fail without writes when the batch cannot accept work or its period is closed.
policyservicetest
services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#refuses a unit with no open batch for its requests (400, `no_open_batch`), writing nothing; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#answers the request as stored: in the unit’s open batch, on its date, the document date kept, its lines with their roles; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#assigns the batch the default-batch rule gives the unit and merchant account; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#asks for no batch when there is no plan: a unit with none answers nothing, not a refusal
02must prove
Confirmed
Request accounting dates follow the operational batch, document dates preserve the original effect and lines distinguish bank, clearing, fee, reserve, adjustment and write-off roles.
origin: services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold; INV-16)
calculationservicetest
services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#answers the request as stored: in the unit’s open batch, on its date, the document date kept, its lines with their roles; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#assigns the batch the default-batch rule gives the unit and merchant account; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#refuses a unit with no open batch for its requests (400, `no_open_batch`), writing nothing; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#asks for no batch when there is no plan: a unit with none answers nothing, not a refusal
03must prove
Confirmed
An effect generating no posting plan needs no operational batch, including a zero transfer without fees.
policyservicetest
services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#asks for no batch when there is no plan: a unit with none answers nothing, not a refusal; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#answers the request as stored: in the unit’s open batch, on its date, the document date kept, its lines with their roles; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#assigns the batch the default-batch rule gives the unit and merchant account; services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#refuses a unit with no open batch for its requests (400, `no_open_batch`), writing nothing
04must prove
Confirmed
Requests are append-only, remain within one unit, balance by currency and contain one to twenty lines with exactly one debit or credit side each.
origin: services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold; INV-11)
invariantdatabasetest
05must prove
Confirmed
Each accounting effect uses a workspace-unique key that distinguishes finalization, reversal, write-off and successive item recognitions.
origin: services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§4: the architecture §6 invariants hold; INV-11)
invariantdatabasetest
06must prove
Confirmed
Bank and clearing lines use their bank and merchant ledger accounts, while fees, reserves and write-offs resolve the unit’s purpose defaults.
calculationservicetest
services-accounting:modules/reconciliation/tests/unit/rules/posting-plans.spec.js#takes a fee’s counter-account from processor_fee_expense; services-accounting:modules/reconciliation/tests/unit/rules/posting-plans.spec.js#takes a reserve release’s counter-account from processor_reserve_receivable; services-accounting:modules/reconciliation/tests/unit/rules/posting-plans.spec.js#debits the bank and credits clearing for a positive payout; services-accounting:modules/reconciliation/tests/unit/rules/posting-plans.spec.js#debits the write-off account and credits clearing for a positive item never paid out
07must prove
Confirmed
Posted status is calculated from an unreversed batch posting containing the request’s reconciliation entry; reversing that posting makes the request pending again.
calculationservicetest
08must prove
Confirmed
Operational batch posting creates the reconciliation entries, one per request, and unposting removes those entries; reconciliation does not post directly.
policyservicetest
09must prove
Confirmed
Posting requests support two-decimal currencies only and reject other exponents without writes until batch posting supports minor units.
validationservicetest
10must prove
Confirmed
Pending batch requests are read in creation order with event-key tie breaking and pages capped at five hundred.
policyservicetest
11must prove
Confirmed
Request creation requires the causing command’s transaction, and its operational batch cannot be deleted while the request refers to it.
invariantservice, databasetest

Scenarios

IdGivenWhenThenProvenance
01Three approved requests are assigned to an open operational batch.Post that batch.Three balanced reconciliation entries leave no request pending.test
02Those operational entries are posted.Unpost the batch.Entry removal makes the requests pending and reverses the example’s clearing effect.test
services-accounting:modules/reconciliation/tests/integration/services/batch-lifecycle/finalize-posts-to-subledger.integration.spec.js#deletes the entries, empties the clearing account and makes the three requests pending again

Edge Cases

IdGivenWhenThenProvenance
03The merchant settles in yen.Create a required posting request.Unsupported exponent refusal leaves no written request.test
services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-ledger-postings.integration.spec.js#refuses a currency whose exponent is not 2 (409, `unsupported-currency-exponent`), writing nothing

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.