---
id: WF-ACC-CLS-003
title: Retry an interrupted close or reopen
trigger: >-
  A controller selects retry for failed work, or an authorized client calls
  recovery directly.
product_area: accounting
module: close
revision: 1
status: draft
design_intent: proposed
implementation_evidence: inconsistent
inference: []
source_sha:
  services-accounting: f47cb263875bbc0c5640fba7dae6785ec32695f8
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-ACC-CLS-012
moves:
  - STATE-ACC-CLS-002
crosses:
  - SVC-ACC-CLS-fiscal-close
idempotency: >-
  Retry has no separate command key. Its transaction moves failed to running, so
  another retry is refused. The linked job preserves settled steps and domain
  output; calendar generation remains a separate-commit exception.
concurrency: >-
  Retry acquires the period lock and refreshes the run before creating a linked
  attempt. Its submission identity uses the run and attempt number within the
  workspace.
hops:
  - 'n': 1
    actor_or_service: Console run page
    action: >-
      Show recovery controls for each failed run and send the selected retry
      without a local action-grant check.
    anchor: 'react-console:components/accounting/close/close-run-view.tsx:FailurePanel'
    seam: sync
    on_failure: A refusal appears below the failure explanation.
    left_inconsistent: The attempted control itself writes no Accounting data.
    observer: The controller receives the action error.
    provenance: observed
    source: 'react-console:components/accounting/close/close-run-view.tsx:FailurePanel'
  - 'n': 2
    actor_or_service: Retry route (reconciliation function)
    action: >-
      Require read access at the route and the run kind’s action grant in the
      handler.
    anchor: >-
      services-accounting:modules/fiscal-close/aws/api/fiscal-close.routes.ts:fiscalCloseRoutes
    seam: sync
    on_failure: A caller missing the required grant receives permission refusal.
    left_inconsistent: No retry job is created.
    observer: The calling client receives the permission result.
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/e2e/fiscal-close-runs.e2e.spec.js#refuses
      a reader’s retry with 403: the handler requires the run’s kind’s key
  - 'n': 3
    actor_or_service: Retry action (one transaction)
    action: >-
      Lock the period, refresh the run and require a retained failed month;
      create a linked job, clear failure and return the run to running.
    anchor: >-
      services-accounting:modules/fiscal-close/services/jobs/close-run-actions.ts:retryCloseRun
    seam: sync
    on_failure: >-
      A changed status or released month is refused, with a new request
      identified when needed.
    left_inconsistent: A rolled-back retry leaves the earlier run and job unchanged.
    observer: The response identifies recovery or refusal.
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/jobs/close-job.integration.spec.js#refuses
      a retry of the released run, naming a new close
  - 'n': 4
    actor_or_service: Platform durable jobs and the run's job
    action: >-
      Start the linked job after commit and retain settled steps while it
      resumes the remaining close or reopen work.
    anchor: >-
      services-accounting:modules/fiscal-close/services/jobs/fiscal-close-jobs.ts:createRunRetryJob
    seam: state_machine
    on_failure: >-
      The original workflow’s failure rules apply; a failed start uses the
      delegated reconciler helper.
    left_inconsistent: >-
      The protected month remains until execution finishes or eligible
      cancellation occurs.
    observer: The run view accumulates step attempts across the jobs it reads.
    provenance: test
    source: >-
      services-accounting:modules/fiscal-close/tests/integration/services/jobs/reopen-job.integration.spec.js#finishes
      the reopen on retry
evidence:
  - >-
    services-accounting at f47cb263:
    modules/fiscal-close/services/jobs/close-run-actions.ts,
    fiscal-close-jobs.ts:periodHeldBy, createRunRetryJob;
    services/runs/close-run-view.ts.
  - 'react-console at baf6dae3: components/accounting/close/close-run-view.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-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]
---

# Retry an interrupted close or reopen

## What It Does

Retry resumes a failed request whose month remains protected. A linked job retains earlier settled work and attempts the remaining steps without creating another request.

## The Flow

```mermaid
sequenceDiagram
  actor Staff
  participant API as Recovery service
  participant Job as Linked retry job
  Staff->>API: retry failed request
  API->>API: lock month and verify retained work
  alt eligible
    API->>API: create linked job and clear failure
    API->>Job: start after commit
    Job->>Job: retain settled work and resume
  else released or no longer failed
    API-->>Staff: refuse retry
  end
```

## When Something Fails

If the month has been released, the service refuses retry and directs staff to a new request. A failed start is delegated to the reconciler. Subsequent task failures follow the original close or reopen path. The console cannot distinguish every recovery case from its current response and offers retry even where the service refuses it.

## Open Design Questions

The response should expose recovery eligibility and released-period state. Whether execution should resolve the original requester’s current authority remains a product question.
