---
id: WF-PFM-OPS-013
title: Read one commercial company into licence windows
product_area: platform
module: operations
revision: 1
status: draft
design_intent: confirmed
implementation_evidence: partially-observed
inference: []
origin: >-
  services-platform:docs/proposals/application-access-and-entitlements.md#4.3 and #4.4 (built and accepted by
  Andrew 2026-10-15; source switched off until its key exists)
trigger: 'A queue message, manual staff request or company-link trigger reaches the shared company-sync function.'
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
implements:
  - CAP-PFM-OPS-012
moves:
  - STATE-PFM-OPS-005
crosses:
  - SVC-PFM-OPS-licensing
idempotency: >-
  Repeating the same complete input converges in sequential use. Window comparison suppresses refresh when
  values and source contracts are unchanged; replacement still updates copy and health bookkeeping.
concurrency: >-
  Company replacement is transactional, without a company-wide lock or source-version check. Ordering of
  overlapping snapshots is unknown. Bounded worker concurrency is not a provider rate-limit guarantee.
hops:
  - 'n': 1
    actor_or_service: Licensing sync
    action: 'Resolve the provider; when no token exists, record not_configured and return without changing windows.'
    anchor: 'services-platform:modules/licensing/services/sync/sync-company-licences.ts:syncCompanyLicences'
    seam: sync
    on_failure: >-
      Propagate failures of configuration resolution or health persistence; an ordinary unconfigured result is
      acknowledged.
    left_inconsistent: Stored commercial coverage is retained.
    observer: Sync health read is the observation surface.
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/sync/sync-company-licences.integration.spec.js#leaves
      the licences of a company synced before the key was removed exactly as they were
  - 'n': 2
    actor_or_service: Licensing sync
    action: Read all company contracts and line items before starting replacement.
    anchor: 'services-platform:modules/licensing/hubspot/hubspot-provider.ts'
    seam: sync
    on_failure: >-
      Record redacted provider failure and return a failed result rather than throw, unless that failure
      handling itself fails.
    left_inconsistent: Prior coverage remains even if it is stale.
    observer: Sync health read; the log is the observation surface.
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/sync/sync-company-licences.integration.spec.js#changes
      no snapshot, no window and no last success
  - 'n': 3
    actor_or_service: Licensing sync
    action: Resolve mapped in-force terms into application windows and diagnostics for unresolved inputs.
    anchor: 'services-platform:modules/licensing/services/licences/resolve-licence-windows.ts'
    seam: sync
    on_failure: Propagate an unexpected resolver error before writing replacement.
    left_inconsistent: The earlier commercial snapshot remains intact.
    observer: Flags on the company read is the observation surface.
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/unit/licences/resolve-licence-windows.spec.ts#licenses nothing
      and flags the SKU when the map does not cover it
  - 'n': 4
    actor_or_service: Licensing sync
    action: 'Replace contract copies, lines, application windows and success health in one transaction.'
    anchor: 'services-platform:modules/licensing/services/sync/sync-company-licences.ts:syncCompanyLicences'
    seam: sync
    on_failure: Roll back a failed replacement and propagate the error to the trigger.
    left_inconsistent: No partial successful replacement commits.
    observer: Sync health read is the observation surface.
    provenance: observed
    source: 'services-platform:modules/licensing/services/sync/sync-company-licences.ts:syncCompanyLicences'
  - 'n': 5
    actor_or_service: Licensing sync
    action: Request one cache refresh after commit when the resolved windows differ.
    anchor: >-
      services-platform:modules/security/services/authorizer-flush/submit-flush-job.ts:submitAuthorizerFlushJob
    seam: state_machine
    on_failure: Contain refresh submission failure and rely on cached-authority expiry.
    left_inconsistent: The new coverage can be stored before cached access reflects it.
    observer: Refresh job’s record is the observation surface.
    provenance: test
    source: >-
      services-platform:modules/licensing/tests/integration/services/sync/sync-company-licences.integration.spec.js#changes
      nothing and asks for no second flush when the read is the same as the last
branches:
  - condition: The trigger is the queue consumer
    path: >-
      Malformed input and returned sync outcomes are acknowledged. A thrown error permits redelivery, with a
      five-receive limit before dead-letter handling.
  - condition: The trigger is a staff Sync Now
    path: >-
      Staff can request the company read synchronously with licensing-management authority and receive its
      outcome.
waits: []
evidence:
  - >-
    services-platform at ad3f6a6: modules/licensing (services/sync/sync-company-licences.ts,
    services/licences/resolve-licence-windows.ts, hubspot/*, aws/lambda/LICENCE_SYNC.handler.ts,
    aws/resources/licence-sync.sqs.ts, licensing.settings.ts); docs/licensing.md §10 to §12.
  - >-
    codex examination 2026-10-23: checked the pinned source anchors, planning references and enforcement
    boundaries; unresolved limits are recorded in module findings.
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-003, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-SEC-001, TC-SEC-002, TC-SEC-003, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Read one commercial company into licence windows

## What It Does

All commercial triggers use one company-sync function. It finishes the provider read, resolves coverage and commits the replacement atomically. Missing configuration or provider failure updates health while preserving existing stored coverage.

## The Flow

```mermaid
flowchart TD
  H0["Resolve the provider; when no token exists, record not_configured and return without changing windows."]
  H1["Read all company contracts and line items before starting replacement."]
  H0 --> H1
  H2["Resolve mapped in-force terms into application windows and diagnostics for unresolved inputs."]
  H1 --> H2
  H3["Replace contract copies, lines, application windows and success health in one transaction."]
  H2 --> H3
  H4["Request one cache refresh after commit when the resolved windows differ."]
  H3 --> H4
```

## When Something Fails

Recorded provider failure is acknowledged by the queue consumer, so recovery normally waits for another trigger such as nightly reconciliation. Thrown processing failures are eligible for queue redelivery and eventual dead-lettering. New contract coverage does not prepare a missing operational application. The pinned guide describes configuration and property validation as unfinished; it does not prove live runtime configuration.

## Open Design Questions

Accepted preparation-on-licence intent remains absent from contract sync. Concurrent company reads and real-provider activation also require proof.
