---
id: CAP-ACC-REC-016
title: Accept an understood problem with the required approval
feature: FEAT-ACC-REC-05
product_area: accounting
module: reconciliation
revision: 2
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - react-console acceptance inventory CAP-ACC-REC-010 (accept under policy)
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - >-
    services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D6 (architecture §3.4 U10, U12: Accept is a
    separate permissioned action)
purpose: Approvers need a recorded policy decision when a financial concern remains understood but unresolved.
outcomes:
  - Independent acceptance removes a blocker only after approval.
  - The policy reason and both decision identities remain reviewable.
concepts:
  - CON-ACC-REC-004
actors:
  - ACT-ACC-018
  - ACT-ACC-019
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: accounting.reconciliation-exceptions.accept
    where_checked: api
    scope: tenant
  - key: accounting.reconciliation-exceptions.accept
    where_checked: console
    scope: tenant
rules:
  - id: BR-CAP-ACC-REC-016-01
    proved_by: [ATS-ACC-REC-016-01, TST-ACC-REC-024, TST-ACC-REC-043, TST-ACC-REC-066]
    statement: >-
      A warning can be accepted immediately by one accept-authorized person who supplies a resolution, without
      an approver.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#accepts
      a warning by one user, without a second and with no request;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#answers
      the stored acceptance for the same key and request;
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#answers 200 with a warning
      accepted by one user, with no approver;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#accepts
      an accepted warning with no approver
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-02
    proved_by: [ATS-ACC-REC-016-02, ATS-ACC-REC-016-09, ATS-ACC-REC-018-11, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: >-
      Blocker acceptance first stores a resolution request without closing the open or investigating problem;
      it continues to block and another pending request is rejected.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#records
      a blocker’s acceptance request by the first user and leaves it open (`exception.acceptance-requested`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      a second acceptance request while one is pending (409, `acceptance_already_requested`);
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#answers 200 with the
      blocker still open and its acceptance requested by the caller;
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses an approvedById in
      the body with 400 approved_by_id_not_allowed
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-03
    proved_by: [ATS-ACC-REC-015-11, ATS-ACC-REC-016-03, ATS-ACC-REC-016-10, ATS-ACC-REC-020-13, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: >-
      Approval requires a different accept-authorized person and current version, refusing self-approval or
      approval without a pending request.
    kind: permission
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      the requester’s own approval (403, `second_user_required`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      an approval at a version that is not the exception’s (409, `stale_version`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#accepts
      the blocker on a second user’s approval, the requester its resolver (`exception.accepted`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#answers
      the approver’s own approval again under a new key (state idempotency);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      the approval of a blocker with no acceptance requested (409, `no_acceptance_requested`);
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#answers 200 with the
      blocker accepted, the requester its resolver and the second user its approver
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-04
    proved_by: [ATS-ACC-REC-015-11, ATS-ACC-REC-016-03, ATS-ACC-REC-016-10, ATS-ACC-REC-020-13, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: >-
      Successful approval accepts the blocker, retains the requester as resolver and records the approver,
      with repeat approval by that approver returning the same result.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#accepts
      the blocker on a second user’s approval, the requester its resolver (`exception.accepted`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      the requester’s own approval (403, `second_user_required`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      an approval at a version that is not the exception’s (409, `stale_version`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#answers
      the approver’s own approval again under a new key (state idempotency);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      the approval of a blocker with no acceptance requested (409, `no_acceptance_requested`);
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#answers 200 with the
      blocker accepted, the requester its resolver and the second user its approver
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-05
    proved_by: [ATS-ACC-REC-016-02, ATS-ACC-REC-016-09, ATS-ACC-REC-018-11, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: Clients cannot supply the approval identity; Rhythm derives it from the person performing approval.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses an approvedById in
      the body with 400 approved_by_id_not_allowed;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#records
      a blocker’s acceptance request by the first user and leaves it open (`exception.acceptance-requested`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      a second acceptance request while one is pending (409, `acceptance_already_requested`);
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#answers 200 with the
      blocker still open and its acceptance requested by the caller
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-06
    proved_by: [ATS-ACC-REC-016-04, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: >-
      Only the original requester can withdraw a pending acceptance, clearing the request while leaving the
      blocker open; absent requests cannot be withdrawn.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#withdraws
      the request by its requester, clearing it and leaving the blocker open
      (`exception.acceptance-withdrawn`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      another user’s withdrawal (403, `acceptance_requester_only`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      a withdrawal with no acceptance requested (409, `no_acceptance_requested`);
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#records
      each refused withdrawal as `exception.acceptance-withdrawal-refused`;
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#records the withdrawal in
      the exception’s history
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-07
    proved_by: [ATS-ACC-REC-016-05, TST-ACC-REC-043]
    statement: >-
      Database constraints require an accepted blocker’s request and independent approver, forbid warning
      approvers and reserve pending requests for blockers.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#refuses
      an approver who is the acceptance’s own requester;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#refuses
      an accepted blocker with no approver;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#refuses
      an approver who is the exception’s own resolver;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#refuses
      an accepted warning with an approver;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#refuses
      an acceptance request on a warning;
      services-accounting:modules/reconciliation/tests/integration/db/reconciliation-exceptions.table.integration.spec.js#accepts
      an accepted blocker with its request and an approver other than its requester and resolver
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-08
    proved_by: [ATS-ACC-REC-016-06, TST-ACC-REC-066]
    statement: Human resolution or detector clearing also removes a pending acceptance request and records its removal.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#clears
      a pending acceptance request when the exception is resolved, saying so in `exception.resolved`;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#clears
      a pending acceptance request when its condition is cleared
    origin: none
  - id: BR-CAP-ACC-REC-016-09
    proved_by: [ATS-ACC-REC-016-07, ATS-ACC-REC-016-11, ATS-ACC-REC-020-14, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: >-
      Acceptance operations require replayable request keys, reject changed bodies and record refused commands
      in exception history.
    kind: validation
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#records
      each refused request and approval, and leaves the blocker open with its request pending;
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses a principal who may
      update exceptions but not accept them with 403;
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses an accept without
      an Idempotency-Key with 400 idempotency_key_required;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      the request’s key sent with another request (409, `idempotency_key_reused`);
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#records each refused
      acceptance command in the exception’s history
    origin: 'services-accounting:docs/reconciliation/architecture.md#13.2 Workflow (Andrew''s Decision 2, 2026-10-16)'
  - id: BR-CAP-ACC-REC-016-10
    proved_by: [ATS-ACC-REC-016-07, ATS-ACC-REC-016-11, ATS-ACC-REC-020-14, TST-ACC-REC-024, TST-ACC-REC-066]
    statement: >-
      Accept permission, a sensitive administrator approval beyond update, governs request, approval and
      withdrawal.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses a principal who may
      update exceptions but not accept them with 403;
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses an accept without
      an Idempotency-Key with 400 idempotency_key_required;
      services-accounting:modules/reconciliation/tests/integration/services/persistence/reconciliation-exceptions.integration.spec.js#refuses
      the request’s key sent with another request (409, `idempotency_key_reused`);
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#records each refused
      acceptance command in the exception’s history
    origin: 'services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D10 (§2: permissions)'
  - id: BR-CAP-ACC-REC-016-11
    proved_by: [ATS-ACC-REC-016-08, TST-ACC-REC-013, TST-ACC-REC-022]
    statement: >-
      The console collects an acceptance reason, identifies the pending requester and offers approval and
      withdrawal through accept permission checks.
    kind: policy
    enforced_at:
      - console
    must_prove: false
    provenance: observed
    source: 'react-console:components/accounting/reconciliation/exceptions-screen.tsx:ExceptionsScreen'
    origin: 'services-accounting:docs/milestones/plans/ACCT-M8-plan.md#D6 (architecture §3.4 U12)'
scenarios:
  - id: SC-CAP-ACC-REC-016-01
    given: The gift has an active overdue blocker.
    when: 'Have its requester approve acceptance, then obtain another person’s approval.'
    then: >-
      Self-approval fails and independent approval records requester as resolver and the other person as
      approver.
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-scenario.e2e.spec.js#step 11:
      accepts the exception on priya’s approval, marcus its resolver
  - id: SC-CAP-ACC-REC-016-02
    given: Acceptance is waiting for approval.
    when: Try withdrawal as someone else.
    then: Only the request’s owner can withdraw.
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/outstanding.e2e.spec.js#refuses another user’s
      withdrawal of the request with 403 acceptance_requester_only
edge_cases:
  - id: SC-CAP-ACC-REC-016-03
    given: The gift’s acceptance request remains pending.
    when: Assess October readiness.
    then: The money still blocks and the finding links its exception.
    provenance: test
    source: >-
      services-accounting:modules/reconciliation/tests/e2e/reconciliation-scenario.e2e.spec.js#step 11: still
      blocks October on the gift, naming its exception, while the acceptance awaits approval
constraints: []
depends_on:
  - CAP-ACC-REC-015
related:
  - CAP-ACC-REC-018
journeys:
  - JNY-ACC-REC-005
open_questions: []
evidence:
  - >-
    Examined supporting service material: outstanding.routes.ts (acceptReconciliationException,
    approveReconciliationExceptionAcceptance, withdrawReconciliationExceptionAcceptance),
    services/persistence/reconciliation-exceptions.ts (accepting region),
    db/reconciliation-exceptions.table.ts; tests integration reconciliation-exceptions,
    db/reconciliation-exceptions.table, e2e outstanding and scenario step 11;
    docs/reconciliation/architecture.md §13.2.
  - >-
    Examined supporting console material: components/accounting/reconciliation/exceptions-screen.tsx,
    outstanding-screen.tsx; lib/accounting/reconciliation/store.tsx (acceptException, approveAcceptance,
    withdrawAcceptance); e2e/mock/accounting-reconciliation.mock.spec.ts; acceptance journey ACT-ACC-0605.
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-AVL-001, TC-AVL-004, TC-MON-001, TC-MON-002, TC-MON-004, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-AI-005]
exercised_by: [FAS-ACC-REC-05-02, FAS-ACC-REC-05-03, FAS-ACC-REC-05-04, FAS-ACC-REC-07-02]
suites: [TST-ACC-REC-013, TST-ACC-REC-022, TST-ACC-REC-024, TST-ACC-REC-043, TST-ACC-REC-066]
---

# Accept an understood problem with the required approval

## Purpose

Approvers need a recorded policy decision when a financial concern remains understood but unresolved.

## How It Works

An approver supplies the explanation for accepting the concern. Warnings can conclude with that person’s decision, while blockers retain a request for another approver. Rhythm checks that the requester and approver are distinct before the blocker stops blocking. The requester can withdraw an undecided request. Stale state, missing authority or self-approval leaves the concern active.

## Relationships

Exception investigation supplies the concern and readiness retains its acceptance context for period review.
