---
id: ATS-CRM-ACT-004
scope: CAP-CRM-ACT-004
product_area: crm
module: activities-tasks
revision: 3
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  rhythm-v2-docs: 18a49edf30ee6bda18b159b65a2b91e093ea713d
scenarios:
- id: ATS-CRM-ACT-004-01
  title: Reject attachment overflow
  level: api
  proves:
  - BR-CAP-CRM-ACT-004-01
  preconditions: An activity can accept valid managed attachments.
  steps: Submit 21 attachment entries.
  expected: The request identifies the attachment limit.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#refuses
    more than 20 attachments
  - TST-CRM-ACT-007
  provenance: test
  source: services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#refuses
    more than 20 attachments
  category: boundary
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-004-02
  title: Require prepared managed file references
  level: api
  proves:
  - BR-CAP-CRM-ACT-004-02
  preconditions: A prepared upload and an unprepared address are available.
  steps: Save activities with each reference.
  expected: The prepared file becomes permanent and the unprepared reference is rejected.
  negative: true
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#stores
    an uploaded file as a permanent reference of the activity, and attaches its lifecycle row
  - services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#refuses
    a file reference that did not come through the pipeline
  - TST-CRM-ACT-007
  provenance: test
  source: services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#stores
    an uploaded file as a permanent reference of the activity, and attaches its lifecycle row
  category: validation
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-004-03
  title: Replace only the submitted attachment list
  level: api
  proves:
  - BR-CAP-CRM-ACT-004-03
  preconditions: An activity holds two attachments.
  steps: Submit a replacement list containing one unchanged file.
  expected: Only that file remains attached.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#keeps
    an attachment sent back unchanged, and removes one left out
  - TST-CRM-ACT-007
  provenance: test
  source: services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#keeps
    an attachment sent back unchanged, and removes one left out
  category: rule
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-004-04
  title: Skip file copying during create replay
  level: api
  proves:
  - BR-CAP-CRM-ACT-004-06
  preconditions: A managed attachment accompanies activity creation.
  steps: Repeat the create under the same identifier.
  expected: The permanent file is reused without a second copy.
  negative: false
  data_needs: Each run creates and isolates the records it needs.
  bound_to:
  - services-crm:modules/activities/tests/integration/services/persistence/activities.create-retries.integration.spec.js#copies
    nothing for the retry
  - services-crm:modules/activities/tests/integration/services/persistence/activities.create-retries.integration.spec.js#answers
    the attachment the first attempt stored
  - TST-CRM-ACT-006
  provenance: test
  source: services-crm:modules/activities/tests/integration/services/persistence/activities.create-retries.integration.spec.js#copies
    nothing for the retry
  category: invariant
  binding_scope: Each registered suite contributes the assertions named by the retained file bindings;
    a compound scenario can require several suites. Conformance remains unverified.
- id: ATS-CRM-ACT-004-05
  title: Deletion releases the corrected attachment set
  category: interaction
  level: api
  proves:
  - BR-CAP-CRM-ACT-004-03
  - BR-CAP-CRM-ACT-004-05
  - BR-CAP-CRM-ACT-003-07
  preconditions: An interaction has two prepared files.
  steps: Remove one file through an edit, omit files in another partial edit, then delete the interaction
    and inspect cleanup requests.
  expected: The omitted list preserves the remaining attachment; deletion removes its local entry and
    requests cleanup for released references without claiming physical storage deletion.
  negative: false
  data_needs: Run-owned records in an isolated workspace; fixed clock for calendar checks.
  bound_to: []
  provenance: proposed
  source: services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#keeps
    an attachment sent back unchanged, and removes one left out; services-crm:modules/activities/services/persistence/activities.ts:deleteActivity;
    services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#removes
    the activity and its links
  exercises:
  - CAP-CRM-ACT-004
  - CAP-CRM-ACT-003
  related:
  - CAP-CRM-ACT-003
evidence:
- 'services-crm at a8d1364f1dd44b723bb5f9acba12f983e9ec8d69: scenario sources, executable assertions and
  local dependency boundaries are inspected.'
- 'react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: scoped component tests and browser journey
  assertions are inspected.'
coverage:
  rule: covered
  transition: 'gap: FND-CRM-ACT-050'
  validation: covered
  permission: 'gap: FND-CRM-ACT-050'
  edge: 'gap: FND-CRM-ACT-050'
  failure: 'gap: FND-CRM-ACT-050'
  boundary: covered
  concurrency: 'gap: FND-CRM-ACT-050'
  invariant: covered
  interaction: covered
coverage_obligations:
  finding: FND-CRM-ACT-050
  unproved_rules:
  - BR-CAP-CRM-ACT-004-07
  permission_matrix:
    keys:
    - crm.activities.create
    - crm.activities.update
    remaining: Complete allow/refuse combinations, including each console guard and each API operation.
  execution_note: Covered means a scenario is specified; it does not mean that scenario has executed or
    every variant has an executable binding.
related_coverage:
- capability: CAP-CRM-ACT-003
  scenarios:
  - ATS-CRM-ACT-004-05
  finding: FND-CRM-ACT-050
permission_coverage:
- key: crm.activities.create
  finding: FND-CRM-ACT-050
  note: The finding covers unproved operation and surface combinations; a permission-category scenario
    is not a complete permission matrix.
- key: crm.activities.update
  finding: FND-CRM-ACT-050
  note: The finding covers unproved operation and surface combinations; a permission-category scenario
    is not a complete permission matrix.
---

# Retain supporting files with an activity: Capability Test Specification

## Coverage

Category coverage counts specified proof. Unbound cases remain proposed; registered assertions do not establish a passing run.

| Rule | Proof Scenario Or Finding |
|---|---|
| `BR-CAP-CRM-ACT-004-01` | `ATS-CRM-ACT-004-01` |
| `BR-CAP-CRM-ACT-004-02` | `ATS-CRM-ACT-004-02` |
| `BR-CAP-CRM-ACT-004-03` | `ATS-CRM-ACT-004-03`, `ATS-CRM-ACT-004-05` |
| `BR-CAP-CRM-ACT-004-05` | `ATS-CRM-ACT-004-05` |
| `BR-CAP-CRM-ACT-004-06` | `ATS-CRM-ACT-004-04` |
| `BR-CAP-CRM-ACT-004-07` | `FND-CRM-ACT-050` |

## Interactions With Related Capabilities

An interaction has two prepared files. Remove one file through an edit, omit files in another partial edit, then delete the interaction and inspect cleanup requests.

The interaction scenario names the capabilities and rules it exercises. The coverage finding retains incomplete permission combinations and failure variants.
