---
id: TST-COM-FUL-021
title: Obligation holds
kind: api-lifecycle
product_area: commerce
module: fulfillment
revision: 1
status: draft
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
repository: services-commerce
files:
  - modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js
implements:
  - ATS-COM-FUL-004-10
  - ATS-COM-FUL-005-02
  - ATS-COM-FUL-005-05
  - ATS-COM-FUL-005-06
  - ATS-COM-FUL-005-10
  - FAS-COM-FUL-01-03
environment: local
implementation_state: implemented
latest_result: not-run
latest_run_at: null
latest_run_ref: null
conformance: not-verified
estimated_minutes: 5
isolation: >-
  Run-created workspace identifiers and fixture records in the prepared test database; concurrency
  cases own their extra connections.
evidence:
  - repository: services-commerce
    path: modules/fulfillment/tests/e2e/obligation-holds.e2e.spec.js
    test_titles:
      - >-
        refuses the hold to a reader (403) and without a reason (400), then places it: the
        obligation blocked by the staff hold
      - >-
        keeps the gate shut while the hold stands, though the line is paid and Accounting’s event
        arrives
      - >-
        releases the hold on its route, which evaluates at once and opens the gate, with the
        interventions, the history and the audit events
      - left the obligation in progress
      - >-
        refuses the manual completion without the evidence (400) and to a reader (403), then
        completes it with the records and the note
      - 'refuses the participant’s late callback as not in flight, leaving the manual completion'
    scenario_anchors:
      - >-
        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/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/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/e2e/obligation-holds.e2e.spec.js'
---

# Obligation holds

## Verification Boundary

This suite calls the composed local HTTP handler over the prepared database. It checks obligation holds through request contracts and the enforcing security boundary.

## What This Suite Proves

The bound scenarios identify the assertions this suite contributes. Source anchors retain the exact test cases; where a capability scenario has several contributing suites, a single binding does not imply that every branch runs here.

## What It Does Not Prove

Local handler execution does not establish deployed routing, queue delivery or browser behavior. It also supplies no latest result until a qualification run records one.

## Real Dependencies and Test Doubles

The database and imported Commerce persistence services are real. Fixtures create the records owned by this run. Signed local security contexts and the composed handler exercise the request boundary. Financial facts are supplied by a local fixture provider. Queue publication uses the suite’s recording or scripted publisher.

## Must Not Be Doubled

Keep the composed handler, permission enforcement, request validation and database writes real when claiming this local API coverage. Scripted financial, queue or carrier outcomes must remain visibly separate from deployed integration evidence.
