---
id: SVC-MBR-STR-terms
title: Term Engine
product_area: membership
module: structure
repository: services-membership
source_module: modules/terms
revision: 1
status: draft
design_intent: confirmed
origin: >-
  D-45 (decided 2026-10-17): services-membership:README.md#The term engine (the engine imports nothing of
  Membership and is extracted later)
implementation_evidence: observed
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
inference: []
owns:
  - DOM-MBR-STR-005
does_not_own:
  - 'the memberships module owns holdings, terms, lifecycle events, stored caches and sweep records.'
  - the memberships module owns scheduled sweep execution and published membership events.
  - the memberships module and Commerce own purchase preparation and billing execution.
  - Configuration owns the lifecycle reason catalogue's storage and HTTP routes.
operations:
  - operation_id: getTermsTenantHealth
    intent: Report the deployed term API build for a workspace the caller can access through Membership.
    access: console
    permission: membership.application.access
    realises:
      - CAP-MBR-STR-019
    published_to_submissions: 'not published: a build and access health check collects no submission'
  - operation_id: computeTermPeriod
    intent: 'Calculate purchased term dates from a supplied rule, business date and continuation context.'
    access: internal
    permission: none; called by Membership code that has already authorised its caller
    realises:
      - CAP-MBR-STR-015
    published_to_submissions: 'not published: an internal calculation or SQL template is not submitter intake'
  - operation_id: termRuleProblems
    intent: Return the complete set of problems found in a proposed term rule.
    access: internal
    permission: none; called by the configuration service
    realises:
      - CAP-MBR-STR-015
    published_to_submissions: 'not published: an internal calculation or SQL template is not submitter intake'
  - operation_id: statusOf and episodesOf
    intent: Compute date-specific standing and effective continuity episodes from supplied term facts and settings.
    access: internal
    permission: none; called by Membership code that has already authorised its caller
    realises:
      - CAP-MBR-STR-016
    published_to_submissions: 'not published: an internal calculation or SQL template is not submitter intake'
  - operation_id: cacheOf
    intent: >-
      Recompute a holding cache from terms and current domain settings; the caller compares and persists
      differences.
    access: internal
    permission: none
    realises:
      - CAP-MBR-STR-016
    published_to_submissions: 'not published: an internal calculation or SQL template is not submitter intake'
  - operation_id: 'sweep.boundariesOf, sweep.needsCatchUp and sweep.detectionsOf'
    intent: 'Supply boundary dates, catch-up decisions and expiry or lapse detections for a requested sweep date.'
    access: internal
    permission: none
    realises:
      - CAP-MBR-STR-016
    published_to_submissions: 'not published: an internal calculation or SQL template is not submitter intake'
  - operation_id: migrationSql
    intent: Produce the adopting domain's SQL function templates without executing a migration.
    access: internal
    permission: none
    realises:
      - CAP-MBR-STR-016
    published_to_submissions: 'not published: an internal calculation or SQL template is not submitter intake'
events: []
jobs: []
integrations:
  - system: Memberships module (the engine's one adopting domain)
    direction: inbound
    contract: >-
      The adopting domain names its tables and classification and offering columns and supplies rule, grace,
      benefit, continuity and eligibility hooks. It takes locks and persists decisions; engine facade methods
      can call those domain hooks.
consistency:
  - rule: >-
      Pure helpers make decisions without persisted reads or writes; facade methods obtain inputs through
      domain hooks, and transaction consistency belongs to the caller.
    kind: transactional
    compensation: There is no engine-owned persisted result to undo.
  - rule: >-
      Current-input resolution and stored cache are distinct; repeated missed sweeps can leave caches stale
      until successful catch-up.
    kind: eventual
    compensation: A later successful full sweep refreshes the holding cache.
evidence:
  - >-
    services-membership at 5994c270: aws/terms/terms.routes.ts; modules/terms/services/define-term-engine.ts,
    term-rules.ts, status.ts, holding-cache.ts, sweep.ts, sql-templates.ts;
    modules/terms/tests/unit/isolation.spec.ts; modules/memberships/services/membership-engine.ts,
    membership-caches.ts, sweep/status-sweep.ts (callers); README.md#The term engine.
controls: [TC-AVL-002, TC-AVL-003, 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-CRY-001, TC-CRY-002, TC-CRY-003, TC-DAT-001, TC-DAT-007, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-MON-001, TC-MON-003, TC-MON-004, TC-PI-001, TC-PI-003, TC-PI-005, TC-SEC-001, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Term Engine

## What This Service Is For

The term engine supplies reusable calculations for term dates, standing, continuity and scheduled boundary work. Membership is the current adopter, with an explicit isolation boundary intended to support later reuse.

## Boundary

Pure helpers own the shared interpretation, while the adopting domain owns holdings, terms, events, locking and persistence. The facade uses domain hooks for current allowances and rules. Configuration stores reasons, and Memberships implements the operational purchase and billing flows.

## Operations in Words

One workspace HTTP health route checks access and reports build information. Internal interfaces calculate periods, validate rules, resolve status and episodes, compute caches, decide sweep work and generate SQL templates. The engine's Commerce participant and billing members still fail as unbuilt; they are not evidence of completed operational flows.

## Events and Jobs

The engine publishes no event and schedules no job. Memberships calls its decisions, records unique detections and publishes termination when lapse is first recorded.

## Consistency Guarantees

The caller supplies the transaction around domain reads and writes. Pure decision functions are repeatable for identical inputs, while facade calls depend on the hooks they receive. A missed sweep delays persisted cache and detection work without changing how current-input resolution calculates standing.
