---
id: WF-ACC-REC-005
title: Reverse a finalized reconciliation
trigger: Staff request reversal of an approved explanation that needs correction.
product_area: accounting
module: reconciliation
revision: 3
status: draft
design_intent: confirmed
origin: >-
  ACCT-M8 plan D1 (reverse and redo; a second approver when the month is
  closed), approved by Andrew 2026-10-22; services-accounting
  docs/reconciliation/architecture.md §14.3
implementation_evidence: observed
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-ACC-REC-013
  - CAP-ACC-REC-014
moves:
  - STATE-ACC-REC-003
  - STATE-ACC-REC-001
  - STATE-ACC-REC-004
crosses:
  - SVC-ACC-REC-reconciliation
idempotency: >-
  Request and approval have distinct caller-scoped keys. Matching repeats replay
  retained answers; unique mirror effect keys prevent duplicate requests.
concurrency: >-
  Completion uses the lifecycle lock order and period sharing. Approval compares
  the read version and requires an actor different from the requester.
hops:
  - 'n': 1
    actor_or_service: Reverse command
    action: >-
      Replay the key, lock approved holdings and check version, reason, pending
      request and document period.
    anchor: >-
      services-accounting:modules/reconciliation/services/batch-lifecycle/reverse-batch.ts:reverseReconciliationBatch
    seam: sync
    on_failure: Audited guard refusal records the unsuccessful request.
    left_inconsistent: Approval remains unchanged.
    observer: History and the response identify the refusal.
    provenance: observed
    source: >-
      services-accounting:modules/reconciliation/services/batch-lifecycle/reverse-batch.ts:reverseReconciliationBatch
  - 'n': 2
    actor_or_service: Reverse command
    action: >-
      For a closed document period, retain a pending reason and requester
      without writing mirrors.
    anchor: >-
      services-accounting:modules/reconciliation/services/persistence/reconciliation-batch-lifecycles.ts:recordReversalRequest
    seam: state_machine
    on_failure: A failed request write rolls back.
    left_inconsistent: No partial request is retained.
    observer: Readiness and the workspace show pending approval after success.
    provenance: observed
    source: >-
      services-accounting:modules/reconciliation/services/batch-lifecycle/reverse-batch.ts:reverseReconciliationBatch
  - 'n': 3
    actor_or_service: Second approver
    action: Have a different authorized person approve the current pending request.
    anchor: >-
      services-accounting:modules/reconciliation/services/batch-lifecycle/reverse-batch.ts:approveReconciliationBatchReversal
    seam: sync
    on_failure: 'Invalid requester, version or pending state receives an audited refusal.'
    left_inconsistent: The pending request remains.
    observer: History and readiness retain the unresolved approval.
    provenance: observed
    source: >-
      services-accounting:modules/reconciliation/services/batch-lifecycle/reverse-batch.ts:approveReconciliationBatchReversal
  - 'n': 4
    actor_or_service: Ledger request writer
    action: >-
      Mirror unmirrored finalization requests in the selected open operational
      batch, preserving document dates.
    anchor: >-
      services-accounting:modules/reconciliation/services/persistence/reconciliation-ledger-postings.ts:recordPostings
    seam: sync
    on_failure: A missing accepting batch rolls back completion without an attempt event.
    left_inconsistent: The original stays approved and any existing request stays pending.
    observer: The error response is the available evidence.
    provenance: observed
    source: >-
      services-accounting:modules/reconciliation/services/batch-lifecycle/reverse-batch.ts
  - 'n': 5
    actor_or_service: Reverse command
    action: >-
      Mark the explanation reversed before releasing its claims and payout
      links; retain completion activity.
    anchor: >-
      services-accounting:modules/reconciliation/services/persistence/reconciliation-batch-lifecycles.ts:releaseBatchHoldings
    seam: sync
    on_failure: Any failure rolls back mirrors and release together.
    left_inconsistent: No partly reversed explanation commits.
    observer: History shows reversal and the payout becomes unheld.
    provenance: observed
    source: >-
      services-accounting:modules/reconciliation/services/persistence/reconciliation-batch-lifecycles.ts:recordReversal
  - 'n': 6
    actor_or_service: Preparer
    action: >-
      Create a replacement explanation over the released payout; reusable manual
      effects remain available.
    anchor: 'react-console:lib/accounting/reconciliation/store.tsx:startNewRecon'
    seam: sync
    on_failure: Normal creation checks can refuse the replacement.
    left_inconsistent: The payout remains unreconciled until a replacement is approved.
    observer: Overview and readiness show unfinished payout work.
    provenance: observed
    source: 'react-console:lib/accounting/reconciliation/store.tsx:startNewRecon'
branches:
  - Open-period reversal skips the pending request and second approval.
  - >-
    Closed-period mirrors use the selected operational batch date, not
    automatically the first open date.
waits:
  - A pending closed-period reversal has neither withdrawal nor expiry.
evidence:
  - >-
    services-accounting at f47cb263:
    modules/reconciliation/services/batch-lifecycle/reverse-batch.ts,
    batch-commands.ts; services/persistence/reconciliation-batch-lifecycles.ts,
    reconciliation-ledger-postings.ts; services/rules/posting-plans.ts;
    tests/integration/services/batch-lifecycle/reverse-batch.integration.spec.js.
  - >-
    react-console at baf6dae3: lib/accounting/reconciliation/store.tsx
    (reverseRecon, approveReversal, startNewRecon);
    components/accounting/reconciliation/workspace/workspace.tsx.
controls: [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-005, TC-AZ-006, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-DAT-001, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005]
---
# Reverse a finalized reconciliation

## What It Does

Reversal preserves the original approval as history and creates opposite accounting requests before freeing its holdings. A closed document period requires request and independent approval before completion.

## The Flow

```mermaid
sequenceDiagram
  participant R as Requester
  participant V as Reverse command
  participant A as Second approver
  participant D as Accounting database
  R->>V: reverse (reason, key, version)
  V->>D: lock, share-lock the period
  alt period open
    V->>D: mirrors, reversed, release holdings
  else period closed
    V->>D: pending request only
    A->>V: approve (key, version)
    V->>D: mirrors on selected batch date, reversed, release holdings
  end
  R->>D: open a replacement reconciliation
```

## When Something Fails

Completion is atomic, so no partial mirror or release survives failure. A missing batch can leave the mistaken approval and pending request intact; the implementation provides no way to withdraw that reversal request.

## Open Design Questions

Product must decide whether pending reversal needs cancellation. Forward accounting still requires an appropriately dated operational batch.
