Skip to content

A System is a top-level composition construct that declares a finite set of member contracts and their cross-contract relationships. Systems enable multi-contract coordination: shared persona identity across contracts, cross-contract flow triggers, and cross-contract entity relationships. A System does not alter single-contract semantics -- it is a pure composition overlay.

DSL Syntax

hcl
system <system_id> {
  members: [
    <member_id>: "<file_path>",
    ...
  ]

  shared_personas: [
    { persona: <persona_id>, contracts: [<member_id>, ...] },
    ...
  ]

  triggers: [
    {
      source: <member_id>.<flow_id>,
      on: success | failure | escalation,
      target: <member_id>.<flow_id>,
      persona: <persona_id>
    },
    ...
  ]

  shared_entities: [
    { entity: <entity_id>, contracts: [<member_id>, ...] },
    ...
  ]
}

Fields

FieldRequiredDescription
membersYesMap of member ids to file paths of member contracts. Paths are relative to the system file's directory.
shared_personasNoPersonas recognized as the same identity across listed contracts.
triggersNoCross-contract flow triggers: when a source flow reaches a terminal outcome, a target flow is initiated.
shared_entitiesNoEntities whose state is coordinated across listed contracts. Must have identical state sets.

File Constraints

A System is declared in a dedicated .tenor file. A system file:

  • May not contain Fact, Entity, Rule, Persona, Operation, or Flow declarations.
  • May contain only one system declaration.
  • Member files may not contain system declarations (no nested systems).

Members

Each member maps a MemberId (unique within the system) to a file path of a valid Tenor contract:

hcl
members: [
  inspection:       "../supply_chain/inspection.tenor",
  letter_of_credit: "../trade_finance/letter_of_credit.tenor"
]

Member contracts are elaborated independently through the full six-pass pipeline. A contract within a system produces identical elaboration output as the same contract elaborated outside a system. If any member fails elaboration, the system elaboration fails.

Shared Personas

A shared_personas declaration specifies a PersonaId and a set of MemberIds. It asserts identity equivalence -- the same role has authority in all listed contracts:

hcl
shared_personas: [
  { persona: admin, contracts: [order_mgmt, fulfillment] },
  { persona: warehouse_ops, contracts: [order_mgmt, fulfillment] }
]

What shared persona means:

  • A persona authenticated in one member contract is considered authenticated in all sharing contracts (E-SYS-03a).
  • Authorization is still per-contract: sharing identity does NOT grant authority across contracts. If admin is shared between A and B, admin can only invoke operations that list admin in their allowed_personas in each respective contract (E-SYS-03c).
  • The binding creates no new evaluation semantics. It is a static assertion consumed at runtime by the executor.

What it does NOT mean:

  • It does not merge or federate persona definitions.
  • It does not create a superset of authority.
  • If two contracts have no natural persona overlap, use shared_personas: [].

Triggers

Triggers connect flow outcomes in one contract to flow initiations in another:

hcl
triggers: [
  {
    source: inspection.inspection_flow,
    on: success,
    target: letter_of_credit.lc_presentation_flow,
    persona: beneficiary
  }
]

Trigger semantics:

  • Asynchronous. The source flow completes independently of the target flow's execution. The executor must NOT block the source flow on the target flow.
  • At-most-once. Each trigger fires at most once per source flow execution.
  • Fresh snapshot. The target flow takes its own snapshot at initiation, independent of the source flow's snapshot.
  • Failure recording. If target flow initiation fails, the executor records a TriggerFailureRecord and does NOT silently discard the failure. The source flow's outcome is not affected.
  • Acyclic graph. The trigger declarations form a directed graph. This graph must be acyclic (C-SYS-15). Cycles are elaboration errors.

The on field accepts: success, failure, or escalation -- matching flow terminal outcomes.

Shared Entities

Shared entities coordinate state across member contracts:

hcl
shared_entities: [
  { entity: Order, contracts: [order_mgmt, fulfillment] }
]

Requirements:

  • Each referenced member contract must declare the entity with identical state sets (sorted comparison of state names).
  • Different operations or transitions across contracts are permitted -- only the state set must match.
  • The executor coordinates entity state across sharing contracts with eventual consistency (E-SYS-02).

System-Level Static Analysis

System elaboration extends the standard pipeline:

PassSystem Integration
0 (Parse)Parser recognizes system keyword.
1 (Bundle)Member contract file paths resolved and each member elaborated independently.
2 (Index)System indexed by (System, id). Members indexed by MemberId.
5 (Validate)System-level validation: member uniqueness, shared persona existence, trigger validation, shared entity state set equality, trigger graph acyclicity.
6 (Serialize)System serialized as top-level interchange item. Member bundles preserved as separate items.

Cross-contract S6: When contracts are composed into a System, S6 extends across contract boundaries. tenor check on a system reports:

Cross-Contract Flow Paths (S6): 1 cross-contract triggers, 1 cross-contract paths

Findings:
  [s6_cross/INFO]: Cross-contract flow trigger:
    inspection.inspection_flow --[success]--> letter_of_credit.lc_presentation_flow
    (persona: beneficiary)

This verifies: (1) the source flow has the declared terminal outcome, (2) the target flow exists, (3) the persona is declared in the target contract, (4) the trigger chain is acyclic.

Full Working Example

A complete system connecting supply chain inspection to trade finance:

hcl
system trade_inspection_system {
  members: [
    inspection:       "../supply_chain/inspection.tenor",
    letter_of_credit: "../trade_finance/letter_of_credit.tenor"
  ]

  shared_personas: []

  triggers: [
    {
      source: inspection.inspection_flow,
      on: success,
      target: letter_of_credit.lc_presentation_flow,
      persona: beneficiary
    }
  ]

  shared_entities: []
}

Why shared_personas: []: The supply chain domain uses customs_officer, quality_inspector, port_authority, and shipping_agent. The trade finance domain uses applicant, beneficiary, issuing_bank, advising_bank, and confirming_bank. These domains have no natural persona overlap. The trigger is the only relationship, and the system declaration is honest about that.

Why shared_entities: []: The supply chain tracks Shipment, QualityLot, and ComplianceLot. Trade finance tracks LetterOfCredit and Document. No entity exists in both domains.

Constraints

C-SYS-01 -- Member id uniqueness. (Pass 2) Violation: "duplicate member id '<id>' in System '<system_id>'".

C-SYS-02 -- Member file resolution. (Pass 1) Each member file must resolve to an independently elaboratable contract.

C-SYS-03 -- No nested systems. (Pass 1) Violation: "member '<member_id>' is a System file; nested Systems are not permitted".

C-SYS-04 -- System file exclusivity. (Pass 0) Violation: "System files may not contain contract constructs".

C-SYS-05 -- One system per file. (Pass 0) Violation: "multiple System declarations in a single file".

C-SYS-06 -- Shared persona existence. (Pass 5) Violation: "persona '<persona_id>' not declared in member contract '<member_id>'".

C-SYS-07/08 -- Trigger source/target contract validity. (Pass 5) Violation: "trigger source contract '<id>' is not a System member".

C-SYS-09/10 -- Trigger source/target flow existence. (Pass 5) Violation: "flow '<flow_id>' not found in member contract '<contract_id>'".

C-SYS-11 -- Trigger outcome validity. (Pass 5) Must be "success", "failure", or "escalation". Violation: "invalid trigger outcome '<outcome>'".

C-SYS-12 -- Trigger target persona validity. (Pass 5) Violation: "persona '<persona_id>' not declared in target contract '<contract_id>'".

C-SYS-13 -- Shared entity existence. (Pass 5) Violation: "entity '<entity_id>' not declared in member contract '<member_id>'".

C-SYS-14 -- Shared entity state set equality. (Pass 5) Violation: "entity '<entity_id>' has different state sets in member contracts '<a>' and '<b>'".

C-SYS-15 -- Trigger graph acyclicity. (Pass 5) Cycle detection via DFS over (MemberId, FlowId) pairs. Violation: "trigger cycle detected: <cycle_path>".

C-SYS-16/17 -- Shared persona/entity contracts are members. (Pass 5) Violation: "contract '<member_id>' in shared_persona is not a System member".

Common Mistakes

Circular triggers. A triggers B triggers A is rejected. Design trigger graphs as DAGs.

Sharing personas that do not genuinely overlap. If two contracts have no natural persona overlap, use shared_personas: []. Do not manufacture shared personas to "connect" contracts. The trigger mechanism handles cross-contract coordination.

Mismatched state sets on shared entities. If Order in contract A has states [pending, confirmed, shipped] and Order in contract B has [pending, confirmed, delivered], the state sets differ and the system is rejected.

Nested systems. A member file cannot itself contain a system declaration. System composition is one level deep.

How Systems Connect to Other Constructs

  • Contracts are the members of a system. Each is independently valid.
  • Personas may be shared across contracts, creating identity equivalence.
  • Entities may be shared, requiring identical state sets and coordinated state.
  • Flows are the source and target of triggers. Trigger outcomes match flow terminal outcomes.
  • Individual contract guarantees (S1--S8) are preserved unchanged. The system adds cross-contract S6.

Executor Obligations

Systems introduce four additional executor obligations:

ObligationDescription
E-SYS-01Cross-contract trigger execution: asynchronous, at-most-once, with failure recording.
E-SYS-02Cross-contract entity state coordination: eventual consistency with E2 validation.
E-SYS-03Shared persona identity enforcement: authentication equivalence across sharing contracts.
E-SYS-04Cross-contract snapshot coordination: per-contract isolation preserved, no cross-contract snapshot merging.