---
id: ATS-PFM-DJE-016
scope: CAP-PFM-DJE-016
product_area: platform
module: data-job-engine
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
scenarios:
  - id: ATS-PFM-DJE-016-01
    title: Run management rejects callers without staff authority
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-01
    preconditions: Use a customer administrator and a staff account lacking import-management authority.
    steps:
      - do: Attempt package registration and run retrieval with each account.
        expect: Both accounts receive a refusal.
        provenance: proposed
        source: 'services-platform:modules/data-jobs/aws/api/data-runs.routes.ts:manage'
    expected: Both accounts receive a refusal.
    negative: true
    data_needs: Accounts with the two access profiles.
    bound_to: []
    provenance: proposed
    source: 'services-platform:modules/data-jobs/aws/api/data-runs.routes.ts:manage'
    category: permission
    binding_evidence: []
  - id: ATS-PFM-DJE-016-02
    title: Registration rejects a workspace outside loading
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-02
    preconditions: Prepare an initial-migration package for an implementation workspace that is not loading.
    steps:
      - do: Submit the package for registration.
        expect: Registration identifies the workspace-state refusal and creates no run.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
          an initial import into a tenant that is not loading
    expected: Registration identifies the workspace-state refusal and creates no run.
    negative: true
    data_needs: The workspace and a valid package fixture.
    bound_to:
      - TST-PFM-DJE-176
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      an initial import into a tenant that is not loading
    category: validation
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        an initial import into a tenant that is not loading
  - id: ATS-PFM-DJE-016-03
    title: Invalid package declarations receive refusals
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-03
    preconditions: >-
      Prepare packages with mismatched digests or sizes, incorrect destinations, and missing or
      unexpected dataset uploads.
    steps:
      - do: Attempt to register each package.
        expect: >-
          Each invalid fixture receives the corresponding refusal; the previously registered valid
          run retains its dataset steps.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
          a package whose dataset digest is not the digest of the uploaded file
    expected: >-
      Each invalid fixture receives the corresponding refusal; the previously registered valid run
      retains its dataset steps.
    negative: true
    data_needs: Completed uploads and altered manifest fixtures.
    bound_to:
      - TST-PFM-DJE-176
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      a package whose dataset digest is not the digest of the uploaded file
    category: validation
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a package whose dataset digest is not the digest of the uploaded file
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#writes
        nothing at all when a digest does not match: a refused package leaves no run behind
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a package built for another tenant, whatever tenant it is registered in
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a package built for another environment
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a request that names no upload for a dataset the package contains
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a package whose dataset claims a size the uploaded file does not have
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a request that names an upload for a dataset the package does not contain
  - id: ATS-PFM-DJE-016-04
    title: Dependency ordering permits independent work and rejects cycles
    level: unit
    proves:
      - BR-CAP-PFM-DJE-016-04
    preconditions: 'Prepare manifests containing a dependency chain, independent datasets and a cycle.'
    steps:
      - do: Calculate their execution waves and attempt registration of the cyclic package.
        expect: >-
          The chain receives successive waves, independent datasets share a wave and cyclic
          registration leaves no rows.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/unit/package-manifest.spec.ts#puts a chain in
          one dataset per wave, in the order the edges say
    expected: >-
      The chain receives successive waves, independent datasets share a wave and cyclic registration
      leaves no rows.
    negative: true
    data_needs: Manifest fixtures representing each dependency shape.
    bound_to:
      - TST-PFM-DJE-189
      - TST-PFM-DJE-176
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/unit/package-manifest.spec.ts#puts a chain in one
      dataset per wave, in the order the edges say
    category: rule
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/unit/package-manifest.spec.ts#puts a chain in one
        dataset per wave, in the order the edges say
      - >-
        services-platform:modules/data-jobs/tests/unit/package-manifest.spec.ts#puts two datasets
        with no edge between them in the same wave, so both may run at once
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a package whose datasets cannot be ordered, before any row of it is written
  - id: ATS-PFM-DJE-016-05
    title: A package can be registered again after its run finishes
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-05
    preconditions: A package already has a running load.
    steps:
      - do: 'Register it again, finish the original load and repeat registration.'
        expect: The first request identifies the unfinished run; the later request creates a distinct run.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
          a second registration of a package whose run has not finished, naming the run that holds
          it
    expected: The first request identifies the unfinished run; the later request creates a distinct run.
    negative: true
    data_needs: A package with controllable job progress.
    bound_to:
      - TST-PFM-DJE-176
      - TST-PFM-DJE-167
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      a second registration of a package whose run has not finished, naming the run that holds it
    category: transition
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
        a second registration of a package whose run has not finished, naming the run that holds it
      - >-
        services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#registers
        the same package again as a new run once the first has finished
  - id: ATS-PFM-DJE-016-06
    title: Polling resumes a load that stops receiving requests
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-06
    preconditions: A three-dataset run has a job that finishes in its owning application.
    steps:
      - do: 'Stop reading the run, then resume polling until the load finishes.'
        expect: >-
          No progress is recorded during the gap; subsequent reads submit dependent datasets and
          each dataset is submitted once.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#leaves
          the run where it stood while nobody reads it, though a dataset finished in its service
    expected: >-
      No progress is recorded during the gap; subsequent reads submit dependent datasets and each
      dataset is submitted once.
    negative: false
    data_needs: Application doubles with controllable completion.
    bound_to:
      - TST-PFM-DJE-167
      - TST-PFM-DJE-177
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#leaves
      the run where it stood while nobody reads it, though a dataset finished in its service
    category: transition
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#leaves
        the run where it stood while nobody reads it, though a dataset finished in its service
      - >-
        services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#takes
        the run on from where it stood at the next read: the finished dataset recorded, the next one
        submitted
      - >-
        services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#submits
        every dataset exactly once over the whole load
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#fails
        the run at the first dataset that failed, in the owning service’s own words
  - id: ATS-PFM-DJE-016-07
    title: The owning application receives the staff caller’s token
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-07
    preconditions: Register a package containing a CRM dataset.
    steps:
      - do: Start the run and inspect the outgoing request.
        expect: >-
          CRM receives the dataset through its own job route using the requesting staff member’s
          token.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#asks
          the macroservice that owns the object type, over its own route for that object
    expected: CRM receives the dataset through its own job route using the requesting staff member’s token.
    negative: false
    data_needs: A recording CRM application double.
    bound_to:
      - TST-PFM-DJE-177
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#asks
      the macroservice that owns the object type, over its own route for that object
    category: permission
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#asks
        the macroservice that owns the object type, over its own route for that object
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#forwards
        the staff caller’s own token with every call, and invents no identity of its own
  - id: ATS-PFM-DJE-016-08
    title: Blocked work receives a bounded second attempt
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-08
    preconditions: A dataset job finishes with unresolved references.
    steps:
      - do: Continue driving the load through its remaining datasets.
        expect: >-
          The blocked dataset is submitted exactly twice, dependent work continues and persistent
          blocked records remain visible.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#tries
          a blocked dataset a second time, and only a second time
    expected: >-
      The blocked dataset is submitted exactly twice, dependent work continues and persistent
      blocked records remain visible.
    negative: false
    data_needs: Application doubles that retain blocked outcomes.
    bound_to:
      - TST-PFM-DJE-177
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#tries
      a blocked dataset a second time, and only a second time
    category: edge
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#tries
        a blocked dataset a second time, and only a second time
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#does
        not hold the rest of the run up for a blocked dataset: what depends on it goes on
  - id: ATS-PFM-DJE-016-09
    title: Run controls stop submissions and cancel child jobs
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-09
    preconditions: Prepare a running load with both submitted and pending datasets.
    steps:
      - do: >-
          Pause the load, attempt Resume against a run that is not paused and cancel the running
          fixture.
        expect: >-
          Pause submits no further work, the invalid Resume is refused and successful child
          cancellations leave pending datasets skipped.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#pauses
          a running run where it stands, and submits nothing while it is paused
    expected: >-
      Pause submits no further work, the invalid Resume is refused and successful child
      cancellations leave pending datasets skipped.
    negative: true
    data_needs: Application doubles that acknowledge cancellation.
    bound_to:
      - TST-PFM-DJE-177
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#pauses
      a running run where it stands, and submits nothing while it is paused
    category: transition
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#pauses
        a running run where it stands, and submits nothing while it is paused
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#refuses
        to resume a run that is not paused
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#cancels
        the jobs a cancelled run had already submitted, in their own services
  - id: ATS-PFM-DJE-016-10
    title: Readiness distinguishes successful accounting from tested blockers
    level: unit
    proves:
      - BR-CAP-PFM-DJE-016-10
    preconditions: 'Prepare a successful, fully accounted run and fixtures for each covered readiness blocker.'
    steps:
      - do: Build a summary for each fixture.
        expect: >-
          The complete fixture is ready and each blocking fixture identifies its reason and any
          missing count.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is ready when the run
          succeeded and every record of every dataset is accounted for
    expected: >-
      The complete fixture is ready and each blocking fixture identifies its reason and any missing
      count.
    negative: true
    data_needs: Run and dataset records for the summary cases.
    bound_to:
      - TST-PFM-DJE-192
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is ready when the run
      succeeded and every record of every dataset is accounted for
    category: rule
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is ready when the run
        succeeded and every record of every dataset is accounted for
      - >-
        services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready after a
        validation run, however well it went, because it wrote nothing
      - >-
        services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready while
        records the domain rejected are unresolved, and says how many of which dataset
      - >-
        services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready when a
        dataset’s counts do not add up to what the producer claimed
  - id: ATS-PFM-DJE-016-11
    title: An unreadable job produces a failed step
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-11
    preconditions: A running dataset’s job becomes permanently unreadable.
    steps:
      - do: Perform the next progress pass.
        expect: The dataset fails with an explanatory message.
        provenance: test
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#fails
          the step when its owning service cannot be read at all, rather than running for ever
    expected: The dataset fails with an explanatory message.
    negative: true
    data_needs: An application double that cannot return the submitted job.
    bound_to:
      - TST-PFM-DJE-177
    provenance: test
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#fails
      the step when its owning service cannot be read at all, rather than running for ever
    category: failure
    binding_evidence:
      - >-
        services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#fails
        the step when its owning service cannot be read at all, rather than running for ever
  - id: ATS-PFM-DJE-016-12
    title: Downstream cancellation failure can leave a child running
    category: failure
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-13
    preconditions: Prepare a running run with an active CRM child and a pending dataset.
    steps:
      - do: >-
          Make child cancellation throw a non-access error, cancel the run, then read its parent and
          child; repeat with access denied.
        expect: >-
          The non-access failure is logged and the parent becomes cancelled with pending work
          skipped while the child can continue; access denial interrupts parent cancellation.
        provenance: proposed
        source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelStep'
    expected: >-
      The non-access failure is logged and the parent becomes cancelled with pending work skipped
      while the child can continue; access denial interrupts parent cancellation.
    negative: true
    data_needs: Prepare a running run with an active CRM child and a pending dataset.
    bound_to: []
    provenance: proposed
    source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelStep'
  - id: ATS-PFM-DJE-016-13
    title: A transient read respects the last successful progress write
    category: boundary
    level: api
    proves:
      - BR-CAP-PFM-DJE-016-14
    preconditions: Prepare a running dataset with a known last successful progress time.
    steps:
      - do: >-
          Return a transient read failure at exactly thirty minutes and just beyond it, then test
          access denial.
        expect: >-
          The step is unchanged at the grace boundary, fails beyond it, and access denial reaches
          the caller without rewriting progress.
        provenance: proposed
        source: >-
          services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep;
          services-platform:modules/data-jobs/services/runs/data-job-port.ts:DATA_JOB_UNREADABLE_GRACE_MS
    expected: >-
      The step is unchanged at the grace boundary, fails beyond it, and access denial reaches the
      caller without rewriting progress.
    negative: true
    data_needs: Prepare a running dataset with a known last successful progress time.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep;
      services-platform:modules/data-jobs/services/runs/data-job-port.ts:DATA_JOB_UNREADABLE_GRACE_MS
  - id: ATS-PFM-DJE-016-14
    title: Package registration checks recorded upload integrity
    category: interaction
    level: api
    exercises:
      - CAP-PFM-DJE-011
      - CAP-PFM-DJE-016
    proves:
      - BR-CAP-PFM-DJE-011-05
      - BR-CAP-PFM-DJE-011-06
      - BR-CAP-PFM-DJE-016-03
    preconditions: Complete manifest and dataset uploads with known sizes and a checkable digest.
    steps:
      - do: >-
          Register a package with a mismatched dataset digest, then one matching the saved upload
          evidence.
        expect: The mismatch leaves no run; the matching package registers before any dataset job starts.
        provenance: proposed
        source: >-
          services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:requireCompletedParts;
          services-platform:modules/data-jobs/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
          a completion whose object is not the file the declared SHA-256 describes, naming sha256;
          services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:verifiedDigestOf;
          services-platform:modules/data-jobs/services/runs/register-run.ts:registerRun
    expected: The mismatch leaves no run; the matching package registers before any dataset job starts.
    negative: false
    data_needs: Complete manifest and dataset uploads with known sizes and a checkable digest.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:requireCompletedParts;
      services-platform:modules/data-jobs/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
      a completion whose object is not the file the declared SHA-256 describes, naming sha256;
      services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:verifiedDigestOf;
      services-platform:modules/data-jobs/services/runs/register-run.ts:registerRun
  - id: ATS-PFM-DJE-016-15
    title: Dependency-driven datasets use the owning application
    category: interaction
    level: api
    exercises:
      - CAP-PFM-DJE-012
      - CAP-PFM-DJE-016
    proves:
      - BR-CAP-PFM-DJE-012-04
      - BR-CAP-PFM-DJE-012-07
      - BR-CAP-PFM-DJE-016-04
      - BR-CAP-PFM-DJE-016-06
      - BR-CAP-PFM-DJE-016-07
      - BR-CAP-PFM-DJE-016-08
    preconditions: >-
      Register a loading-workspace package with parent and child datasets and one unresolved
      reference.
    steps:
      - do: >-
          Start and poll the run, forwarding the staff caller's token, through both permitted
          attempts of the blocked dataset.
        expect: >-
          Dataset jobs respect dependency waves; the remaining block is visible in readiness and no
          third attempt is submitted.
        provenance: proposed
        source: >-
          macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#blocks
          the child, and a retry after the parent is loaded applies it and finishes the job;
          services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#keeps
          the archived option an initial import carries, as history;
          services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
          a package whose datasets cannot be ordered, before any row of it is written;
          services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#leaves
          the run where it stood while nobody reads it, though a dataset finished in its service;
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#forwards
          the staff caller’s own token with every call, and invents no identity of its own;
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#tries
          a blocked dataset a second time, and only a second time
    expected: >-
      Dataset jobs respect dependency waves; the remaining block is visible in readiness and no
      third attempt is submitted.
    negative: true
    data_needs: >-
      Register a loading-workspace package with parent and child datasets and one unresolved
      reference.
    bound_to: []
    provenance: proposed
    source: >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#blocks
      the child, and a retry after the parent is loaded applies it and finishes the job;
      services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#keeps
      the archived option an initial import carries, as history;
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      a package whose datasets cannot be ordered, before any row of it is written;
      services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#leaves
      the run where it stood while nobody reads it, though a dataset finished in its service;
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#forwards
      the staff caller’s own token with every call, and invents no identity of its own;
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#tries
      a blocked dataset a second time, and only a second time
  - id: ATS-PFM-DJE-016-16
    title: Completion with refusals remains visible in reconciliation
    category: interaction
    level: api
    exercises:
      - CAP-PFM-DJE-015
      - CAP-PFM-DJE-016
    proves:
      - BR-CAP-PFM-DJE-015-01
      - BR-CAP-PFM-DJE-015-02
      - BR-CAP-PFM-DJE-016-10
    preconditions: Drive a package whose child completes with one refusal and otherwise saved records.
    steps:
      - do: >-
          Poll the run to settlement, inspect readiness, and look up the accepted and refused
          producer keys.
        expect: >-
          The run can finish succeeded while readiness names the refusal; accepted keys resolve and
          the refused creation is missing.
        provenance: proposed
        source: >-
          services-crm:modules/data-jobs/tests/integration/services/jobs/records-by-source-key.integration.spec.js#answers
          each record exactly as the ordinary read of one contact does;
          services-crm:modules/data-jobs/services/jobs/records-by-source-key.ts:readRecordsBySourceKey;
          services-platform:modules/data-jobs/services/jobs/records-by-source-key.ts:readCustomFieldsBySourceKey;
          services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready when a
          dataset’s counts do not add up to what the producer claimed
    expected: >-
      The run can finish succeeded while readiness names the refusal; accepted keys resolve and the
      refused creation is missing.
    negative: true
    data_needs: Drive a package whose child completes with one refusal and otherwise saved records.
    bound_to: []
    provenance: proposed
    source: >-
      services-crm:modules/data-jobs/tests/integration/services/jobs/records-by-source-key.integration.spec.js#answers
      each record exactly as the ordinary read of one contact does;
      services-crm:modules/data-jobs/services/jobs/records-by-source-key.ts:readRecordsBySourceKey;
      services-platform:modules/data-jobs/services/jobs/records-by-source-key.ts:readCustomFieldsBySourceKey;
      services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready when a
      dataset’s counts do not add up to what the producer claimed
  - id: ATS-PFM-DJE-016-17
    title: Failed loading remains available for reset and a fresh run
    category: interaction
    level: api
    exercises:
      - CAP-PFM-DJE-016
      - CAP-PFM-DJE-017
    proves:
      - BR-CAP-PFM-DJE-016-09
      - BR-CAP-PFM-DJE-016-10
      - BR-CAP-PFM-DJE-017-02
      - BR-CAP-PFM-DJE-017-04
      - BR-CAP-PFM-DJE-017-05
    preconditions: Start a package with a dataset that fails after earlier work committed.
    steps:
      - do: 'Inspect the failed run, reset the loading workspace, register corrected input and reload.'
        expect: >-
          Earlier commits remain until reset; a new registration drives the corrected load without
          reopening the failed run.
        provenance: proposed
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#cancels
          the jobs a cancelled run had already submitted, in their own services;
          services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready when a
          dataset’s counts do not add up to what the producer claimed;
          services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#removes
          everything the load wrote: no contact, organization, imported type or crosswalk row is
          left;
          services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#reloads
          the same records as the load before the reset, numbers included;
          services-platform:docs/data-jobs/tenant-reset.md#1. When a tenant may be reset
    expected: >-
      Earlier commits remain until reset; a new registration drives the corrected load without
      reopening the failed run.
    negative: true
    data_needs: Start a package with a dataset that fails after earlier work committed.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#cancels
      the jobs a cancelled run had already submitted, in their own services;
      services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready when a
      dataset’s counts do not add up to what the producer claimed;
      services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#removes
      everything the load wrote: no contact, organization, imported type or crosswalk row is left;
      services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#reloads
      the same records as the load before the reset, numbers included;
      services-platform:docs/data-jobs/tenant-reset.md#1. When a tenant may be reset
  - id: ATS-PFM-DJE-016-18
    title: Platform datasets use the same domain authority as direct jobs
    category: interaction
    level: api
    exercises:
      - CAP-PFM-DJE-016
      - CAP-PFM-DJE-018
    proves:
      - BR-CAP-PFM-DJE-016-07
      - BR-CAP-PFM-DJE-016-12
      - BR-CAP-PFM-DJE-018-07
      - BR-CAP-PFM-DJE-018-08
    preconditions: >-
      Register a package with custom definitions, records and associations and prepare limited and
      authorized staff contexts.
    steps:
      - do: >-
          Start under insufficient domain authority, then under authorized authority and inspect
          each local job.
        expect: >-
          The refusal leaves the run unchanged; permitted local datasets use domain validation and
          preserve line-specific refusals.
        provenance: proposed
        source: >-
          services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#forwards
          the staff caller’s own token with every call, and invents no identity of its own;
          services-platform:modules/data-jobs/services/runs/data-run-services.ts:DATA_RUN_SERVICES;
          services-platform:modules/data-jobs/tests/integration/services/jobs/custom-field-data-jobs.integration.spec.js#refuses
          a caller who may create a definition but holds no bulk right;
          services-platform:modules/data-jobs/tests/integration/services/jobs/custom-object-data-jobs.integration.spec.js#refuses
          a hull number an earlier line of the same file holds, naming that line
    expected: >-
      The refusal leaves the run unchanged; permitted local datasets use domain validation and
      preserve line-specific refusals.
    negative: true
    data_needs: >-
      Register a package with custom definitions, records and associations and prepare limited and
      authorized staff contexts.
    bound_to: []
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#forwards
      the staff caller’s own token with every call, and invents no identity of its own;
      services-platform:modules/data-jobs/services/runs/data-run-services.ts:DATA_RUN_SERVICES;
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-field-data-jobs.integration.spec.js#refuses
      a caller who may create a definition but holds no bulk right;
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-object-data-jobs.integration.spec.js#refuses
      a hull number an earlier line of the same file holds, naming that line
evidence:
  - >-
    services-platform: inspected package registration, dependency ordering, driver controls,
    readiness summaries, run persistence and the cited API, integration and unit suites.
  - 'services-crm: inspected the documented dataset job route pattern used by a Data Run.'
  - >-
    Testing back-fill: related capability rules, domain invariants, state transitions and crossing
    workflows at the pinned source revisions.
coverage:
  rule: covered
  transition: 'gap: FND-PFM-DJE-076'
  validation: covered
  permission: covered
  edge: covered
  failure: covered
  boundary: covered
  concurrency: 'gap: FND-PFM-DJE-076'
  invariant: 'gap: FND-PFM-DJE-076'
  interaction: covered
coverage_notes:
  transition: >-
    Selected lifecycle examples do not cover every applicable object and batch transition. The
    linked finding retains the remaining matrix.
  execution: >-
    Covered means a specification scenario exists. Proposed scenarios and registered suites with no
    run result do not establish executed conformance.
related:
  - CAP-PFM-DJE-011
  - CAP-PFM-DJE-012
  - CAP-PFM-DJE-015
  - CAP-PFM-DJE-017
workflows:
  - WF-PFM-DJE-009
  - WF-PFM-DJE-011
  - WF-PFM-DJE-012
  - WF-PFM-DJE-013
coverage_evidence:
  - rule: BR-CAP-PFM-DJE-016-01
    scenarios:
      - ATS-PFM-DJE-016-01
    provenance: proposed
    source: 'services-platform:modules/data-jobs/aws/api/data-runs.routes.ts:manage'
  - rule: BR-CAP-PFM-DJE-016-02
    scenarios:
      - ATS-PFM-DJE-016-02
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      an initial import into a tenant that is not loading
  - rule: BR-CAP-PFM-DJE-016-03
    scenarios:
      - ATS-PFM-DJE-016-03
      - ATS-PFM-DJE-016-14
    provenance: proposed
    source: 'services-platform:modules/data-jobs/services/runs/register-run.ts:registerRun'
  - rule: BR-CAP-PFM-DJE-016-04
    scenarios:
      - ATS-PFM-DJE-016-04
      - ATS-PFM-DJE-016-15
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      a package whose datasets cannot be ordered, before any row of it is written
  - rule: BR-CAP-PFM-DJE-016-05
    scenarios:
      - ATS-PFM-DJE-016-05
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/register-run.integration.spec.js#refuses
      a second registration of a package whose run has not finished, naming the run that holds it
  - rule: BR-CAP-PFM-DJE-016-06
    scenarios:
      - ATS-PFM-DJE-016-06
      - ATS-PFM-DJE-016-15
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/lifecycle/data-run-guarantees.integration.spec.js#leaves
      the run where it stood while nobody reads it, though a dataset finished in its service
  - rule: BR-CAP-PFM-DJE-016-07
    scenarios:
      - ATS-PFM-DJE-016-07
      - ATS-PFM-DJE-016-15
      - ATS-PFM-DJE-016-18
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#forwards
      the staff caller’s own token with every call, and invents no identity of its own
  - rule: BR-CAP-PFM-DJE-016-08
    scenarios:
      - ATS-PFM-DJE-016-08
      - ATS-PFM-DJE-016-15
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#tries
      a blocked dataset a second time, and only a second time
  - rule: BR-CAP-PFM-DJE-016-09
    scenarios:
      - ATS-PFM-DJE-016-09
      - ATS-PFM-DJE-016-17
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/integration/services/runs/run-driver.integration.spec.js#cancels
      the jobs a cancelled run had already submitted, in their own services
  - rule: BR-CAP-PFM-DJE-016-10
    scenarios:
      - ATS-PFM-DJE-016-10
      - ATS-PFM-DJE-016-16
      - ATS-PFM-DJE-016-17
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/tests/unit/run-summary.spec.ts#is not ready when a
      dataset’s counts do not add up to what the producer claimed
  - rule: BR-CAP-PFM-DJE-016-11
    scenarios:
      - ATS-PFM-DJE-016-11
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep;
      services-platform:modules/data-jobs/services/runs/run-driver.ts:submitStep
  - rule: BR-CAP-PFM-DJE-016-13
    scenarios:
      - ATS-PFM-DJE-016-12
    provenance: proposed
    source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelStep'
  - rule: BR-CAP-PFM-DJE-016-14
    scenarios:
      - ATS-PFM-DJE-016-13
    provenance: proposed
    source: >-
      services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep;
      services-platform:modules/data-jobs/services/runs/data-job-port.ts:DATA_JOB_UNREADABLE_GRACE_MS
---

# Load and reconcile a migration package across its owning applications: Capability Test Specification

## Coverage

The structured coverage rows link required rules to their scenarios. A covered category has a defined check; executable coverage and successful execution require separate evidence. The category map keeps incomplete lifecycle matrices and other missing checks visible as findings.

## Interactions With Related Capabilities

Package registration checks recorded upload integrity. Dependency-driven datasets use the owning application. Completion with refusals remains visible in reconciliation. Failed loading remains available for reset and a fresh run. Platform datasets use the same domain authority as direct jobs. The interaction scenarios use the related capabilities' rule references and identify the shared fixture and observable outcome.
