---
id: ATS-COM-FUL-005
scope: CAP-COM-FUL-005
product_area: commerce
module: fulfillment
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-COM-FUL-005-01
    title: Only staff inspect the delivery register
    level: api
    proves:
      - BR-CAP-COM-FUL-005-01
    preconditions: An order has delivery obligations and a portal identity is available.
    steps: 'List obligations and read detail as staff, then as the portal caller.'
    expected: Staff receive gates and delivery history; the portal caller is denied.
    negative: true
    data_needs: Fixtures for only staff inspect the delivery register.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#lists
        each order’s one pending obligation with the built-in default gate
        frozen on it, and refuses a portal member the register
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#answers
        the obligation whole with its authorization and the attempt, through the
        register’s read
      - TST-COM-FUL-022
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#lists
      each order’s one pending obligation with the built-in default gate frozen
      on it, and refuses a portal member the register
    category: permission
  - id: ATS-COM-FUL-005-02
    title: Interventions retain reasons and append-only attribution
    level: api
    proves:
      - BR-CAP-COM-FUL-005-02
      - BR-CAP-COM-FUL-005-08
      - INV-DOM-COM-FUL-001-07
      - INV-DOM-COM-FUL-001-08
    preconditions: A reader and administrator can access an order.
    steps: >-
      Try reader approval and reasonless approval, then hold and release with
      explanations.
    expected: >-
      Invalid actions fail; valid actions retain intervention, history and
      fixture audit records.
    negative: true
    data_needs: Fixtures for interventions retain reasons and append-only attribution.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#refuses
        an approval to a reader, 403 permission_missing, and without a reason,
        400
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the hold to a reader (403) and without a reason (400), then places it:
        the obligation blocked by the staff hold
      - >-
        services-commerce:modules/fulfillment/tests/integration/db/register-tables.table.integration.spec.js#records
        an intervention of the catalogue (intervention_logs_intervention_check)
        and never lets the application change or remove it (42501)
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#holds
        the unpaid obligation with the log row, the history line and the audit
        event, then releases it and evaluates: unpaid, it stays blocked
      - TST-COM-FUL-022
      - TST-COM-FUL-021
      - TST-COM-FUL-025
      - TST-COM-FUL-039
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#refuses
      an approval to a reader, 403 permission_missing, and without a reason, 400
    category: validation
  - id: ATS-COM-FUL-005-03
    title: Competing approvals leave one approved result
    level: api
    proves:
      - BR-CAP-COM-FUL-005-03
      - INV-DOM-COM-FUL-001-09
    preconditions: A paid obligation requires staff approval.
    steps: Submit five approvals concurrently.
    expected: One approval opens delivery and four conflicts identify that approval.
    negative: false
    data_needs: Fixtures for competing approvals leave one approved result.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#releases
        the blocked obligation on one of five simultaneous approvals, which
        opens its gate at once since the line is paid, with the one intervention
        recorded; the other four are refused 409 naming it (DEF-COM-0869)
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-register.integration.spec.js#refuses
        the second once the first committed, 409 obligation_not_intervenable
        naming the first, whose approval stands
      - >-
        services-commerce:modules/fulfillment/tests/unit/register/obligation-approval.spec.js#names
        the approval that stands, who and when, in the message and the details
      - TST-COM-FUL-022
      - TST-COM-FUL-040
      - TST-COM-FUL-054
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#releases
      the blocked obligation on one of five simultaneous approvals, which opens
      its gate at once since the line is paid, with the one intervention
      recorded; the other four are refused 409 naming it (DEF-COM-0869)
    category: concurrency
  - id: ATS-COM-FUL-005-04
    title: Exceptional override and failed-work recovery remain distinct
    level: api
    proves:
      - BR-CAP-COM-FUL-005-04
      - BR-CAP-COM-FUL-005-05
    preconditions: One unpaid obligation waits and another has failed.
    steps: >-
      Override waiting work, then re-authorize failed work, fail it again and
      resolve it.
    expected: >-
      The override is attributed; recovery uses sequence two and resolution
      closes the failed work and exceptions.
    negative: false
    data_needs: >-
      Fixtures for exceptional override and failed-work recovery remain
      distinct.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#overrides
        the gate of the unpaid obligation, authorizing it regardless of the
        facts, with the override on the obligation
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#re-authorizes
        the failed obligation at sequence two, which the participant fails
        again, then resolves it with its exceptions
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-register.integration.spec.js#issues
        the next authorization for a failed obligation, naming the previous and
        superseding it; refuses any other state
      - TST-COM-FUL-022
      - TST-COM-FUL-040
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#overrides
      the gate of the unpaid obligation, authorizing it regardless of the facts,
      with the override on the obligation
    category: transition
  - id: ATS-COM-FUL-005-05
    title: A paid obligation remains blocked by its hold
    level: api
    proves:
      - BR-CAP-COM-FUL-005-06
    preconditions: Held pending work receives a payment.
    steps: >-
      Deliver the payment event, release the hold and attempt a hold on
      authorized work.
    expected: >-
      Payment does not defeat the hold, release evaluates eligibility and
      authorized work rejects holding.
    negative: false
    data_needs: Fixtures for a paid obligation remains blocked by its hold.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#keeps
        the gate shut while the hold stands, though the line is paid and
        Accounting’s event arrives
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#releases
        the hold on its route, which evaluates at once and opens the gate, with
        the interventions, the history and the audit events
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#blocks
        a pending obligation with the hold, keeps a blocked one blocked with the
        hold over its reason, and refuses an authorized one
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#releases
        the hold (the reason and the evaluation time cleared, the state still
        blocked) and refuses a release of what is not held
      - TST-COM-FUL-021
      - TST-COM-FUL-039
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#keeps
      the gate shut while the hold stands, though the line is paid and
      Accounting’s event arrives
    category: rule
  - id: ATS-COM-FUL-005-06
    title: Manual evidence closes only work in flight
    level: api
    proves:
      - BR-CAP-COM-FUL-005-07
    preconditions: Fixtures contain pending and in-progress delivery.
    steps: >-
      Try completion without evidence, supply evidence, submit a late callback
      and try the pending work.
    expected: >-
      Only evidenced completion of in-flight work succeeds, and the later
      callback is rejected.
    negative: true
    data_needs: Fixtures for manual evidence closes only work in flight.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the manual completion without the evidence (400) and to a reader (403),
        then completes it with the records and the note
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the participant’s late callback as not in flight, leaving the manual
        completion
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#completes
        the in-flight obligation by hand with the evidence, closing its
        authorization, and refuses a pending one
      - TST-COM-FUL-021
      - TST-COM-FUL-039
    provenance: test
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
      the manual completion without the evidence (400) and to a reader (403),
      then completes it with the records and the note
    category: validation
  - id: ATS-COM-FUL-005-07
    title: The delivery card respects per-action authority
    level: browser
    proves:
      - BR-CAP-COM-FUL-005-10
    preconditions: Staff possess re-authorization authority alone.
    steps: Inspect Order 360 with failed and held obligations.
    expected: >-
      Re-authorization is available while resolution, hold release and override
      are unavailable.
    negative: true
    data_needs: Fixtures for the delivery card respects per-action authority.
    bound_to: []
    provenance: proposed
    source: >-
      react-console:lib/commerce/order-flows/__tests__/live.test.ts#re-authorizes
      an obligation on the register's route and answers the intervention it
      logged
    category: permission
  - id: ATS-COM-FUL-005-08
    title: Explicit policy application changes the staff-visible waiting gate
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-001-08
      - BR-CAP-COM-FUL-005-01
      - BR-CAP-COM-FUL-002-12
    exercises:
      - CAP-COM-FUL-001
      - CAP-COM-FUL-005
      - CAP-COM-FUL-002
    relies_on:
      - ATS-COM-FUL-001-06
      - ATS-COM-FUL-005-01
      - ATS-COM-FUL-002-09
    preconditions: >-
      A waiting order uses the earlier product policy. Staff can apply the
      replacement and inspect delivery.
    steps: >-
      Replace the policy, apply it with a reason, read the obligation, and run
      the eligible pending sweep.
    expected: >-
      The detail shows the replacement gate and intervention; the sweep
      evaluates the new condition. Reapplication adds no gate replacement.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/fulfillment-policies.e2e.spec.js#re-freezes
        the pending obligation to the replaced policy with a receipt, records
        the intervention, and re-freezes nothing on a repeat
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#lists
        each order’s one pending obligation with the built-in default gate
        frozen on it, and refuses a portal member the register
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/register/register-sweeper.integration.spec.js#finds
        no stale pending obligation and no overdue authorization, and nudges
        nothing
  - id: ATS-COM-FUL-005-09
    title: >-
      A recovered membership releases the blocked purchase while staff retain
      the diagnosis
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-003-07
      - BR-CAP-COM-FUL-003-06
      - BR-CAP-COM-FUL-005-05
      - BR-CAP-COM-FUL-008-03
    exercises:
      - CAP-COM-FUL-003
      - CAP-COM-FUL-005
      - CAP-COM-FUL-008
    relies_on:
      - ATS-COM-FUL-003-05
      - ATS-COM-FUL-005-04
      - ATS-COM-FUL-008-03
    preconditions: >-
      Membership delivery failed permanently and its member-priced shirt is
      blocked. The failure is visible to staff.
    steps: >-
      Inspect and acknowledge the finding, re-authorize the membership, complete
      its new instruction, then inspect the shirt and retained history.
    expected: >-
      The shirt can open after membership completion; its original price remains
      visible. Acknowledgement alone does not release it.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/register/prerequisite-settlement.integration.spec.js#keeps
        the registration blocked when the sweep evaluates it again, and opens it
        once the membership is re-authorized and completes (05 §4)
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#overrides
        the gate of the unpaid obligation, authorizing it regardless of the
        facts, with the override on the obligation
      - >-
        services-commerce:modules/operations/tests/e2e/operations.e2e.spec.js#acknowledges
        then resolves the finding, with the interventions logged, the order’s
        history and the audit events recorded
  - id: ATS-COM-FUL-005-10
    title: Manual completion closes application delivery before a late callback
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-004-07
      - BR-CAP-COM-FUL-005-07
    exercises:
      - CAP-COM-FUL-004
      - CAP-COM-FUL-005
    relies_on:
      - ATS-COM-FUL-004-05
      - ATS-COM-FUL-005-06
    preconditions: >-
      An application left the authorized obligation in progress. Staff have
      manual-completion authority.
    steps: >-
      Complete with a reason and evidence, then send the application callback
      using the earlier authorization.
    expected: The recorded manual result remains and the late callback fails.
    negative: true
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the manual completion without the evidence (400) and to a reader (403),
        then completes it with the records and the note
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the participant’s late callback as not in flight, leaving the manual
        completion
      - TST-COM-FUL-021
    provenance: test
    source:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#completes
        the obligation and answers it as it stands; the repeat answers the same
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the manual completion without the evidence (400) and to a reader (403),
        then completes it with the records and the note
  - id: ATS-COM-FUL-005-11
    title: >-
      Operations intervention follows its delivery subject and refreshes the
      queue
    category: interaction
    level: api
    proves:
      - BR-CAP-COM-FUL-005-05
      - BR-CAP-COM-FUL-008-06
    exercises:
      - CAP-COM-FUL-005
      - CAP-COM-FUL-008
    relies_on:
      - ATS-COM-FUL-005-04
      - ATS-COM-FUL-008-04
    preconditions: >-
      Operations shows a failed obligation and staff hold re-authorization
      authority.
    steps: >-
      Open the finding, re-authorize its obligation with a reason, and read both
      the new instruction and refreshed queue.
    expected: >-
      The obligation has a new authorization; the queue action does not resolve
      an unrelated subject.
    negative: false
    data_needs: >-
      An isolated workspace with the products, records, authority and quantities
      described in the preconditions.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#overrides
        the gate of the unpaid obligation, authorizing it regardless of the
        facts, with the override on the obligation
      - >-
        react-console:lib/commerce/operations/__tests__/rules.test.ts#asks each
        intervention for its own key, so holding one does not offer another
evidence:
  - repository: services-commerce
    tests:
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#lists
        each order’s one pending obligation with the built-in default gate
        frozen on it, and refuses a portal member the register
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#answers
        the obligation whole with its authorization and the attempt, through the
        register’s read
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#refuses
        an approval to a reader, 403 permission_missing, and without a reason,
        400
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the hold to a reader (403) and without a reason (400), then places it:
        the obligation blocked by the staff hold
      - >-
        services-commerce:modules/fulfillment/tests/integration/db/register-tables.table.integration.spec.js#records
        an intervention of the catalogue (intervention_logs_intervention_check)
        and never lets the application change or remove it (42501)
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#holds
        the unpaid obligation with the log row, the history line and the audit
        event, then releases it and evaluates: unpaid, it stays blocked
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#releases
        the blocked obligation on one of five simultaneous approvals, which
        opens its gate at once since the line is paid, with the one intervention
        recorded; the other four are refused 409 naming it (DEF-COM-0869)
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-register.integration.spec.js#refuses
        the second once the first committed, 409 obligation_not_intervenable
        naming the first, whose approval stands
      - >-
        services-commerce:modules/fulfillment/tests/unit/register/obligation-approval.spec.js#names
        the approval that stands, who and when, in the message and the details
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#overrides
        the gate of the unpaid obligation, authorizing it regardless of the
        facts, with the override on the obligation
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#re-authorizes
        the failed obligation at sequence two, which the participant fails
        again, then resolves it with its exceptions
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-register.integration.spec.js#issues
        the next authorization for a failed obligation, naming the previous and
        superseding it; refuses any other state
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#keeps
        the gate shut while the hold stands, though the line is paid and
        Accounting’s event arrives
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#releases
        the hold on its route, which evaluates at once and opens the gate, with
        the interventions, the history and the audit events
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#blocks
        a pending obligation with the hold, keeps a blocked one blocked with the
        hold over its reason, and refuses an authorized one
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#releases
        the hold (the reason and the evaluation time cleared, the state still
        blocked) and refuses a release of what is not held
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the manual completion without the evidence (400) and to a reader (403),
        then completes it with the records and the note
      - >-
        services-commerce:modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js#refuses
        the participant’s late callback as not in flight, leaving the manual
        completion
      - >-
        services-commerce:modules/fulfillment/tests/integration/services/persistence/obligation-holds.integration.spec.js#completes
        the in-flight obligation by hand with the evidence, closing its
        authorization, and refuses a pending one
  - repository: react-console
    tests: []
coverage:
  rule: covered
  transition: covered
  validation: covered
  permission: covered
  edge: 'gap: FND-COM-FUL-060'
  failure: 'gap: FND-COM-FUL-060'
  boundary: 'gap: FND-COM-FUL-060'
  concurrency: covered
  invariant: 'gap: FND-COM-FUL-060'
  interaction: covered
coverage_notes:
  edge: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  failure: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  boundary: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
  invariant: >-
    No scenario specifically isolates this dimension; the coverage finding
    retains the missing proof.
transition_audit:
  - model: STATE-COM-FUL-001
    from: pending
    to: eligible
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:openGate
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: blocked
    to: eligible
    source: 'services-commerce:modules/fulfillment/services/register/gate-evaluation.ts'
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: eligible
    to: authorized
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:openGate
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: pending
    to: blocked
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:recordGateEvaluation,placeStaffHold
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: pending
    to: cancelled
    source: 'services-commerce:docs/migrations/obligation-register/README.md#D-P4-03'
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: blocked
    to: cancelled
    source: 'services-commerce:docs/migrations/obligation-register/README.md#D-P4-03'
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: eligible
    to: cancelled
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:OBLIGATION_TRANSITIONS
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: authorized
    to: in_progress
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:recordObligationOutcome
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: authorized
    to: completed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:recordObligationOutcome,completeObligationManually
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: in_progress
    to: completed
    source: >-
      services-commerce:modules/shipping/tests/integration/services/fulfillment/shipping-flow.integration.spec.js#completes
      every unit’s obligation through the register (the allocation as the
      record), and emits one deferred cost relief fact per item
    coverage: covered
    scenarios:
      - ATS-COM-FUL-004-12
      - ATS-COM-FUL-012-10
      - ATS-COM-FUL-013-10
      - ATS-COM-FUL-014-01
      - ATS-COM-FUL-014-06
      - ATS-COM-FUL-014-07
      - ATS-COM-FUL-018-08
  - model: STATE-COM-FUL-001
    from: authorized
    to: failed
    source: >-
      services-commerce:modules/fulfillment/tests/integration/services/register/obligation-worker.integration.spec.js#fails
      the obligation with the participant’s code, raises obligation_failed, and
      acknowledges the item
    coverage: covered
    scenarios:
      - ATS-COM-FUL-004-04
  - model: STATE-COM-FUL-001
    from: in_progress
    to: failed
    source: >-
      services-commerce:modules/fulfillment/services/register/register-sweeper.ts:sweepRegister
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: failed
    to: authorized
    source: >-
      services-commerce:modules/fulfillment/tests/e2e/obligation-register.e2e.spec.js#re-authorizes
      the failed obligation at sequence two, which the participant fails again,
      then resolves it with its exceptions
    coverage: covered
    scenarios:
      - ATS-COM-FUL-005-04
  - model: STATE-COM-FUL-001
    from: failed
    to: resolved
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-interventions.ts:resolveObligationByStaff
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
  - model: STATE-COM-FUL-001
    from: completed
    to: superseded
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:OBLIGATION_TRANSITIONS
    coverage: 'gap: FND-COM-FUL-060'
    scenarios: []
permission_audit:
  - key: commerce.obligations.read
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.obligations.approve
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.obligations.override
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.obligations.reauthorize
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.obligations.resolve
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.obligations.hold
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: commerce.obligations.complete-manually
    where_checked: api
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
  - key: orders.obligations.view
    where_checked: console
    coverage: 'gap: FND-COM-FUL-060'
    note: >-
      Per-key positive and negative coverage is not separately mapped;
      permission scenarios retain the observed aggregate tests.
related_audit:
  - capability: CAP-COM-FUL-001
    scenarios:
      - ATS-COM-FUL-005-08
  - capability: CAP-COM-FUL-008
    scenarios:
      - ATS-COM-FUL-005-09
      - ATS-COM-FUL-005-11
invariant_audit:
  - invariant: INV-DOM-COM-FUL-001-01
    scenarios:
      - ATS-COM-FUL-004-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts:obligations_subject_uq
  - invariant: INV-DOM-COM-FUL-001-02
    scenarios:
      - ATS-COM-FUL-004-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:OBLIGATION_TRANSITIONS;
      db/migrations/20261018004016_obligation_register.sql:refuse_obligation_regression
  - invariant: INV-DOM-COM-FUL-001-03
    scenarios:
      - ATS-COM-FUL-004-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts:obligations_authorization_state_check
  - invariant: INV-DOM-COM-FUL-001-04
    scenarios:
      - ATS-COM-FUL-004-03
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts:obligations_quantity_check
  - invariant: INV-DOM-COM-FUL-001-05
    scenarios:
      - ATS-COM-FUL-002-08
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:openGate
  - invariant: INV-DOM-COM-FUL-001-06
    scenarios:
      - ATS-COM-FUL-004-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/persistence/obligations.ts:recordObligationOutcome
  - invariant: INV-DOM-COM-FUL-001-07
    scenarios:
      - ATS-COM-FUL-005-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligation-attempts.table.ts;
      modules/fulfillment/db/intervention-logs.table.ts (UPDATE, DELETE and
      TRUNCATE revoked)
  - invariant: INV-DOM-COM-FUL-001-08
    scenarios:
      - ATS-COM-FUL-005-02
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/register/obligation-interventions.ts
  - invariant: INV-DOM-COM-FUL-001-09
    scenarios:
      - ATS-COM-FUL-005-03
    coverage: covered
    provenance: test
    source: >-
      services-commerce:docs/migrations/obligation-register/README.md#D-P4-16
      (obligation-register.e2e five simultaneous approvals)
  - invariant: INV-DOM-COM-FUL-001-10
    scenarios:
      - ATS-COM-FUL-006-03
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/enforcements.table.ts:enforcements_cause_uq
  - invariant: INV-DOM-COM-FUL-001-11
    scenarios:
      - ATS-COM-FUL-002-07
    coverage: covered
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/services/facts/financial-facts-handler.ts
  - invariant: INV-DOM-COM-FUL-001-12
    scenarios: []
    coverage: 'gap: FND-COM-FUL-060'
    provenance: observed
    source: >-
      services-commerce:modules/fulfillment/db/obligations.table.ts (composite
      RESTRICT keys)
---

# Understand and intervene in an order's delivery: Capability Test Specification

## Coverage

The category map distinguishes available cases from missing proof. A covered category has a scenario; the lifecycle and permission audits retain gaps in exhaustive coverage. Proposed cases describe the intended verification and carry no execution result.

| Rule | Scenarios |
|---|---|
| `BR-CAP-COM-FUL-005-01` | `ATS-COM-FUL-005-01`, `ATS-COM-FUL-005-08` |
| `BR-CAP-COM-FUL-005-02` | `ATS-COM-FUL-005-02` |
| `BR-CAP-COM-FUL-005-03` | `ATS-COM-FUL-005-03` |
| `BR-CAP-COM-FUL-005-04` | `ATS-COM-FUL-005-04`, `ATS-COM-FUL-005-09`, `ATS-COM-FUL-005-11` |
| `BR-CAP-COM-FUL-005-05` | `ATS-COM-FUL-005-04`, `ATS-COM-FUL-005-09`, `ATS-COM-FUL-005-11` |
| `BR-CAP-COM-FUL-005-06` | `ATS-COM-FUL-005-05` |
| `BR-CAP-COM-FUL-005-07` | `ATS-COM-FUL-005-06`, `ATS-COM-FUL-005-10` |
| `BR-CAP-COM-FUL-005-08` | `ATS-COM-FUL-005-02` |
| `BR-CAP-COM-FUL-005-10` | `ATS-COM-FUL-005-07` |

## Interactions With Related Capabilities

The interaction cases exercise choose delivery conditions for sold items; review and resolve operations findings. They vary the upstream record or outcome and inspect the resulting work across the capability boundary. Workflow crossings also include stock, financial or application records when the flow depends on them. Existing test bindings retain their source anchors so a reviewer can distinguish supporting assertions from a complete workflow run.
