---
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
finding_evidence:
  - finding: FND-PFM-DJE-001
    source: >-
      services-platform:modules/tenants/aws/api/hq-tenant-loading.routes.ts:activateHqTenant;
      docs/milestones/plans/PLAT-M22-plan.md#A3
    provenance: documented
  - finding: FND-PFM-DJE-002
    source: >-
      macroservice-libraries:packages/data-jobs/src/data-job-config.ts; submission-purge.ts;
      docs/milestones/PLAT-M19-data-job-engine-foundations.md#D6;
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0668.json
    provenance: documented
  - finding: FND-PFM-DJE-003
    source: >-
      macroservice-libraries:packages/data-jobs/src/job-control.ts;
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0662.json
    provenance: documented
  - finding: FND-PFM-DJE-004
    source: >-
      services-crm:docs/milestones/CRM-M7-data-operations.md#M2-D13;
      modules/data-jobs/services/operations/contact-import.ts (keep_automatic_roles)
    provenance: documented
  - finding: FND-PFM-DJE-005
    source: >-
      react-console:lib/api/data-jobs/rules.ts:ROLLBACK_SUPPORTED; lib/authz/backend-aliases.ts;
      services-crm:modules/data-jobs/aws/api/organization-data-jobs.routes.ts:rollbackOrganizationDataJob;
      macroservice-libraries:packages/data-jobs/README.md#Rolling a job back
    provenance: documented
  - finding: FND-PFM-DJE-006
    source: >-
      services-crm:docs/data-jobs.md#Putting a bulk change back;
      docs/debt/rollback-of-collections.md;
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0659.json
    provenance: documented
  - finding: FND-PFM-DJE-007
    source: >-
      services-crm:docs/data-jobs.md#Deleting records in bulk;
      docs/milestones/CRM-M7-data-operations.md#D-41
    provenance: documented
  - finding: FND-PFM-DJE-008
    source: >-
      services-crm:docs/data-jobs.md#What is not built; #Records with files; #The bulk lane; #The
      routes; modules/data-jobs/aws/api/organization-data-jobs.routes.ts
    provenance: documented
  - finding: FND-PFM-DJE-009
    source: >-
      react-console:acceptance/data-jobs/inventory/business-rules.json#RUL-DJE-ENG-007,
      RUL-DJE-ENG-028, RUL-DJE-ENG-026; services-crm:docs/data-jobs.md#Concurrent edits
    provenance: documented
  - finding: FND-PFM-DJE-010
    source: >-
      services-platform:docs/data-jobs/uploads.md#Integrity;
      modules/data-jobs/services/runs/register-run.ts
    provenance: documented
  - finding: FND-PFM-DJE-011
    source: >-
      services-platform:docs/data-jobs/uploads.md#Archives: what a later step must do;
      services-crm:docs/data-jobs.md#The bulk lane
    provenance: documented
  - finding: FND-PFM-DJE-012
    source: 'services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#Status history'
    provenance: documented
  - finding: FND-PFM-DJE-013
    source: >-
      services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#D3;
      services-crm:docs/debt/configuration-type-status.md
    provenance: documented
  - finding: FND-PFM-DJE-014
    source: 'services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#D2'
    provenance: documented
  - finding: FND-PFM-DJE-015
    source: >-
      services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#D4;
      react-console:lib/api/data-jobs/capabilities.ts;
      acceptance/data-jobs/journeys/dialogs/DJE-ACC-0115.json
    provenance: documented
  - finding: FND-PFM-DJE-016
    source: >-
      services-crm:docs/data-jobs.md#Listing a tenant's jobs;
      services-platform:docs/data-jobs/platform-data-operations.md#The surfaces
    provenance: documented
  - finding: FND-PFM-DJE-017
    source: >-
      react-console:lib/api/data-jobs/crm.ts:CRM_SERVES_ITEM_TOOLS;
      services-platform:docs/milestones/plans/PLAT-M21-plan.md#Added 2026-10-22 (from PLAT-M19
      review R3): results at scale, server side
    provenance: documented
  - finding: FND-PFM-DJE-018
    source: >-
      react-console:acceptance/data-jobs/inventory/capabilities.json#CAP-DJE-ENG-006;
      services-platform:docs/milestones/plans/PLAT-M21-plan.md#10. Walkthrough preview
    provenance: documented
  - finding: FND-PFM-DJE-019
    source: >-
      services-membership:modules/data-jobs/services/operations/structure-data-operations.ts;
      export/import-crosswalk.dataset.ts;
      services-platform:modules/data-jobs/services/runs/data-run-services.ts
    provenance: documented
  - finding: FND-PFM-DJE-020
    source: >-
      services-crm:docs/data-jobs.md#Reading a load back by source key;
      modules/data-jobs/aws/api/bulk-data-jobs.routes.ts:BULK_SUBMISSIONS
    provenance: documented
  - finding: FND-PFM-DJE-021
    source: >-
      services-platform:docs/partitions.md; db/partitioned-tables.ts;
      macroservice-libraries:packages/data-jobs/README.md#Partitioning is deferred
    provenance: documented
  - finding: FND-PFM-DJE-022
    source: >-
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0673.json;
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0674.json;
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0679.json;
      services-platform:modules/capacity/tests/README.md
    provenance: documented
  - finding: FND-PFM-DJE-023
    source: specs/PRODUCT-AREAS.md (MOD-PFM-DJE row); react-console tree at baf6dae3
    provenance: documented
  - finding: FND-PFM-DJE-024
    source: >-
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0645.json;
      services-crm:docs/data-jobs.md#What is not built
    provenance: documented
  - finding: FND-PFM-DJE-025
    source: >-
      react-console:lib/api/data-jobs/capabilities.ts;
      services-crm:modules/data-jobs/aws/api/bulk-data-jobs.routes.ts:regionDataJobsRoutes
    provenance: documented
  - finding: FND-PFM-DJE-026
    source: 'services-crm:docs/data-jobs.md#Spreadsheet columns (D-40, DEF-CRM-0660)'
    provenance: documented
  - finding: FND-PFM-DJE-027
    source: 'react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0644.json'
    provenance: documented
  - finding: FND-PFM-DJE-028
    source: >-
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0667.json;
      services-crm:docs/data-jobs.md#Listing a tenant's jobs
    provenance: documented
  - finding: FND-PFM-DJE-029
    source: >-
      services-platform:docs/data-jobs/platform-data-operations.md#7. What a third macroservice
      would add
    provenance: documented
  - finding: FND-PFM-DJE-030
    source: >-
      services-crm:docs/data-jobs.md#Listing a tenant's jobs;
      modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#counts
      every batch it planned as finished, which is what lets a client say “batch 7 of 20”
    provenance: documented
  - id: FND-PFM-DJE-031
    provenance: observed
    source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelStep'
  - id: FND-PFM-DJE-032
    provenance: observed
    source: 'services-platform:modules/data-jobs/services/runs/run-summary.ts:readinessBlockers'
  - id: FND-PFM-DJE-033
    provenance: observed
    source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:submitStep'
  - id: FND-PFM-DJE-034
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep;
      services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelStep
  - id: FND-PFM-DJE-035
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/persistence/data-runs.ts:registerDataRun;
      services-platform:modules/data-jobs/db/data-runs.table.ts:dataRuns
  - id: FND-PFM-DJE-036
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/runs/register-run.ts:resolveDatasetUploads;
      services-platform:modules/data-jobs/aws/api/data-jobs.schemas.ts:dataRunRequestSchema
  - id: FND-PFM-DJE-037
    provenance: observed
    source: 'services-platform:modules/data-jobs/services/runs/register-run.ts:requireDestination'
  - id: FND-PFM-DJE-038
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/runs/data-job-port.ts:readProgress;
      services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun
  - id: FND-PFM-DJE-039
    provenance: observed
    source: 'services-platform:modules/data-jobs/aws/api/custom-field-data-jobs.routes.ts'
  - id: FND-PFM-DJE-040
    provenance: observed
    source: >-
      services-platform:docs/data-jobs/uploads.md#Part size;
      services-platform:modules/data-jobs/db/data-job-uploads.table.ts:partSizeOf
  - id: FND-PFM-DJE-041
    provenance: observed
    source: >-
      macroservice-libraries:packages/data-jobs/src/chunk-source.ts:closedGroupKeys;
      macroservice-libraries:packages/data-jobs/src/chunk-plan.ts:shouldCloseChunk
  - id: FND-PFM-DJE-042
    provenance: inferred
    source: >-
      specs/platform/data-job-engine/reports/EXAMINATION-2026-10-22.md#Remaining Suite Examination;
      specs/platform/data-job-engine/MODULE.md:coverage_catalog
    note: >-
      The recorded inventories exceed the selected semantic reviews described in the two-pass
      report, so exhaustive completion cannot be inferred from anchor checks or final wording.
  - id: FND-PFM-DJE-043
    provenance: observed
    source: 'macroservice-libraries:packages/data-jobs/src/row-level-security.ts:PRIVILEGES'
  - id: FND-PFM-DJE-044
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:completeUpload;
      services-platform:modules/data-jobs/services/uploads/upload-storage.ts:completeMultipartUpload
  - id: FND-PFM-DJE-045
    provenance: documented
    source: specs/CONVENTIONS.md#9.8 Inference Operation (IOP); specs/platform/data-job-engine/MODULE.md
  - id: FND-PFM-DJE-046
    provenance: observed
    source: >-
      react-console:lib/api/data-jobs/object-types.ts:OBJECT_TYPE_ENTRIES;
      react-console:lib/api/data-jobs/crm.ts;
      services-crm:modules/data-jobs/aws/api/bulk-data-jobs.routes.ts:BULK_SUBMISSIONS;
      services-platform:modules/data-jobs/aws/api/data-jobs.routes.ts:dataJobsRoutes
  - id: FND-PFM-DJE-047
    provenance: inferred
    source: >-
      services-platform:modules/data-jobs/services/jobs/custom-field-data-jobs.ts:runQueuedBatches;
      macroservice-libraries:packages/data-jobs/src/batch-queue-dispatcher.ts:dispatchDataJobBatches;
      macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob, retryDataJob;
      services-platform:modules/data-jobs/aws/logic/data-jobs-api.lambda.ts (timeoutSeconds 30)
    note: >-
      The claim deletes the queue entries of every claimed batch before any of them runs, and
      nothing else finds a pending batch without a queue entry; the consequence for an interrupted
      request is deduced, not executed.
  - id: FND-PFM-DJE-048
    provenance: observed
    source: >-
      services-crm:modules/data-jobs/services/jobs/data-job-submission-purge.ts;
      macroservice-libraries:packages/data-jobs/src/submission-purge.ts:purgeDataJobSubmissions;
      services-platform:modules (no caller of purgeDataJobSubmissions at the pinned commit)
  - id: FND-PFM-DJE-049
    provenance: observed
    source: >-
      services-platform:docs/row-level-security.md (table of forced policies, the data-job tables
      row);
      macroservice-libraries:packages/data-jobs/src/data-job-columns.ts:dataJobRejectionColumns
  - id: FND-PFM-DJE-050
    provenance: observed
    source: >-
      macroservice-libraries:packages/data-jobs/src/data-id-mappings.ts:sqlDataIdMappingStore;
      macroservice-libraries:packages/data-jobs/src/apply-keyed-item.ts:applyDataJobItem
  - id: FND-PFM-DJE-051
    provenance: observed
    source: >-
      services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState;
      rhythm-v2-docs:specs/platform/data-job-engine/planning/capabilities/CAP-PFM-DJE-019-hold-the-platform-s-protection-state-while-the-database-is.md
  - id: FND-PFM-DJE-052
    provenance: observed
    source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
  - id: FND-PFM-DJE-053
    provenance: observed
    source: >-
      rhythm-v2-docs:briefs/design/platform-data-job-engine.brief.md (absent at
      1070cb57a7637fe65287eee492a7bd0275f77d80); specs/platform/data-job-engine/planning/**:status,
      product_intent
  - id: FND-PFM-DJE-054
    provenance: observed
    source: >-
      macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob;
      packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS;
      packages/data-jobs/src/sql-data-job-repository.ts:setJobState
  - id: FND-PFM-DJE-055
    provenance: observed
    source: >-
      react-console:lib/api/data-jobs/selection.ts:collectDataJobIds;
      components/data-management/data-jobs/bulk/data-job-bulk-actions.tsx
  - id: FND-PFM-DJE-056
    provenance: observed
    source: >-
      react-console:components/data-management/data-jobs/bulk/data-job-bulk-actions.tsx;
      lib/api/data-jobs/bulk-actions.ts:dataJobBulkActionOffers; lib/authz/backend-aliases.ts;
      components/data-management/data-jobs/new/step-what.tsx
question_evidence:
  - id: OQ-PFM-DJE-001
    provenance: proposed
    source: >-
      services-platform:docs/data-jobs/uploads.md#Integrity;
      modules/data-jobs/services/runs/register-run.ts
  - id: OQ-PFM-DJE-002
    provenance: proposed
    source: 'services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#D2'
  - id: OQ-PFM-DJE-003
    provenance: proposed
    source: >-
      services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#D3;
      services-crm:docs/debt/configuration-type-status.md
  - id: OQ-PFM-DJE-004
    provenance: proposed
    source: >-
      services-platform:docs/partitions.md; db/partitioned-tables.ts;
      macroservice-libraries:packages/data-jobs/README.md#Partitioning is deferred
  - id: OQ-PFM-DJE-005
    provenance: proposed
    source: >-
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0645.json;
      services-crm:docs/data-jobs.md#What is not built
  - id: OQ-PFM-DJE-006
    provenance: proposed
    source: 'services-crm:docs/data-jobs.md#Spreadsheet columns (D-40, DEF-CRM-0660)'
  - id: OQ-PFM-DJE-007
    provenance: proposed
    source: >-
      macroservice-libraries:packages/data-jobs/README.md#What this package does not do;
      services-crm:modules/data-jobs/services/queue/data-job-worker.ts;
      react-console:lib/api/data-jobs/hooks.ts
  - id: OQ-PFM-DJE-008
    provenance: proposed
    source: >-
      services-platform:modules/capacity/services/capacity/apply-emergency-throttles.ts:CAPACITY_EMERGENCY_THROTTLES_VARIABLE;
      services-platform:modules/capacity/aws/logic/capacity-sentinel.lambda.ts
control_gap_evidence:
  - finding: FND-PFM-DJE-057
    controls:
      - TC-DAT-003
    provenance: documented
    source: >-
      macroservice-libraries:packages/data-jobs/src/data-job-config.ts; submission-purge.ts;
      docs/milestones/PLAT-M19-data-job-engine-foundations.md#D6;
      react-console:acceptance/crm/journeys/data-operations/CRM-ACC-0668.json
    related_finding: FND-PFM-DJE-002
  - finding: FND-PFM-DJE-058
    controls:
      - TC-PI-002
      - TC-PI-003
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/persistence/data-runs.ts:registerDataRun;
      services-platform:modules/data-jobs/db/data-runs.table.ts:dataRuns
    related_finding: FND-PFM-DJE-035
  - finding: FND-PFM-DJE-059
    controls:
      - TC-AVL-004
      - TC-PI-004
    provenance: observed
    source: >-
      services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:completeUpload;
      services-platform:modules/data-jobs/services/uploads/upload-storage.ts:completeMultipartUpload
    related_finding: FND-PFM-DJE-044
  - finding: FND-PFM-DJE-060
    controls:
      - TC-PI-002
      - TC-PI-003
    provenance: observed
    source: >-
      macroservice-libraries:packages/data-jobs/src/data-id-mappings.ts:sqlDataIdMappingStore;
      macroservice-libraries:packages/data-jobs/src/apply-keyed-item.ts:applyDataJobItem
    related_finding: FND-PFM-DJE-050
testing_gap_evidence:
  - id: FND-PFM-DJE-061
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-001-submit-one-audited-job-that-changes-many-records.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/e2e/data-jobs.e2e.spec.js#refuses a caller who may update
      one contact but holds no bulk key with 403;
      services-crm:modules/data-jobs/tests/e2e/organization-update.e2e.spec.js#refuses a selection
      past the interactive lane’s 500 with 400;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
      a field the bulk update may not set, naming it, before any contact is touched;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#freezes
      the patch on every item, so a later apply writes what was submitted and not what is asked for
      then;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#answers
      the second submission with the first job, having written nothing;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
      an object type CRM performs no bulk operation on, naming what it does perform;
      services-crm:modules/data-jobs/aws/api/data-jobs.schemas.ts:dataJobRequestSchema;
      services-crm:modules/data-jobs/tests/integration/services/jobs/configuration-data-jobs.integration.spec.js#is
      not found by the apply, so a validated job of contacts cannot be started from here;
      macroservice-libraries:packages/data-jobs/src/tests/integration/tenant-isolation.integration.spec.ts#does
      not let another tenant see a job, or learn that it exists;
      macroservice-libraries:packages/data-jobs/README.md#A worked example: updating contacts in
      bulk
    missing_categories:
      - rule
      - transition
      - failure
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-001-10
      - ATS-PFM-DJE-001-11
      - ATS-PFM-DJE-001-12
      - ATS-PFM-DJE-001-13
      - ATS-PFM-DJE-001-14
      - ATS-PFM-DJE-001-15
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: crm.contact-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.contact-roles.bulk
        where_checked: api
        scope: tenant
      - key: crm.organization-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.address-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.phone-number-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.regions.bulk
        where_checked: api
        scope: tenant
      - key: crm.activity-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.activities.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.update
        where_checked: api
        scope: tenant
      - key: crm.contacts.delete
        where_checked: api
        scope: tenant
      - key: crm.organizations.update
        where_checked: api
        scope: tenant
      - key: crm.organizations.delete
        where_checked: api
        scope: tenant
      - key: platform.custom-fields.bulk
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-001
      - WF-PFM-DJE-009
      - WF-PFM-DJE-018
      - WF-PFM-DJE-020
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-062
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-002-preview-what-a-job-will-do-and-approve-exactly-that.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#changes
      nothing while it is validating;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
      an apply of the validated update whose digest is not the one the validation answered;
      macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob;
      services-crm:modules/data-jobs/tests/e2e/organization-update.e2e.spec.js#refuses the apply of
      a job that was never validated with 409, because an apply is the approval of a validation;
      macroservice-libraries:packages/data-jobs/src/define-data-operation.spec.ts#adds the counts,
      which is what makes a digest speak for every batch and not the last one;
      services-crm:modules/data-jobs/aws/api/bulk-data-jobs.schemas.ts;
      services-platform:modules/data-jobs/services/jobs/custom-field-data-jobs.ts:submitPlatformDataJob;
      react-console:components/data-management/data-jobs/new/step-validate.tsx;
      services-crm:docs/data-jobs.md#Listing a tenant's jobs
    missing_categories:
      - transition
      - permission
      - edge
      - failure
      - concurrency
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-002-03
      - ATS-PFM-DJE-002-06
      - ATS-PFM-DJE-002-07
      - ATS-PFM-DJE-002-08
      - ATS-PFM-DJE-002-09
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.update
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: platform.custom-fields.bulk
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-001
      - WF-PFM-DJE-003
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-063
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-003-apply-every-good-record-and-set-aside-every-bad-one.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/queue/data-job-worker.integration.spec.js#changes
      each contact once between them, whichever delivery got there first;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
      the other five, counting each as what refused it;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#rejects
      that contact as not found, which tells the person nothing about a record they may not see;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#names
      the rule a refused value broke, and quotes no value of the record;
      macroservice-libraries:packages/data-jobs/src/commit-split.spec.ts#halves the unit until the
      failing object stands alone, and isolates only it;
      macroservice-libraries:packages/data-jobs/src/tests/integration/group-refusals.integration.spec.ts#writes
      none of the group, rejects the other two as group_member_refused, and applies the items of no
      group; macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict;
      services-crm:docs/data-jobs.md#What each contact's outcome can be;
      services-crm:modules/data-jobs/tests/integration/services/queue/data-job-worker.integration.spec.js#fails
      the whole job with the code, not just the batch; services-crm:docs/data-jobs.md#Imports;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#writes
      no revision, so the history names only the job that changed the contact
    missing_categories:
      - transition
      - validation
    unbound_scenarios:
      - ATS-PFM-DJE-003-08
      - ATS-PFM-DJE-003-11
      - ATS-PFM-DJE-003-12
      - ATS-PFM-DJE-003-13
      - ATS-PFM-DJE-003-14
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.update
        where_checked: service
        scope: record
      - key: crm.contacts.bulk
        where_checked: service
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-002
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-064
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-004-pause-resume-cancel-or-retry-a-job-safely.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      macroservice-libraries:packages/data-jobs/src/data-job-states.spec.ts#leaves every final state
      with nowhere to go, but for the retry of blocked items the plan allows;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
      the job cancelled, not failed, once the batch it waited for has finished;
      macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
      a job paused before its source was read, and runs it to the end once resumed;
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#refuses
      to retry a job whose refusals are not blocked items, because correcting records is a new job;
      macroservice-libraries:packages/data-jobs/src/tests/integration/rollback-and-retry.integration.spec.ts#refuses
      to retry a job that has been rolled back, so its blocked rows are not written after the undo;
      services-crm:docs/data-jobs.md#What a job may be asked now: `actions` (D-39);
      services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
      the data job, so its status read answers failed and a Data Run polling it stops;
      react-console:lib/api/data-jobs/rules.ts:DATA_JOB_ACTIONS_NEEDING_CONFIRMATION
    missing_categories:
      - rule
      - transition
      - validation
      - boundary
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-004-08
      - ATS-PFM-DJE-004-09
      - ATS-PFM-DJE-004-10
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: data.jobs.control
        where_checked: console
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-004
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-065
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-005-follow-a-job-and-trace-every-change-it-made.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/jobs/list-contact-data-jobs.integration.spec.js#answers
      a caller without the bulk key only the jobs they submitted;
      services-crm:modules/data-jobs/tests/e2e/data-jobs.e2e.spec.js#refuses a state no job can be
      in with 400, rather than a filter it quietly ignores;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#answers
      the next page from the cursor the last one gave, so no item is read twice;
      services-crm:docs/data-jobs.md#Listing a tenant's jobs;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#stamps
      the job on the revision, so every record one job changed can be listed;
      services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D3;
      services-platform:docs/milestones/PLAT-M19-data-job-engine-foundations.md#D6;
      macroservice-libraries:packages/data-jobs/src/tests/integration/submission-purge.integration.spec.ts#deletes
      the tenant's rows older than 30 days and keeps the rest, the row exactly 30 days old included;
      services-platform:docs/milestones/plans/PLAT-M21-plan.md#Added 2026-10-22 (from PLAT-M19
      review R3): results at scale, server side;
      services-crm:modules/data-jobs/tests/integration/services/jobs/data-job-instants.integration.spec.js#answers
      a finished apply’s submission, queueing, start and finish in ISO 8601
    missing_categories:
      - transition
      - edge
      - failure
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-005-05
      - ATS-PFM-DJE-005-07
      - ATS-PFM-DJE-005-08
      - ATS-PFM-DJE-005-09
      - ATS-PFM-DJE-005-10
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: platform.custom-fields.bulk
        where_checked: api
        scope: tenant
      - key: platform.custom-records.update
        where_checked: service
        scope: tenant
      - key: data.jobs.view
        where_checked: console
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-002
      - WF-PFM-DJE-018
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-066
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-006-never-overwrite-a-colleague-s-edit-made-during-a-bulk-change.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-update-versions.integration.spec.js#skips
      the contact that changed after the validation as a named conflict;
      services-crm:modules/data-jobs/services/operations/contact-update.ts:prevalidate;
      services-crm:docs/data-jobs.md#What each contact's outcome can be;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-update-versions.integration.spec.js#applies
      the contact whose colleague made the very change the job asks for, rather than calling it a
      conflict;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-update-versions.integration.spec.js#makes
      the revalidation a new validation of the one conflicted contact, linked to the job it
      corrects;
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#refuses
      the delivery as a conflict and leaves the record alone;
      macroservice-libraries:packages/data-jobs/src/keyed-item-decision.ts:decideKeyedItem;
      macroservice-libraries:packages/data-jobs/README.md#Keyed writes and the ID crosswalk;
      macroservice-libraries:packages/data-jobs/README.md#Versions: captured at validation, verified
      at application
    missing_categories:
      - transition
      - permission
      - failure
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-006-03
      - ATS-PFM-DJE-006-08
      - ATS-PFM-DJE-006-09
      - ATS-PFM-DJE-006-10
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
      - INV-DOM-PFM-DJE-004-01
      - INV-DOM-PFM-DJE-004-02
      - INV-DOM-PFM-DJE-004-03
      - INV-DOM-PFM-DJE-004-04
      - INV-DOM-PFM-DJE-004-05
      - INV-DOM-PFM-DJE-004-06
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.update
        where_checked: service
        scope: record
      - key: crm.organizations.update
        where_checked: service
        scope: record
    workflow_matrix:
      - WF-PFM-DJE-002
      - WF-PFM-DJE-006
      - WF-PFM-DJE-007
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-067
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-007-delete-records-in-bulk-only-after-a-counted-typed-approval.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
      a delete submitted to be applied, because a delete is validated first;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#counts
      the rows each delete would take with it, per collection, as the contacts hold them;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
      an apply whose confirmation names another number of contacts;
      services-crm:modules/data-jobs/tests/integration/services/jobs/organization-delete.integration.spec.js#refuses
      the one the contact now belongs to as a conflict, because the delete approved was another one;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
      the unlocked contact at the apply with the code the validation refused it with, saying why;
      services-crm:modules/data-jobs/tests/integration/services/jobs/organization-delete.integration.spec.js#names,
      per organization, what stopped it, with the counts in the message;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#removed,
      per collection, exactly the number of rows the validation had counted;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-update-rollback.integration.spec.js#refuses
      the rollback, because there is no undo for a hard delete;
      services-crm:docs/data-jobs.md#Deleting records in bulk;
      react-console:lib/api/data-jobs/capabilities.ts:DATA_JOB_CAPABILITIES
    missing_categories:
      - transition
      - permission
      - failure
      - boundary
    unbound_scenarios:
      - ATS-PFM-DJE-007-09
      - ATS-PFM-DJE-007-10
      - ATS-PFM-DJE-007-11
      - ATS-PFM-DJE-007-12
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.delete
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.delete
        where_checked: api
        scope: tenant
      - key: crm.activities.bulk
        where_checked: api
        scope: tenant
      - key: crm.activities.delete
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-001
      - WF-PFM-DJE-003
      - WF-PFM-DJE-019
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-068
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-008-put-a-bulk-change-back-without-losing-later-edits.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-update-rollback.integration.spec.js#plans
      it already validated, because planning a rollback IS validating it;
      services-crm:modules/data-jobs/tests/integration/services/jobs/contact-update-rollback.integration.spec.js#says
      which field changed since the job and when, without saying what it was changed to;
      macroservice-libraries:packages/data-jobs/src/tests/integration/rollback-and-retry.integration.spec.ts#refuses
      a rollback plan with an unversioned item, and writes no rollback job;
      macroservice-libraries:packages/data-jobs/src/data-job-actions.spec.ts#does not offer Rollback
      once a rollback has been applied, by the code the route answers, and still does while one is
      only planned; services-crm:docs/data-jobs.md#Putting a bulk change back;
      macroservice-libraries:packages/data-jobs/README.md#What a rollback promises, and what Retry
      does beside it; services-crm:docs/data-jobs.md#What is not built;
      macroservice-libraries:packages/data-jobs/README.md#Rolling a job back;
      macroservice-libraries:packages/data-jobs/README.md#Rolling a job back
    missing_categories:
      - rule
      - transition
      - failure
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-008-06
      - ATS-PFM-DJE-008-07
      - ATS-PFM-DJE-008-08
      - ATS-PFM-DJE-008-09
      - ATS-PFM-DJE-008-10
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.update
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.update
        where_checked: api
        scope: tenant
      - key: data.jobs.rollback
        where_checked: console
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-005
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-069
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-009-update-or-delete-selected-records-from-a-list-in-one-dialog.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0110.spec.ts#DJE-ACC-0110;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0111.spec.ts#DJE-ACC-0111;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0104.spec.ts#DJE-ACC-0104;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0102.spec.ts#DJE-ACC-0102;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0101.spec.ts#DJE-ACC-0101;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0114.spec.ts#DJE-ACC-0114;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0112.spec.ts#DJE-ACC-0112;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0113.spec.ts#DJE-ACC-0113;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0108.spec.ts#DJE-ACC-0108;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0105.spec.ts#DJE-ACC-0105;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0115.spec.ts#DJE-ACC-0115
    missing_categories:
      - failure
    unbound_scenarios:
      - ATS-PFM-DJE-009-11
      - ATS-PFM-DJE-009-12
      - ATS-PFM-DJE-009-13
      - ATS-PFM-DJE-009-14
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: console
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: console
        scope: tenant
      - key: data.jobs.submit
        where_checked: console
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-003
      - WF-PFM-DJE-019
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-070
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-010-retire-and-reactivate-configuration-items-in-bulk-from-their.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/jobs/configuration-data-jobs.integration.spec.js#says
      both are blocked because they are in use; services-crm:docs/data-jobs.md#Deleting records in
      bulk;
      services-crm:modules/data-jobs/tests/integration/services/jobs/configuration-data-jobs.integration.spec.js#asks
      a person to type the number it would delete, not the number submitted;
      services-crm:docs/data-jobs.md#Deleting records in bulk;
      services-platform:docs/milestones/PLAT-M20-small-bulk-operations.md#D3;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0109.spec.ts#DJE-ACC-0109;
      react-console:acceptance/data-jobs/playwright/journeys/dialogs/DJE-ACC-0106.spec.ts#DJE-ACC-0106;
      services-crm:docs/data-jobs.md#The routes
    missing_categories:
      - transition
      - edge
      - failure
      - concurrency
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-010-02
      - ATS-PFM-DJE-010-05
      - ATS-PFM-DJE-010-07
      - ATS-PFM-DJE-010-08
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: crm.contact-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.contact-types.delete
        where_checked: api
        scope: tenant
      - key: crm.contact-types.update
        where_checked: api
        scope: tenant
      - key: crm.contact-roles.bulk
        where_checked: api
        scope: tenant
      - key: crm.contact-roles.delete
        where_checked: api
        scope: tenant
      - key: crm.contact-roles.update
        where_checked: api
        scope: tenant
      - key: crm.organization-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.organization-types.delete
        where_checked: api
        scope: tenant
      - key: crm.organization-types.update
        where_checked: api
        scope: tenant
      - key: crm.address-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.address-types.delete
        where_checked: api
        scope: tenant
      - key: crm.address-types.update
        where_checked: api
        scope: tenant
      - key: crm.phone-number-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.phone-number-types.delete
        where_checked: api
        scope: tenant
      - key: crm.phone-number-types.update
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-019
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-071
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-011-bring-a-file-of-any-size-into-rhythm-intact.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-003-upload-session.md;
      services-platform:modules/data-jobs/tests/e2e/data-jobs.e2e.spec.js#refuses reading a session,
      because which files a tenant loaded is not a read-only user’s business;
      services-platform:modules/data-jobs/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
      a declaration before it creates anything in S3, so a refused request leaves no upload behind;
      services-platform:modules/data-jobs/tests/unit/part-sizing.spec.ts#rounds a part size the
      division leaves between whole MiB up to the next whole MiB;
      services-platform:modules/data-jobs/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
      more than a hundred parts at a time, which is the page the protocol presigns;
      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/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
      to abort a completed session, whose object a job may already be reading;
      services-platform:modules/data-jobs/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
      in words a completion naming a part S3 does not hold, rather than failing as a server fault;
      services-platform:modules/data-jobs/tests/integration/services/uploads/upload-sessions.integration.spec.js#refuses
      to complete another tenant’s session, and makes no S3 call for it;
      services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:presignUploadParts;
      services-platform:docs/data-jobs/uploads.md#Retention;
      services-platform:docs/data-jobs/uploads.md#Deletion
    missing_categories:
      - rule
      - transition
      - edge
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-011-10
      - ATS-PFM-DJE-011-11
      - ATS-PFM-DJE-011-12
    transition_matrix:
      - state_model: STATE-PFM-DJE-003
        requires_review:
          - from: open
            to: completed
            trigger: Complete the multipart transfer
            source: 'services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:completeUpload'
          - from: open
            to: aborted
            trigger: Abandon the transfer or refuse integrity
            source: >-
              services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:abortUpload;
              services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:completeUpload
          - from: open
            to: expired
            trigger: Observe a missing multipart transfer
            source: >-
              services-platform:modules/data-jobs/services/uploads/upload-sessions.ts:readUploadSession
    invariant_matrix:
      - INV-DOM-PFM-DJE-003-01
      - INV-DOM-PFM-DJE-003-02
      - INV-DOM-PFM-DJE-003-03
      - INV-DOM-PFM-DJE-003-04
      - INV-DOM-PFM-DJE-003-05
      - INV-DOM-PFM-DJE-003-06
    permission_matrix:
      - key: platform.data-jobs.upload
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-008
      - WF-PFM-DJE-010
      - WF-PFM-DJE-014
      - WF-PFM-DJE-020
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-072
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-012-load-records-from-another-system-by-its-own-keys.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      services-crm:modules/data-jobs/tests/integration/services/operations/record-imports.integration.spec.js#skips
      every record of the same file delivered a second time, rather than making a second
      organization;
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#skips
      a delivery a newer one has overtaken, so a late file never undoes the current record;
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-data-jobs.integration.spec.ts#writes
      no crosswalk row for an item it refused, so the corrected delivery of that key is a create;
      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/operations/record-imports.integration.spec.js#writes
      nothing at all of the rejected organization: not the row, not its addresses, not its mapping;
      services-crm:modules/data-jobs/tests/integration/services/operations/record-imports.integration.spec.js#keeps
      each producer key as its organization’s external id, the record sending none of its own;
      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-crm:modules/data-jobs/tests/integration/services/operations/record-imports.integration.spec.js#takes
      the keys of the deleted records with them;
      services-crm:modules/data-jobs/tests/integration/services/jobs/initial-import-guarantees.integration.spec.js#applies
      every organization whose logo could be saved, and rejects the two that could not be written;
      services-crm:docs/milestones/CRM-M7-data-operations.md#M2-D13;
      services-crm:docs/data-jobs.md#The bulk lane; services-crm:docs/data-jobs.md#What is not
      built; services-crm:docs/data-jobs.md#Historical import
    missing_categories:
      - transition
      - validation
      - permission
      - edge
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-012-10
      - ATS-PFM-DJE-012-11
      - ATS-PFM-DJE-012-12
      - ATS-PFM-DJE-012-13
      - ATS-PFM-DJE-012-14
      - ATS-PFM-DJE-012-15
      - ATS-PFM-DJE-012-16
      - ATS-PFM-DJE-012-17
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
      - INV-DOM-PFM-DJE-004-01
      - INV-DOM-PFM-DJE-004-02
      - INV-DOM-PFM-DJE-004-03
      - INV-DOM-PFM-DJE-004-04
      - INV-DOM-PFM-DJE-004-05
      - INV-DOM-PFM-DJE-004-06
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.update
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.update
        where_checked: api
        scope: tenant
      - key: crm.activities.bulk
        where_checked: api
        scope: tenant
      - key: crm.regions.bulk
        where_checked: api
        scope: tenant
      - key: crm.activity-types.bulk
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-002
      - WF-PFM-DJE-004
      - WF-PFM-DJE-007
      - WF-PFM-DJE-008
      - WF-PFM-DJE-020
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-073
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-013-map-a-spreadsheet-s-columns-onto-a-record-s-typed-details.md;
      services-crm:modules/data-jobs/tests/integration/services/operations/spreadsheet-columns.integration.spec.js#maps
      the mobile and work phone columns to their own types, the first declared type preferred, an
      empty cell no value;
      services-crm:modules/data-jobs/tests/integration/services/operations/spreadsheet-columns.integration.spec.js#makes
      the preferred e-mail value that repeats the personal one the first address, the personal one,
      ahead of the work one; macroservice-libraries:packages/data-jobs/README.md#Spreadsheet columns
      into typed collections;
      services-crm:modules/data-jobs/tests/integration/services/operations/spreadsheet-columns.integration.spec.js#refuses
      a column mapped to a slot the record does not declare, naming the column and no value;
      services-crm:modules/data-jobs/tests/integration/services/operations/spreadsheet-columns.integration.spec.js#refuses
      the untyped phone number of a tenant with no default type, at the element’s path, writing
      nothing;
      services-crm:modules/data-jobs/tests/integration/services/operations/spreadsheet-columns.integration.spec.js#names
      a typed target as the tenant names the type, and offers only the types the tenant has;
      services-crm:docs/data-jobs.md#Spreadsheet columns (D-40, DEF-CRM-0660);
      services-crm:docs/data-jobs.md#Spreadsheet columns (D-40, DEF-CRM-0660);
      react-console:lib/api/data-jobs/mapping.ts
    missing_categories:
      - transition
      - permission
      - concurrency
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-013-06
    transition_matrix: []
    invariant_matrix:
      - INV-DOM-PFM-DJE-004-01
      - INV-DOM-PFM-DJE-004-02
      - INV-DOM-PFM-DJE-004-03
      - INV-DOM-PFM-DJE-004-04
      - INV-DOM-PFM-DJE-004-05
      - INV-DOM-PFM-DJE-004-06
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.contacts.update
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.update
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-008
      - WF-PFM-DJE-020
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-074
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-014-run-large-files-without-starving-anyone-else.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-006-capacity-protection-state.md;
      services-crm:modules/data-jobs/tests/e2e/bulk-data-jobs.e2e.spec.js#refuses an upload id of no
      upload at all in the same words, so neither answer tells a caller whose it is;
      services-crm:docs/data-jobs.md#The bulk lane;
      macroservice-libraries:packages/data-jobs/src/chunk-plan.ts:shouldCloseChunk;
      macroservice-libraries:packages/data-jobs/src/chunk-source.ts:ChunkRun;
      macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#fails
      the job when most of the file cannot be read, rather than reading nine million lines of it;
      macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#hands
      over no more batches at once than the budget allows;
      macroservice-libraries:packages/data-jobs/src/admission-budget.ts:tenantBulkCeiling;
      macroservice-libraries:packages/data-jobs/src/admission-planner.spec.ts#puts a starved job
      ahead of the round-robin;
      macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#fails
      a job whose ceiling has been held by work that is not moving, rather than waiting for room for
      ever;
      macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#admits
      the next job when the one holding the tenant’s ceiling has been paused, because a paused batch
      is not in flight; macroservice-libraries:packages/data-jobs/README.md#The bulk lane;
      services-crm:docs/data-jobs.md#The bulk lane;
      macroservice-libraries:packages/data-jobs/src/chunk-source.ts:closedGroupKeys
    missing_categories:
      - transition
      - permission
    unbound_scenarios:
      - ATS-PFM-DJE-014-09
      - ATS-PFM-DJE-014-10
      - ATS-PFM-DJE-014-11
      - ATS-PFM-DJE-014-12
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
      - state_model: STATE-PFM-DJE-006
        requires_review:
          - from: normal
            to: constrained
            trigger: Evaluate sustained pressure
            source: >-
              services-platform:modules/capacity/tests/unit/services/capacity/decide-state.spec.ts#makes
              no second change within five minutes of the last
          - from: constrained
            to: critical
            trigger: Evaluate sustained critical pressure
            source: 'services-platform:modules/capacity/services/capacity/decide-state.ts:assessReading'
          - from: critical
            to: emergency
            trigger: Escalate sustained critical state
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: emergency
            to: critical
            trigger: Recover from emergency
            source: 'services-platform:docs/workload-governance.md#Capacity sentinel'
          - from: critical
            to: constrained
            trigger: Recover from critical
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: constrained
            to: normal
            trigger: Recover or fall back to normal
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: normal
            to: emergency
            trigger: Apply a staff override
            source: >-
              services-platform:modules/capacity/tests/integration/services/pins/capacity-pins.integration.spec.js#records
              the pin and its removal, each with what it was and what it became
          - from: normal
            to: critical
            trigger: Enter critical directly
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: critical
            to: normal
            trigger: Release protection after signal loss
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: emergency
            to: normal
            trigger: Release emergency after signal loss
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
      - INV-DOM-PFM-DJE-006-01
      - INV-DOM-PFM-DJE-006-02
      - INV-DOM-PFM-DJE-006-03
      - INV-DOM-PFM-DJE-006-04
      - INV-DOM-PFM-DJE-006-05
      - INV-DOM-PFM-DJE-006-06
      - INV-DOM-PFM-DJE-006-07
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-008
      - WF-PFM-DJE-015
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-075
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-015-read-back-what-a-load-wrote-by-the-producer-s-keys.md;
      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-crm:modules/data-jobs/tests/integration/services/jobs/records-by-source-key.integration.spec.js#refuses
      more than 100 keys by InvalidRequest, naming the limit; services-crm:docs/data-jobs.md#Reading
      a load back by source key;
      services-crm:modules/data-jobs/tests/integration/services/jobs/records-by-source-key.integration.spec.js#looks
      a key up under its own object type only: a contact key is not an organization;
      services-crm:modules/data-jobs/services/jobs/records-by-source-key.ts;
      services-crm:modules/data-jobs/aws/api/bulk-data-jobs.routes.ts:BULK_SUBMISSIONS;
      services-platform:modules/data-jobs/aws/api/custom-field-data-jobs.routes.ts
    missing_categories:
      - transition
      - validation
      - failure
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-015-06
      - ATS-PFM-DJE-015-07
      - ATS-PFM-DJE-015-08
    transition_matrix: []
    invariant_matrix:
      - INV-DOM-PFM-DJE-004-01
      - INV-DOM-PFM-DJE-004-02
      - INV-DOM-PFM-DJE-004-03
      - INV-DOM-PFM-DJE-004-04
      - INV-DOM-PFM-DJE-004-05
      - INV-DOM-PFM-DJE-004-06
    permission_matrix:
      - key: crm.contacts.bulk
        where_checked: api
        scope: tenant
      - key: crm.organizations.bulk
        where_checked: api
        scope: tenant
      - key: crm.contact-types.bulk
        where_checked: api
        scope: tenant
      - key: crm.regions.bulk
        where_checked: api
        scope: tenant
      - key: platform.custom-fields.bulk
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-007
      - WF-PFM-DJE-012
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-076
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-016-load-a-migration-package-into-a-new-workspace-in-dependency.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-004-data-run-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-005-data-run-step.md;
      services-platform:modules/data-jobs/aws/api/data-runs.routes.ts:manage;
      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;
      services-platform:modules/data-jobs/services/runs/register-run.ts:registerRun;
      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/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#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;
      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-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep;
      services-platform:modules/data-jobs/services/runs/run-driver.ts:submitStep;
      services-platform:modules/data-jobs/services/runs/data-run-services.ts:DATA_RUN_SERVICES;
      services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelStep;
      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
    missing_categories:
      - transition
      - concurrency
      - invariant
    unbound_scenarios:
      - ATS-PFM-DJE-016-01
      - ATS-PFM-DJE-016-12
      - ATS-PFM-DJE-016-13
      - ATS-PFM-DJE-016-14
      - ATS-PFM-DJE-016-15
      - ATS-PFM-DJE-016-16
      - ATS-PFM-DJE-016-17
      - ATS-PFM-DJE-016-18
    transition_matrix:
      - state_model: STATE-PFM-DJE-004
        requires_review:
          - from: registered
            to: running
            trigger: Start package execution
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:startDataRun'
          - from: running
            to: paused
            trigger: Hold further dataset submission
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:pauseDataRun'
          - from: paused
            to: running
            trigger: Continue package execution
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:resumeDataRun'
          - from: running
            to: succeeded
            trigger: Settle completed package work
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun'
          - from: running
            to: failed
            trigger: Settle a failed dataset
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: registered
            to: cancelled
            trigger: Abandon an unstarted package
            source: >-
              services-platform:modules/data-jobs/services/persistence/data-runs.ts:DATA_RUN_TRANSITIONS
          - from: running
            to: cancelled
            trigger: Abandon active package work
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelDataRun'
          - from: paused
            to: cancelled
            trigger: Abandon paused package work
            source: >-
              services-platform:modules/data-jobs/services/persistence/data-runs.ts:DATA_RUN_TRANSITIONS
      - state_model: STATE-PFM-DJE-005
        requires_review:
          - from: pending
            to: running
            trigger: Submit an eligible dataset
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:submitStep'
          - from: running
            to: succeeded
            trigger: Read a settled successful child
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun'
          - from: running
            to: blocked
            trigger: Read a settled blocked child
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun'
          - from: blocked
            to: running
            trigger: Resubmit dependency-blocked work
            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
          - from: running
            to: failed
            trigger: Fail dataset progress
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep'
          - from: pending
            to: skipped
            trigger: Skip unsubmitted work
            source: 'services-platform:modules/data-jobs/services/persistence/data-runs.ts:skipPendingSteps'
    invariant_matrix:
      - INV-DOM-PFM-DJE-005-01
      - INV-DOM-PFM-DJE-005-02
      - INV-DOM-PFM-DJE-005-03
      - INV-DOM-PFM-DJE-005-04
      - INV-DOM-PFM-DJE-005-05
      - INV-DOM-PFM-DJE-005-06
      - INV-DOM-PFM-DJE-005-07
    permission_matrix:
      - key: hq.data-runs.manage
        where_checked: api
        scope: global
      - key: platform.custom-fields.bulk
        where_checked: service
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-009
      - WF-PFM-DJE-011
      - WF-PFM-DJE-012
      - WF-PFM-DJE-013
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-077
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-017-empty-a-loading-workspace-to-load-it-again-and-open-it-only.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-004-data-run-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-005-data-run-step.md;
      services-platform:docs/data-jobs/tenant-reset.md#1. When a tenant may be reset;
      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-platform:docs/data-jobs/tenant-reset.md#3.1 Declaring support;
      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;
      services-platform:docs/data-jobs/data-runs.md#7. The summary and the readiness verdict;
      services-platform:docs/milestones/plans/PLAT-M22-plan.md#A3;
      services-platform:docs/data-jobs/platform-data-operations.md#Reading a load back by source key
    missing_categories:
      - transition
      - edge
      - failure
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-017-01
      - ATS-PFM-DJE-017-03
      - ATS-PFM-DJE-017-05
      - ATS-PFM-DJE-017-06
      - ATS-PFM-DJE-017-07
      - ATS-PFM-DJE-017-08
      - ATS-PFM-DJE-017-09
      - ATS-PFM-DJE-017-10
    transition_matrix:
      - state_model: STATE-PFM-DJE-004
        requires_review:
          - from: registered
            to: running
            trigger: Start package execution
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:startDataRun'
          - from: running
            to: paused
            trigger: Hold further dataset submission
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:pauseDataRun'
          - from: paused
            to: running
            trigger: Continue package execution
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:resumeDataRun'
          - from: running
            to: succeeded
            trigger: Settle completed package work
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun'
          - from: running
            to: failed
            trigger: Settle a failed dataset
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: registered
            to: cancelled
            trigger: Abandon an unstarted package
            source: >-
              services-platform:modules/data-jobs/services/persistence/data-runs.ts:DATA_RUN_TRANSITIONS
          - from: running
            to: cancelled
            trigger: Abandon active package work
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:cancelDataRun'
          - from: paused
            to: cancelled
            trigger: Abandon paused package work
            source: >-
              services-platform:modules/data-jobs/services/persistence/data-runs.ts:DATA_RUN_TRANSITIONS
      - state_model: STATE-PFM-DJE-005
        requires_review:
          - from: pending
            to: running
            trigger: Submit an eligible dataset
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:submitStep'
          - from: running
            to: succeeded
            trigger: Read a settled successful child
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun'
          - from: running
            to: blocked
            trigger: Read a settled blocked child
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:advanceDataRun'
          - from: blocked
            to: running
            trigger: Resubmit dependency-blocked work
            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
          - from: running
            to: failed
            trigger: Fail dataset progress
            source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:pollStep'
          - from: pending
            to: skipped
            trigger: Skip unsubmitted work
            source: 'services-platform:modules/data-jobs/services/persistence/data-runs.ts:skipPendingSteps'
    invariant_matrix:
      - INV-DOM-PFM-DJE-004-01
      - INV-DOM-PFM-DJE-004-02
      - INV-DOM-PFM-DJE-004-03
      - INV-DOM-PFM-DJE-004-04
      - INV-DOM-PFM-DJE-004-05
      - INV-DOM-PFM-DJE-004-06
      - INV-DOM-PFM-DJE-005-01
      - INV-DOM-PFM-DJE-005-02
      - INV-DOM-PFM-DJE-005-03
      - INV-DOM-PFM-DJE-005-04
      - INV-DOM-PFM-DJE-005-05
      - INV-DOM-PFM-DJE-005-06
      - INV-DOM-PFM-DJE-005-07
    permission_matrix:
      - key: hq.data-runs.manage
        where_checked: api
        scope: global
      - key: hq.tenants.activate
        where_checked: api
        scope: global
    workflow_matrix:
      - WF-PFM-DJE-014
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-078
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-018-offer-a-product-area-s-records-to-the-engine.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-001-data-job-lifecycle.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-002-data-job-batch.md;
      macroservice-libraries:packages/data-jobs/src/validate-data-job-request.spec.ts#refuses a
      delete that declares patchable fields, which a delete never sets;
      macroservice-libraries:packages/data-jobs/src/row-level-security.ts:PRIVILEGES;
      services-platform:modules/data-jobs/tests/integration/services/jobs/custom-field-data-jobs.integration.spec.js#refuses
      the same change as an insert, naming the definition rather than writing a second one;
      services-platform:docs/data-jobs/platform-data-operations.md#1.1 A definition's rules (the
      package format); services-platform:docs/data-jobs/platform-data-operations.md#3. The batches
      run in the submitting request;
      services-platform:modules/data-jobs/services/jobs/custom-field-data-jobs.ts:parseDatasetLines;
      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;
      services-platform:docs/data-jobs/platform-data-operations.md#There is no `/rollback`;
      services-membership:modules/data-jobs/services/operations/structure-data-operations.ts
    missing_categories:
      - transition
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-018-04
      - ATS-PFM-DJE-018-05
      - ATS-PFM-DJE-018-06
      - ATS-PFM-DJE-018-09
      - ATS-PFM-DJE-018-10
    transition_matrix:
      - state_model: STATE-PFM-DJE-001
        requires_review:
          - from: accepted
            to: validating
            trigger: Submit a preview
            source: 'macroservice-libraries:packages/data-jobs/src/submit-data-job.ts:submitDataJob'
          - from: accepted
            to: queued
            trigger: Submit direct application
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-delete.integration.spec.js#refuses
              a delete submitted to be applied, because a delete is validated first
          - from: validating
            to: validated
            trigger: Settle the final validation batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
          - from: validated
            to: queued
            trigger: Approve the saved preview
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#refuses
              an apply of the validated update whose digest is not the one the validation answered
          - from: validated
            to: expired
            trigger: Attempt late approval
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:applyValidatedJob'
          - from: queued
            to: running
            trigger: Begin the first apply batch
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:runDataJobBatch'
          - from: running
            to: succeeded
            trigger: Finish apply processing
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: completed_with_rejections
            trigger: Finish apply processing with unresolved outcomes
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:finalDataJobState'
          - from: running
            to: paused
            trigger: Hold further processing
            source: 'macroservice-libraries:packages/data-jobs/src/rejection-guard.ts:rejectionGuardVerdict'
          - from: queued
            to: paused
            trigger: Pause before execution
            source: >-
              macroservice-libraries:packages/data-jobs/src/tests/integration/bulk-data-jobs.integration.spec.ts#holds
              a job paused before its source was read, and runs it to the end once resumed
          - from: paused
            to: running
            trigger: Continue held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: running
            to: cancelling
            trigger: Cancel active work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: queued
            to: cancelling
            trigger: Cancel queued work
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: paused
            to: cancelling
            trigger: Cancel held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: validated
            to: cancelling
            trigger: Discard an unused preview
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: cancelling
            to: cancelled
            trigger: Finish cancellation
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/contact-data-jobs.integration.spec.js#ends
              the job cancelled, not failed, once the batch it waited for has finished
          - from: completed_with_rejections
            to: queued
            trigger: Retry dependency-blocked items
            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
          - from: running
            to: failed
            trigger: End work after a systemic problem
            source: >-
              services-crm:modules/data-jobs/tests/integration/services/jobs/bulk-data-job-failure.integration.spec.js#fails
              the data job, so its status read answers failed and a Data Run polling it stops
          - from: completing
            to: succeeded
            trigger: Complete declared settlement
            source: 'macroservice-libraries:packages/data-jobs/src/data-job-states.ts:DATA_JOB_TRANSITIONS'
          - from: validating
            to: paused
            trigger: Pause a preview through the guard
            source: 'macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:settleJob'
      - state_model: STATE-PFM-DJE-002
        requires_review:
          - from: pending
            to: running
            trigger: Take a batch delivery
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts (module comment,
              steps 1 and 2)
          - from: running
            to: done
            trigger: Settle batch items
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
          - from: running
            to: failed_transient
            trigger: Exhaust transient attempts
            source: >-
              macroservice-libraries:packages/data-jobs/src/run-data-job-batch.ts:DATA_JOB_MAX_BATCH_ATTEMPTS
          - from: pending
            to: not_attempted
            trigger: Abandon unfinished work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:cancelDataJob'
          - from: not_attempted
            to: pending
            trigger: Resume held work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: failed_transient
            to: pending
            trigger: Recover exhausted work
            source: 'macroservice-libraries:packages/data-jobs/src/job-control.ts:resumeDataJob'
          - from: done
            to: pending
            trigger: Requeue an approved preview or dependency retry
            source: 'macroservice-libraries:packages/data-jobs/README.md#The counters on the job row'
    invariant_matrix:
      - INV-DOM-PFM-DJE-001-01
      - INV-DOM-PFM-DJE-001-02
      - INV-DOM-PFM-DJE-001-03
      - INV-DOM-PFM-DJE-001-04
      - INV-DOM-PFM-DJE-001-05
      - INV-DOM-PFM-DJE-001-06
      - INV-DOM-PFM-DJE-001-07
      - INV-DOM-PFM-DJE-001-08
      - INV-DOM-PFM-DJE-001-09
      - INV-DOM-PFM-DJE-001-10
      - INV-DOM-PFM-DJE-001-11
      - INV-DOM-PFM-DJE-001-12
    permission_matrix:
      - key: platform.custom-fields.bulk
        where_checked: api
        scope: tenant
      - key: platform.custom-fields.create
        where_checked: api
        scope: tenant
      - key: platform.custom-fields.update
        where_checked: api
        scope: tenant
      - key: platform.custom-records.create
        where_checked: api
        scope: tenant
      - key: platform.custom-records.update
        where_checked: service
        scope: record
      - key: platform.associations.create
        where_checked: api
        scope: tenant
      - key: platform.associations.update
        where_checked: api
        scope: tenant
    workflow_matrix:
      - WF-PFM-DJE-001
      - WF-PFM-DJE-009
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-079
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-019-hold-the-platform-s-protection-state-while-the-database-is.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-006-capacity-protection-state.md;
      services-platform:modules/capacity/services/capacity/decide-state.ts:assessReading;
      services-platform:modules/capacity/tests/unit/services/capacity/decide-state.spec.ts#makes no
      second change within five minutes of the last;
      services-platform:modules/capacity/tests/unit/services/capacity/decide-state.spec.ts#stops
      bulk and quarters heavy in critical, keeping writes and reads whole;
      services-platform:modules/capacity/tests/e2e/capacity-pins.e2e.spec.js#refuses a customer's
      administrator, whatever they hold at their customer's scope;
      services-platform:modules/capacity/tests/integration/services/persistence/capacity-state-pins.integration.spec.js#refuses
      an expiry more than a day ahead, naming expires_at;
      services-platform:modules/capacity/tests/integration/services/pins/capacity-pins.integration.spec.js#records
      the pin and its removal, each with what it was and what it became;
      services-platform:docs/workload-governance.md#Capacity sentinel;
      services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState;
      services-platform:docs/workload-governance.md#Capacity sentinel
    missing_categories:
      - transition
      - edge
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-019-09
      - ATS-PFM-DJE-019-10
      - ATS-PFM-DJE-019-11
    transition_matrix:
      - state_model: STATE-PFM-DJE-006
        requires_review:
          - from: normal
            to: constrained
            trigger: Evaluate sustained pressure
            source: >-
              services-platform:modules/capacity/tests/unit/services/capacity/decide-state.spec.ts#makes
              no second change within five minutes of the last
          - from: constrained
            to: critical
            trigger: Evaluate sustained critical pressure
            source: 'services-platform:modules/capacity/services/capacity/decide-state.ts:assessReading'
          - from: critical
            to: emergency
            trigger: Escalate sustained critical state
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: emergency
            to: critical
            trigger: Recover from emergency
            source: 'services-platform:docs/workload-governance.md#Capacity sentinel'
          - from: critical
            to: constrained
            trigger: Recover from critical
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: constrained
            to: normal
            trigger: Recover or fall back to normal
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: normal
            to: emergency
            trigger: Apply a staff override
            source: >-
              services-platform:modules/capacity/tests/integration/services/pins/capacity-pins.integration.spec.js#records
              the pin and its removal, each with what it was and what it became
          - from: normal
            to: critical
            trigger: Enter critical directly
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: critical
            to: normal
            trigger: Release protection after signal loss
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: emergency
            to: normal
            trigger: Release emergency after signal loss
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
    invariant_matrix:
      - INV-DOM-PFM-DJE-006-01
      - INV-DOM-PFM-DJE-006-02
      - INV-DOM-PFM-DJE-006-03
      - INV-DOM-PFM-DJE-006-04
      - INV-DOM-PFM-DJE-006-05
      - INV-DOM-PFM-DJE-006-06
      - INV-DOM-PFM-DJE-006-07
    permission_matrix:
      - key: hq.capacity.manage
        where_checked: api
        scope: global
    workflow_matrix:
      - WF-PFM-DJE-015
      - WF-PFM-DJE-016
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-080
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-020-keep-monthly-history-tables-partitioned-and-trimmed.md;
      specs/platform/data-job-engine/design/state-models/STATE-PFM-DJE-006-capacity-protection-state.md;
      services-platform:modules/partitions/tests/integration/services/maintenance/maintain-partitions.integration.spec.js#creates
      the current month and the two after it on the first run, and drops nothing;
      services-platform:modules/partitions/aws/logic/partitions-maintenance.schedule.ts:createPartitionsMaintenanceSchedule;
      services-platform:docs/partitions.md#The helpers; services-platform:docs/partitions.md#A
      partition is secured like its parent;
      services-platform:modules/partitions/tests/integration/services/maintenance/maintain-partitions.integration.spec.js#fails
      the run as a whole when one table’s pass failed, naming that table;
      services-platform:docs/partitions.md#The helpers;
      macroservice-libraries:packages/data-jobs/README.md#Partitioning is deferred
    missing_categories:
      - rule
      - validation
      - permission
      - edge
      - boundary
      - concurrency
    unbound_scenarios:
      - ATS-PFM-DJE-020-03
      - ATS-PFM-DJE-020-05
    transition_matrix:
      - state_model: STATE-PFM-DJE-006
        requires_review:
          - from: normal
            to: constrained
            trigger: Evaluate sustained pressure
            source: >-
              services-platform:modules/capacity/tests/unit/services/capacity/decide-state.spec.ts#makes
              no second change within five minutes of the last
          - from: constrained
            to: critical
            trigger: Evaluate sustained critical pressure
            source: 'services-platform:modules/capacity/services/capacity/decide-state.ts:assessReading'
          - from: critical
            to: emergency
            trigger: Escalate sustained critical state
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: emergency
            to: critical
            trigger: Recover from emergency
            source: 'services-platform:docs/workload-governance.md#Capacity sentinel'
          - from: critical
            to: constrained
            trigger: Recover from critical
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: constrained
            to: normal
            trigger: Recover or fall back to normal
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: normal
            to: emergency
            trigger: Apply a staff override
            source: >-
              services-platform:modules/capacity/tests/integration/services/pins/capacity-pins.integration.spec.js#records
              the pin and its removal, each with what it was and what it became
          - from: normal
            to: critical
            trigger: Enter critical directly
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: critical
            to: normal
            trigger: Release protection after signal loss
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
          - from: emergency
            to: normal
            trigger: Release emergency after signal loss
            source: >-
              services-platform:modules/capacity/services/capacity/decide-state.ts:decideCapacityState
    invariant_matrix:
      - INV-DOM-PFM-DJE-006-01
      - INV-DOM-PFM-DJE-006-02
      - INV-DOM-PFM-DJE-006-03
      - INV-DOM-PFM-DJE-006-04
      - INV-DOM-PFM-DJE-006-05
      - INV-DOM-PFM-DJE-006-06
      - INV-DOM-PFM-DJE-006-07
    permission_matrix: []
    workflow_matrix:
      - WF-PFM-DJE-017
    note: >-
      Category coverage counts defined scenarios. These transition, invariant, permission and
      workflow inventories require clause-level executable proof; the scenario references do not
      establish all rows.
  - id: FND-PFM-DJE-081
    provenance: observed
    source: >-
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-001-submit-one-audited-job-that-changes-many-records.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-002-preview-what-a-job-will-do-and-approve-exactly-that.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-003-apply-every-good-record-and-set-aside-every-bad-one.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-004-pause-resume-cancel-or-retry-a-job-safely.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-005-follow-a-job-and-trace-every-change-it-made.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-006-never-overwrite-a-colleague-s-edit-made-during-a-bulk-change.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-007-delete-records-in-bulk-only-after-a-counted-typed-approval.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-008-put-a-bulk-change-back-without-losing-later-edits.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-009-update-or-delete-selected-records-from-a-list-in-one-dialog.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-010-retire-and-reactivate-configuration-items-in-bulk-from-their.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-011-bring-a-file-of-any-size-into-rhythm-intact.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-012-load-records-from-another-system-by-its-own-keys.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-013-map-a-spreadsheet-s-columns-onto-a-record-s-typed-details.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-014-run-large-files-without-starving-anyone-else.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-015-read-back-what-a-load-wrote-by-the-producer-s-keys.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-016-load-a-migration-package-into-a-new-workspace-in-dependency.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-017-empty-a-loading-workspace-to-load-it-again-and-open-it-only.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-018-offer-a-product-area-s-records-to-the-engine.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-019-hold-the-platform-s-protection-state-while-the-database-is.md;
      specs/platform/data-job-engine/design/tests/ATS-PFM-DJE-020-keep-monthly-history-tables-partitioned-and-trimmed.md
  - id: FND-PFM-DJE-082
    provenance: observed
    source: >-
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0674.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0673.spec.ts
  - id: FND-PFM-DJE-083
    provenance: observed
    source: 'services-platform:modules/data-jobs/services/runs/run-driver.ts:startDataRun'
  - id: FND-PFM-DJE-084
    provenance: observed
    source: >-
      specs/platform/data-job-engine/planning/acceptance/FAS-PFM-DJE-01-data-jobs.md;
      specs/platform/data-job-engine/planning/acceptance/FAS-PFM-DJE-02-protected-bulk-changes.md;
      specs/platform/data-job-engine/planning/acceptance/FAS-PFM-DJE-03-bulk-actions-from-lists.md;
      specs/platform/data-job-engine/planning/acceptance/FAS-PFM-DJE-04-file-imports.md;
      specs/platform/data-job-engine/planning/acceptance/FAS-PFM-DJE-05-workspace-loading.md;
      specs/platform/data-job-engine/planning/acceptance/FAS-PFM-DJE-06-workload-protection.md
  - id: FND-PFM-DJE-085
    provenance: observed
    source: >-
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0662.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0668.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0673.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0674.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0675.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0677.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0678.spec.ts;
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0679.spec.ts;
      react-console:acceptance/data-jobs/playwright/rehearsals/plat-m19.spec.ts
binding_corrections:
  - scenario: ATS-PFM-DJE-017-01
    binding: >-
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0674.spec.ts#CRM-ACC-0674
    reason: blocked placeholder
  - scenario: ATS-PFM-DJE-017-07
    binding: >-
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0673.spec.ts#CRM-ACC-0673
    reason: blocked placeholder
binding_review:
  finding: FND-PFM-DJE-081
  provenance: test
  source:
    - >-
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0664.spec.ts#CRM-ACC-0664
    - >-
      react-console:acceptance/crm/playwright/journeys/data-operations/CRM-ACC-0659.spec.ts#CRM-ACC-0659
    - >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-patches.integration.spec.ts#skips
      a late patch file whose revision is older than the one applied, and writes nothing
    - >-
      macroservice-libraries:packages/data-jobs/src/tests/integration/keyed-patches.integration.spec.ts#applies
      a patch of the revision already applied, which is a further part of that revision (a second
      pass)
  corrections:
    - scenario: ATS-PFM-DJE-004-06
      removed_binding:
        - TST-PFM-DJE-063
      reason: 'The browser asserts import entry access, not job control visibility and requests.'
    - scenario: ATS-PFM-DJE-008-05
      removed_binding:
        - TST-PFM-DJE-058
      reason: >-
        The custom-field branch is conditional and records that the case is not provable when the
        field is unavailable.
    - scenario: ATS-PFM-DJE-006-07
      removed_binding:
        - TST-PFM-DJE-043
      replacement_binding:
        - TST-PFM-DJE-030
      reason: >-
        The shared-engine integration assertions cover both stale and equal-revision patches; the
        browser does not assert the equal-revision second pass.
  unproved_clauses:
    - scenario: ATS-PFM-DJE-012-07
      clause: >-
        Initial-import refusal in a live workspace is not executed by the bound historical-value
        case.
    - scenario: ATS-PFM-DJE-014-07
      clause: >-
        The bound case configures ten minutes; it does not establish the default fifteen-minute
        stall threshold.
    - scenario: ATS-PFM-DJE-020-01
      clause: The bound initial pass does not establish repeat invocation at the same month.
    - scenario: ATS-PFM-DJE-013-01
      clause: >-
        Updating a pre-existing record without a collection needs a persistence assertion showing
        that collection survives.
    - scenario: ATS-PFM-DJE-013-05
      clause: >-
        The inherited target assertions do not establish the absence of an organization email
        target.
    - scenario: ATS-PFM-DJE-016-03
      clause: >-
        Re-reading the valid run does not establish that every invalid request leaves no additional
        run record.
---

# Data Job Engine: Findings and Decisions Needed

## Findings

Every finding remains open unless its text identifies a narrower correction completed in this examination. Evidence references below distinguish recorded reports from observed code; neither establishes product approval.

| id | severity | statement | affects | evidence | kind |
|---|---|---|---|---|---|
| `FND-PFM-DJE-001` | high | Workspace activation does not consult Data Run readiness. PLAT-M22 A3 requires an activation refusal when blockers remain, but the cited route changes the workspace state without that check; acceptance proof is also absent. | `BR-CAP-PFM-DJE-017-07`, `CAP-PFM-DJE-017`, `JNY-PFM-DJE-004` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-002` | medium | The recorded 90-day evidence and rollback window has no matching cleanup mechanism in the scoped engine. Submission-ledger purging exists, but jobs, receipts and refusals are retained, so the intended retention boundary is not enforced. | `BR-CAP-PFM-DJE-005-07`, `BR-CAP-PFM-DJE-008-04` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-003` | medium | Expiry is evaluated when a validated job is acted upon rather than by a scheduled sweep. A list can consequently show a validated job whose apply window has elapsed; the blocked acceptance record supplies no executable expiry proof. | `BR-CAP-PFM-DJE-002-03` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-004` | medium | CRM-M7 M2-D13 specifies an automatic-role import switch with an off default. The observed schema has no switch and contact import preserves automatic roles; the bound role test does not establish the requested option or its default. | `BR-CAP-PFM-DJE-012-10` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-005` | medium | Backend and console rollback support differ. CRM serves organization-update rollback and the engine supports reversing a rollback, while the console exposes contact-update rollback and uses the contacts bulk alias. | `BR-CAP-PFM-DJE-008-07`, `BR-CAP-PFM-DJE-008-09` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-006` | medium | A record changed through custom fields or collections is excluded as a whole from rollback. Ordinary changes on that same record are therefore left in place, although the update surfaces offer those fields without explaining that restoration limit. | `BR-CAP-PFM-DJE-008-05`, `BR-CAP-PFM-DJE-009-04` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-007` | medium | The counted contact-deletion impact omits cleared task references and duplicate-detection rows. The broader cross-module impact contract in CRM-M7 D-41 remains deferred. | `BR-CAP-PFM-DJE-007-09` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-008` | low | The CRM guide mixes obsolete limitations with later functionality. Its unbuilt-items and route descriptions conflict with its file-support and bulk-lane sections and with the organization routes; the conflicting guidance needs correction at its source. | `BR-CAP-PFM-DJE-012-09`, `BR-CAP-PFM-DJE-008-07`, `MOD-PFM-DJE` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-009` | low | Three inherited inventory descriptions lag the observed behavior: previewed edits now have version protection, small-upload digests are measured, and bulk admission uses a capacity-adjusted service share rather than a fixed worker count. | `CAP-PFM-DJE-006`, `CAP-PFM-DJE-011`, `CAP-PFM-DJE-014` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-010` | medium | When no storage-supplied full-object digest is available, uploads above the 256 MiB measurement limit retain a declared digest without verification. Run registration compares that recorded value with the manifest rather than proving the file bytes; the large-file integrity decision stays open. | `BR-CAP-PFM-DJE-011-06`, `BR-CAP-PFM-DJE-016-03` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-011` | low | Upload registration permits JSON documents and zip archives, but the inspected readers do not provide corresponding dataset processing or archive extraction. An accepted upload format is consequently not a guarantee that a job can consume it. | `BR-CAP-PFM-DJE-014-02` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-012` | medium | The PLAT-M20 rehearsal records configuration actions failing at Apply through the contacts route. This pass did not rerun the pinned browser journeys or establish the fix, so the rehearsal defect remains an unresolved verification item. | `CAP-PFM-DJE-010`, `JNY-PFM-DJE-003`, `BR-CAP-PFM-DJE-010-04` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-013` | medium | Address and phone-number type catalogues lack a status field. Their deactivate path is unavailable, and PLAT-M20 D3 leaves the schema decision with Andrew. | `BR-CAP-PFM-DJE-010-05` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-014` | low | PLAT-M20 D2 contains a recommendation for engine-backed configuration activation and deactivation without a recorded answer. Observing its implementation supplies evidence but does not confirm the product decision. | `BR-CAP-PFM-DJE-010-04` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-015` | low | The recorded organization-dialog design and the console capability registry disagree. PLAT-M20 D4 describes interactive organization updates, whereas the registry and journey send them through the file wizard. | `BR-CAP-PFM-DJE-009-11` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-016` | low | CRM job endpoints require bulk permission, preventing a caller without it from exercising the own-jobs-only visibility branch. Platform custom-record routes provide a surface where that distinction can apply. | `BR-CAP-PFM-DJE-005-01` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-017` | medium | The planned server result tools are absent from the inspected service surfaces. PLAT-M19 R3 and PLAT-M21 call for result search, refusal-code totals and generated exports; the console advertises controls that remain disabled. | `BR-CAP-PFM-DJE-005-09` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-018` | low | CRM file jobs have no preview-before-apply path. Input mistakes can therefore emerge as refusals after accepted records have already been written; this limitation does not apply to every Platform uploaded-dataset operation. | `BR-CAP-PFM-DJE-002-06` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-019` | medium | Membership provides structure operation definitions without the engine persistence, execution surfaces or keyed reconciliation needed for a Data Run participant. Its crosswalk export reports that it does not apply. | `BR-CAP-PFM-DJE-018-10`, `BR-CAP-PFM-DJE-016-12` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-020` | low | The CRM guide understates keyed lookup coverage: activity and activity-type routes exist in addition to the eight collections it lists. | `BR-CAP-PFM-DJE-015-07` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-021` | low | The module assignment includes monthly partition maintenance for eligibility and integration history. Data-job receipts are intentionally unpartitioned, leaving the operational ownership question separate from the engine record model. | `CAP-PFM-DJE-020`, `MOD-PFM-DJE` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-022` | low | Several required-proof branches lack a usable binding or a binding that proves the stated requirement. These include lifecycle and partition contracts outside the inspected scope, blocked acceptance work, rollback authorization, and automatic-role configuration; capacity emergency and failed-signal bindings were corrected in pass 2. | `BR-CAP-PFM-DJE-003-08`, `BR-CAP-PFM-DJE-017-01`, `BR-CAP-PFM-DJE-017-03`, `BR-CAP-PFM-DJE-017-08`, `BR-CAP-PFM-DJE-017-06`, `BR-CAP-PFM-DJE-016-01`, `BR-CAP-PFM-DJE-006-02`, `BR-CAP-PFM-DJE-010-02`, `BR-CAP-PFM-DJE-018-04`, `BR-CAP-PFM-DJE-018-05`, `BR-CAP-PFM-DJE-018-06`, `BR-CAP-PFM-DJE-020-03`, `BR-CAP-PFM-DJE-008-06`, `BR-CAP-PFM-DJE-012-10` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-023` | low | The module registry omits dependent console component/client paths, CRM browser specs and later Platform milestone records. This continuation is restricted to module files and actor rows, so the registry correction is still required rather than claimed complete. | `MOD-PFM-DJE` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-024` | low | A producer can create another contact by delivering the same person under a new key without raising a duplicate candidate. The inherited acceptance record treats duplicate detection on import as an undecided product behavior. | `BR-CAP-PFM-DJE-012-12` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-025` | low | The console capability commentary says regions have no import route, but the CRM route factory exposes region data jobs. The comment is stale evidence rather than an engine limitation. | `CAP-PFM-DJE-001` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-026` | low | Typed e-mail spreadsheet columns affect address ordering without persisting the column type on an address. The source guide leaves that additional data model decision unresolved. | `BR-CAP-PFM-DJE-013-07` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-027` | low | Non-numeric, non-date revisions use lexical ordering. A token such as v9 can consequently rank above v10, which producers must account for until a revision-format decision changes the contract. | `BR-CAP-PFM-DJE-012-02` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-028` | medium | Overwrite-policy deliveries can replace staff edits where no explicit expected-version guard applies. Record history remains available, but the console does not display the policy or distinguish that overwrite in its job view. | `BR-CAP-PFM-DJE-006-05` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-029` | low | The Platform adoption guide identifies three pieces duplicated from CRM that could move into the shared engine package. This is a package-boundary debt item, not evidence that those implementations are interchangeable. | `CAP-PFM-DJE-018` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-030` | low | The CRM guide describes finished-batch progress as always zero, contradicting the cited integration assertion that completed planned batches are counted. The progress explanation is outdated. | `BR-CAP-PFM-DJE-005-03` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-031` | high | Parent cancellation can finish while a child continues writing. The driver logs and ignores downstream cancellation errors other than access denial, without checking that every child has stopped. | `BR-CAP-PFM-DJE-016-13` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-032` | medium | Readiness detects an accounted total below the manifest count but does not block an excess. A run with an overcount can therefore receive a ready verdict. | `BR-CAP-PFM-DJE-016-10` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-033` | medium | Dataset submission errors escape before the driver records a settled step. The parent can remain running with a pending step, so unreachable-service settlement is not guaranteed by this branch. | `BR-CAP-PFM-DJE-016-11` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-034` | low | The planning acceptance set has no scenario for downstream cancellation failure or transient-read grace. Both observed branches require explicit proof before their recovery guarantees can be approved. | `BR-CAP-PFM-DJE-016-13`, `BR-CAP-PFM-DJE-016-14` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-035` | medium | Registration locks existing run rows and uses a non-unique package index. Those scoped mechanisms do not establish uniqueness when concurrent registrations find no existing row. | `BR-CAP-PFM-DJE-016-05` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-036` | low | Repeated dataset names in upload entries are accepted into a map whose last value wins. Neither the registration code nor the request schema establishes a unique upload entry per dataset. | `BR-CAP-PFM-DJE-016-03` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-037` | low | Destination-environment comparison depends on the process having an environment configured. With that setting absent, registration accepts the manifest environment without comparison. | `BR-CAP-PFM-DJE-016-03` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-038` | medium | An unrecognized successful progress payload can become a running status instead of a refusal. Repeated responses of that shape can refresh progress while leaving the step unsettled indefinitely. | `BR-CAP-PFM-DJE-016-11` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-039` | medium | Platform custom-record and association loaders have no matching producer-key reconciliation endpoint. Imported-type reconciliation coverage is therefore narrower than a universal lookup promise. | `BR-CAP-PFM-DJE-015-07`, `CAP-PFM-DJE-018` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-040` | low | The upload guide labels binary-size arithmetic as 200 GB. Its 24 MiB part size and 8,534-part count describe 200 GiB; the scenario now uses the explicit binary unit. | `SC-CAP-PFM-DJE-011-01` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-041` | high | Repeated-group detection retains only a bounded set associated with the most recently closed chunk. Distant repeats and resumed invocations can evade it, so whole-file group atomicity lacks both an implementation guarantee and a matching planning proof. | `BR-CAP-PFM-DJE-014-03`, `BR-CAP-PFM-DJE-014-11` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-042` | medium | This continuation completes final wording and selected semantic corrections, but not exhaustive examination of every indexed operation, table constraint/policy, permission surface, page, infrastructure recovery branch, compound rule, intent authority or complete test suite. The report retains the exact residual suite inventory; selected anchor and assertion review does not discharge that work. Remaining broad bindings, including compound group ordering and combined live-import/merge behavior, require clause-by-clause proof review. | `MOD-PFM-DJE` | See pinned finding_evidence | debt |
| `FND-PFM-DJE-043` | low | The engine security commentary describes receipts as append-only and deletion as mapping-only, but PRIVILEGES grants receipt UPDATE and DELETE on queued batches, submission-ledger rows and mappings. Receipt completion requires mutation; the capability now follows the actual grants and the commentary needs correction. | `BR-CAP-PFM-DJE-018-02` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-044` | medium | Upload completion has a recovery gap if storage completes before the database row is saved. The adapter retries multipart completion before HEAD, and the service treats NoSuchUpload as expiry; neither path discovers the already completed object to repair an open session. No crash-recovery behavior test was executed in this examination. | `CAP-PFM-DJE-011` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-045` | low | The design layer found that no service, workflow or screen of this module asks a model anything, so the module has no inference directory; the conventions require the module charter to say so in one sentence, and the charter is a planning artifact this design pass may not edit. | `MOD-PFM-DJE` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-046` | medium | The console's record-kind registry knows only contacts, organizations and the five configuration catalogues. Regions, activity types, activities, custom field definitions and custom object records have served job routes, but their jobs cannot be started, listed or inspected in Data Imports, and the list reads only CRM's jobs. The list is also read at the contacts address, so a person whose only bulk key is a catalogue's is shown Data Imports but refused its list (inferred from the route keys and the console's alias table). | `CAP-PFM-DJE-005`, `CAP-PFM-DJE-018`, `SCR-PFM-DJE-002`, `SCR-PFM-DJE-003`, `SCR-PFM-DJE-004` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-047` | high | Platform's in-request batch runner claims every queued batch of the workspace, and the claim deletes their queue entries, before running them one by one inside a 30-second function. A request that ends partway leaves pending batches with no queue entry and no schedule to find them; the job reads running, resume and retry refuse a running job, and only cancel settles it. Nothing alerts anyone. | `BR-CAP-PFM-DJE-018-05`, `WF-PFM-DJE-009`, `ADR-PFM-DJE-019` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-048` | low | Only CRM calls the 30-day idempotency-ledger purge. Platform's ledger of custom field and custom object record jobs is never trimmed, so its keys answer the original job indefinitely. | `BR-CAP-PFM-DJE-005-08`, `WF-PFM-DJE-018`, `ADR-PFM-DJE-020` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-049` | low | The row-level security standard says the data-job refusal rows carry the values a record was refused for, while the engine's refusal record holds codes, field paths, a constraint name and a safe message and never a value. The standard's description needs correcting at its source; the design follows the code and the planning rule. | `INV-DOM-PFM-DJE-001-03`, `BR-CAP-PFM-DJE-003-04` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-057` | medium | Bulk-job evidence, receipts and refusals have no cleanup enforcing the recorded retention window. | `TC-DAT-003`, `BR-CAP-PFM-DJE-005-07`, `BR-CAP-PFM-DJE-008-04` | Structured control evidence | control-gap |
| `FND-PFM-DJE-058` | medium | Migration-package registration protects existing runs but has no uniqueness safeguard for concurrent first registrations. | `TC-PI-002`, `TC-PI-003`, `BR-CAP-PFM-DJE-016-05` | Structured control evidence | control-gap |
| `FND-PFM-DJE-059` | medium | A completed multipart object can remain attached to an open upload session after a database failure, and the retry path cannot repair that storage-first result. | `TC-AVL-004`, `TC-PI-004`, `CAP-PFM-DJE-011` | Structured control evidence | control-gap |
| `FND-PFM-DJE-060` | high | Concurrent first use of one producer key can create two domain records because the mapping conflict replaces its destination rather than forcing convergence. | `TC-PI-002`, `TC-PI-003`, `WF-PFM-DJE-007`, `BR-CAP-PFM-DJE-012-01` | Structured control evidence | control-gap |

| `FND-PFM-DJE-050` | high | Two first deliveries of one producer key can both find no mapping and create separate records. The mapping writer updates on conflict, replacing the destination rather than forcing a losing transaction to retry; locking existing rows does not protect absent keys. This contradicts the library commentary and the intended stable producer identity. | `INV-DOM-PFM-DJE-004-02`, `WF-PFM-DJE-007`, `BR-CAP-PFM-DJE-012-01` | See pinned finding_evidence | defect |
| `FND-PFM-DJE-051` | medium | Capacity escalation selects the highest level supported by three readings and can enter critical directly from normal. Recovery from emergency restores active stage throttles in a separate tick before stepping down; an active pin also takes precedence over failed signal reads. The design now describes these branches, while the planning narrative still suggests gradual escalation. | `STATE-PFM-DJE-006`, `DOM-PFM-DJE-006`, `CAP-PFM-DJE-019` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-052` | low | A concurrent interactive submission that loses the idempotency-key insert rolls back and returns a conflict naming the winning job. Only a subsequent read of the ledger returns that job, so simultaneous identical requests do not both receive the ordinary reuse response. | `WF-PFM-DJE-001`, `CAP-PFM-DJE-001` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-053` | medium | The requested design brief is absent from this checkout, and the current planning artifacts retain draft status and proposed product intent. Cited approved proposal decisions support selected design choices but do not establish approval of the whole planning layer or readiness for implementation preparation. | `MOD-PFM-DJE` | See pinned finding_evidence | undocumented |
| `FND-PFM-DJE-054` | medium | Control actions check the declared transition table, but batch settlement writes state directly. The refusal-rate guard can pause validating work although the table excludes that transition; accepted and completing are declared vocabulary rather than intermediate states written by the examined submission and settlement paths. | `INV-DOM-PFM-DJE-001-05`, `STATE-PFM-DJE-001`, `WF-PFM-DJE-002`, `CAP-PFM-DJE-004` | See pinned finding_evidence | inconsistency |
| `FND-PFM-DJE-055` | low | Collecting all matching records deduplicates independently fetched pages without a shared snapshot token. The collected identifiers are fixed after collection, but the implementation does not establish that they are exactly the query result at one common instant. | `SCR-PFM-DJE-008`, `WF-PFM-DJE-019`, `CAP-PFM-DJE-009` | See pinned finding_evidence | undocumented |

| `FND-PFM-DJE-056` | medium | Bulk menus check the record kind’s bulk permission without checking its update or delete permission. The wizard offers registry-supported kinds under a broad submission alias, rather than filtering kinds by the caller’s keys. These controls can offer actions that the service subsequently refuses; the corrected screen contracts distinguish visibility from authorization. | `SCR-PFM-DJE-003`, `SCR-PFM-DJE-005`, `SCR-PFM-DJE-006`, `SCR-PFM-DJE-007`, `BR-CAP-PFM-DJE-009-01` | See pinned finding_evidence | inconsistency |

| `FND-PFM-DJE-061` | medium | Submit an accountable change across many records retains rule, transition, failure, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-001`, `ATS-PFM-DJE-001` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-062` | medium | Review a change before approving its application retains transition, permission, edge, failure, concurrency, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-002`, `ATS-PFM-DJE-002` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-063` | medium | Process valid records and report individual refusals retains transition, validation category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-003`, `ATS-PFM-DJE-003` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-064` | medium | Interrupt a job and recover its unfinished work retains rule, transition, validation, boundary, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-004`, `ATS-PFM-DJE-004` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-065` | medium | Inspect job progress and account for its changes retains transition, edge, failure, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-005`, `ATS-PFM-DJE-005` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-066` | medium | Preserve intervening edits during bulk changes retains transition, permission, failure, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-006`, `ATS-PFM-DJE-006` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-067` | medium | Approve a counted bulk deletion retains transition, permission, failure, boundary category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-007`, `ATS-PFM-DJE-007` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-068` | medium | Restore a bulk update while preserving later changes retains rule, transition, failure, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-008`, `ATS-PFM-DJE-008` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-069` | medium | Complete selected-record changes from a list dialog retains failure category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-009`, `ATS-PFM-DJE-009` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-070` | medium | Manage selected configuration items through recorded jobs retains transition, edge, failure, concurrency, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-010`, `ATS-PFM-DJE-010` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-071` | medium | Upload a bounded file for reliable job input retains rule, transition, edge, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-011`, `ATS-PFM-DJE-011` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-072` | medium | Import records using their producer identities retains transition, validation, permission, edge, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-012`, `ATS-PFM-DJE-012` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-073` | medium | Translate spreadsheet columns into record details retains transition, permission, concurrency, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-013`, `ATS-PFM-DJE-013` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-074` | medium | Process file jobs within shared workload limits retains transition, permission category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-014`, `ATS-PFM-DJE-014` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-075` | medium | Reconcile loaded records using the producer’s keys retains transition, validation, failure, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-015`, `ATS-PFM-DJE-015` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-076` | medium | Load and reconcile a migration package across its owning applications retains transition, concurrency, invariant category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-016`, `ATS-PFM-DJE-016` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-077` | medium | Reset a loading workspace and review its release retains transition, edge, failure, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-017`, `ATS-PFM-DJE-017` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-078` | medium | Enable product records to use the shared job engine retains transition, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-018`, `ATS-PFM-DJE-018` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-079` | medium | Control capacity protection during database pressure retains transition, edge, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-019`, `ATS-PFM-DJE-019` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-080` | medium | Maintain and retire monthly history partitions retains rule, validation, permission, edge, boundary, concurrency category gaps. Proposed scenarios and the remaining object transition, permission, invariant and crossing-workflow matrix require executable proof before conformance is established. | `CAP-PFM-DJE-020`, `ATS-PFM-DJE-020` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-081` | medium | Compound inherited scenarios combine different test boundaries; selected assertions do not establish every rule clause, domain invariant or full lifecycle transition. The retained bindings describe their existing evidence and require completion of the clause-level audit. | `ATS-PFM-DJE-001`, `ATS-PFM-DJE-002`, `ATS-PFM-DJE-003`, `ATS-PFM-DJE-004`, `ATS-PFM-DJE-005`, `ATS-PFM-DJE-006`, `ATS-PFM-DJE-007`, `ATS-PFM-DJE-008`, `ATS-PFM-DJE-009`, `ATS-PFM-DJE-010`, `ATS-PFM-DJE-011`, `ATS-PFM-DJE-012`, `ATS-PFM-DJE-013`, `ATS-PFM-DJE-014`, `ATS-PFM-DJE-015`, `ATS-PFM-DJE-016`, `ATS-PFM-DJE-017`, `ATS-PFM-DJE-018`, `ATS-PFM-DJE-019`, `ATS-PFM-DJE-020` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-082` | medium | The reset-eligibility and loading-route browser callbacks only record a blocked reason. Their prior bindings are removed; the scenarios remain proposed until runnable fixtures and assertions exist. | `ATS-PFM-DJE-017-01`, `ATS-PFM-DJE-017-07` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-083` | low | Starting a paused run authorizes the remaining steps and resumes running work. The state model omits this start-triggered move although it describes the explicit Resume action; the transition matrix needs a separate start-from-paused check. | `STATE-PFM-DJE-004`, `CAP-PFM-DJE-016` | See pinned testing_gap_evidence | inconsistency |
| `FND-PFM-DJE-084` | medium | Feature acceptance is defined for all five scenario kinds, but the composed feature scenarios lack complete executable bindings. Constituent capability assertions cannot establish a whole feature chain by themselves. | `FAS-PFM-DJE-01`, `FAS-PFM-DJE-02`, `FAS-PFM-DJE-03`, `FAS-PFM-DJE-04`, `FAS-PFM-DJE-05`, `FAS-PFM-DJE-06` | See pinned testing_gap_evidence | coverage-gap |
| `FND-PFM-DJE-085` | medium | Some registered browser files report blocked work or record a guided rehearsal with deviations. Their existence supplies neither completed behavioural assertions nor qualification; they receive no specification bindings. | `TST-PFM-DJE-061`, `TST-PFM-DJE-067`, `TST-PFM-DJE-072`, `TST-PFM-DJE-073`, `TST-PFM-DJE-074`, `TST-PFM-DJE-076`, `TST-PFM-DJE-077`, `TST-PFM-DJE-078`, `TST-PFM-DJE-102` | See pinned testing_gap_evidence | coverage-gap |

## Open Questions

Recommendations are proposed examination advice. The question_evidence entries identify the originating concern; Andrew owns the product decision.

| id | question | why_it_matters | options | recommendation | affects |
|---|---|---|---|---|---|
| `OQ-PFM-DJE-001` | What integrity requirement should apply above the upload measurement limit? | Without a supplied full-object digest, a large-file run relies on the producer declaration rather than measured bytes. | (a) Measure in a background completion stage. (b) Check while consuming and refuse mismatches. (c) Explicitly accept declared integrity for large files. | Prefer (a), giving subsequent readers a verified value; this would change the current acceptance of declared-only digests. | `BR-CAP-PFM-DJE-011-06`, `BR-CAP-PFM-DJE-016-03` |
| `OQ-PFM-DJE-002` | Does Andrew approve engine-backed configuration activation and deactivation under PLAT-M20 D2? | The answer determines whether those status changes use the audited job path. | (a) Use jobs for delete, activate and deactivate. (b) Use jobs only for delete and retain individual status calls. | Prefer (a) for a consistent recorded operation path; the existing implementation is evidence, not approval. | `BR-CAP-PFM-DJE-010-04`, `CAP-PFM-DJE-010` |
| `OQ-PFM-DJE-003` | Should address and phone-number types gain a status under PLAT-M20 D3? | An in-use type cannot currently be retired through a deactivate action. | (a) Introduce status on both catalogues. (b) Retain their delete-only model. | Prefer (a), subject to the owning module decision, so retirement can preserve existing references. | `BR-CAP-PFM-DJE-010-05` |
| `OQ-PFM-DJE-004` | Where should monthly partition maintenance be specified? | Its current assignment groups operational history maintenance with an engine whose evidence tables are unpartitioned. | (a) Retain this module assignment. (b) Assign Platform jobs, audit and licensing. (c) Establish a separately approved storage module. | Prefer (b) alongside scheduled operational maintenance; no ownership change is made here. | `CAP-PFM-DJE-020` |
| `OQ-PFM-DJE-005` | Should keyed imports request duplicate detection when a new key matches an existing person? | Key changes or another producer can introduce another contact for the same person. | (a) Request detection for ongoing feeds, excluding initial loads. (b) Depend on scheduled rescans. (c) Exclude imports from detection. | Prefer (a), distinguishing routine feeds from an initial package that is reconciled separately. | `BR-CAP-PFM-DJE-012-12` |
| `OQ-PFM-DJE-006` | Should contact e-mail addresses persist the type specified by an import column? | Work and personal labels currently influence ordering without surviving as address metadata. | (a) Add an address type through the owning record model. (b) Preserve ordering-only interpretation. | Prefer (a) if imported and manually edited addresses are expected to retain the same classification. | `BR-CAP-PFM-DJE-013-07` |
| `OQ-PFM-DJE-007` | Should a data job tell its submitter when it finishes, rather than being polled? | Large imports and data runs take hours; today staff and integrations must keep reading the job, and nothing notices a job left paused or failed. | (a) Emit a job-settled business event and let Notifications tell the submitter. (b) Emit the event only, for integrations to subscribe. (c) Keep polling only. | Prefer (a): one event per final state (and per pause by the guard), consumed by Notifications for people and available to integrations. | `DOM-PFM-DJE-001`, `ADR-PFM-DJE-018`, `CAP-PFM-DJE-005` |
| `OQ-PFM-DJE-008` | Should the capacity sentinel's emergency stage throttles be switched on in production? | The switch ships off everywhere, so a sustained emergency halves internal write and read factors but never lowers API limits; switching it on protects the database at the cost of refusing callers. | (a) Switch on in production after the load scenarios confirm the thresholds. (b) Keep off and rely on staff pins. (c) Switch on now. | Prefer (a); the approved workload governance values are starting values pending measurement. | `DOM-PFM-DJE-006`, `ADR-PFM-DJE-013`, `CAP-PFM-DJE-019` |
