Scenario Authoring

Start with one real conversation: an X12 850 order and its 810 invoice

Suppose a retailer sends your company an X12 850 purchase order and your company later returns an X12 810 invoice. A scenario turns that familiar exchange into a repeatable proof that the right documents, maps, partner route, acknowledgments, timing, and business values all agree.

Maps define how documents are processed; scenarios define and prove the business conversation those maps implement. A ScenarioDefinition is the portable recipe for that conversation: who exchanges each X12 business document, which documents belong together, what order and repetition are allowed, and what evidence must pass. Tenant partners, syntax trees, mappings, and executable targets belong in a ScenarioBinding.

Scenario definitions and bindings are strict JSON documents. Their JSON Schema Draft 2020-12 contracts drive external tooling, Mapper completion and diagnostics, examples, and this generated reference. Server validation adds cross-file, tenant-ownership, conversation-rule, extracted-fact, and executable-support checks that JSON Schema cannot express alone.

Mental model

Definition → Binding → Run → Evidence

  1. DefinitionThe reusable recipe for an X12 business conversation: roles, document steps, allowed order and repetition, matching rules, evidence requirements, and business checks.
  2. BindingThe tenant-specific wiring that selects the partners, workspace, maps, fact expressions, server-side execution implementation, and optional X12 syntax-tree versions used by that recipe.
  3. RunOne timestamped evaluation of an applied binding against persisted transactions and platform evidence.
  4. EvidenceThe durable, hash-identified record of what happened and why the run passed, failed, was cancelled, or remained inconclusive.

The signed-in Workspace API is the customer HTTP API for definitions, bindings, runs, context, operations, and evidence reports. A conversation graph is only the definition's model of actors, document steps, and directed rules; the scenario runtime is the server-side evaluator that executes supported applied bindings. Some generated OpenAPI component names begin with ScenarioGraph because they represent conversation-graph state inside a run; they remain part of the Workspace API, not a separate Graph API.

*.scenario.json

ModernEDI ScenarioDefinition v1

Authoring workflow

  1. Create a *.scenario.json draft in Mapper Explorer. JSON Schema supplies completion, hover help, and immediate structural diagnostics.
  2. Run Validate to check references, X12 catalog values, closure and branch rules, typed operands, and whether the current scenario runtime can execute the definition.
  3. Publish only after validation succeeds. Publish creates an immutable definition identity and content hash for bindings.
  4. Create and Apply a matching *.binding.json to resolve tenant partners, mappings, adapters, and optional syntax-tree choices.
  5. Start a scenario run with the applied binding, then inspect each occurrence, evidence item, correlation, and assertion in Implementation Verification.

Server semantic checks

  • Actor, step, transition, parameter, checkpoint, branch, predicate, fact, and pipeline-stage IDs are unique in their documented scopes.
  • Every referenced actor, step, fact, checkpoint, transition, and parameter exists, and every document step goes from one actor to a different actor. A correlation may read facts only from its two connected steps. A branch condition may read facts only from the common source step and cannot use a destination document to select itself.
  • An occurrence minimum cannot exceed its maximum; every repeated step has an objective closure rule; repeated-document pairing and every/any/count behavior are explicit; durations are positive and no longer than P365D. A min-zero step uses expected_count because zero observations cannot satisfy max_reached, unless every incoming follows path is branch-controlled so an unselected path supplies the no-document outcome. expected_count uses an exact integer parameter that is required at run start or has a default within the step bounds; steps sharing that parameter must have overlapping bounds.
  • Transaction sets exist in the X12 catalog, while 997 and 999 are represented as assurance evidence.
  • Ordinary next-document paths cannot loop, and every step belongs to the same connected conversation. Only supersedes with previous matching may form a same-step revision chain, and that repeated step must allow at least two occurrences; cancels identifies a distinct cancellation-document step.
  • Each operator receives compatible typed values from facts, run parameters, or literals; list and set elements must use one exact scalar type.
  • Each composed processing pipeline contains one exchange stage in valid order and at most one map and assure stage. map must be directly beside exchange; Apply requires it before exchange for an outgoing runtime mapping and after exchange for an incoming one. Every parameter named by prepare is required at run start or has a default. Every declared fact appears in exactly one extract stage. Every declared checkpoint has exactly one emitting stage, a step that emits a checkpoint can occur only once, and a branch fact is extracted before its decision checkpoint.
  • supersedes and cancels require a revision effect; follows forbids one. previous matching is supersedes-only, requires a step occurrence max of at least 2, and requires record for both matching and effect because the first occurrence is the initial revision. Revisions always match the unchanged observation history, cannot be branch alternatives, and cannot open or schedule a next-document path. Each branch checkpoint must be emitted by the alternatives' shared source step and must necessarily observe at least one document, so expected_count closure with occurrence min 0 is rejected. Each branch-decision round uses only steps already allowed at its start; a selected path becomes available in the next round. After branch selection, a revision affects checks only when both endpoint steps remain on the selected path. retain keeps the original document for branch conditions, follows transitions, and assertions; reevaluate uses the replacement or removal instead. A later effective time wins, and equal latest times fail with REVISION_EFFECT_CONFLICT.
  • The definition's combined worst-case occurrence summaries, transition pairs, checks, and compact evidence references must fit the v1 durable run-state budget. Per-step JSON Schema maxima for fact declarations and occurrences are structural ceilings, not separately available runtime quotas.

Runtime capacity

Validate and Apply conservatively estimate deterministic durable run-state growth rather than accepting each step independently. The estimate includes occurrence summaries, compact evidence references, checks, and quadratic transition-pair and revision-check growth. It does not reserve the maximum runtime value size for every declared fact; actual Mapper-derived values and evidence are checked against separate per-observation limits before persistence. A definition is rejected with runtime_capacity_exceeded when its combined structural projection exceeds the v1 durable run-state budget.

  • Durable run-state projection budget: 480,000 bytes.
  • Per-step JSON Schema fact declaration maximum: 100; this is a structural ceiling, not preallocated runtime value capacity.
  • Per-step JSON Schema occurrence maximum: 1000; this is a structural ceiling, not an independently available quota.
  • Stable compiler diagnostic: runtime_capacity_exceeded.

Example

{
  "$schema": "https://www.modernedi.com/docs/scenarios/schemas/scenario-definition-v1.schema.json",
  "apiVersion": "modernedi.com/scenario/v1",
  "kind": "ScenarioDefinition",
  "metadata": {
    "namespace": "acme",
    "key": "retail-order-invoice",
    "version": "1.0.0"
  },
  "spec": {
    "actors": [
      {
        "id": "retailer"
      },
      {
        "id": "supplier"
      }
    ],
    "steps": [
      {
        "id": "purchaseOrder",
        "fromActor": "retailer",
        "toActor": "supplier",
        "transaction": {
          "standard": "X12",
          "transactionSet": "850",
          "businessUsage": "purchase_order"
        },
        "occurrence": {
          "min": 1,
          "max": 1,
          "closure": {
            "kind": "fixed"
          }
        },
        "assurance": {
          "requirements": [
            {
              "type": "mapping_succeeded"
            }
          ]
        },
        "facts": [
          {
            "name": "purchaseOrderNumber",
            "type": "string",
            "cardinality": "one",
            "normalization": [
              "trim"
            ],
            "sensitivity": "business"
          }
        ],
        "pipeline": [
          {
            "id": "exchange",
            "kind": "exchange"
          },
          {
            "id": "extract",
            "kind": "extract",
            "facts": [
              "purchaseOrderNumber"
            ]
          },
          {
            "id": "assure",
            "kind": "assure"
          }
        ]
      },
      {
        "id": "invoice",
        "fromActor": "supplier",
        "toActor": "retailer",
        "transaction": {
          "standard": "X12",
          "transactionSet": "810",
          "businessUsage": "invoice"
        },
        "occurrence": {
          "min": 1,
          "max": 1,
          "closure": {
            "kind": "fixed"
          }
        },
        "assurance": {
          "requirements": [
            {
              "type": "transport_receipt_accepted",
              "within": "PT4H"
            },
            {
              "type": "functional_or_implementation_acknowledgment_accepted"
            }
          ]
        },
        "facts": [
          {
            "name": "purchaseOrderNumber",
            "type": "string",
            "cardinality": "one",
            "normalization": [
              "trim"
            ],
            "sensitivity": "business"
          },
          {
            "name": "invoiceTotal",
            "type": "decimal",
            "cardinality": "optional",
            "normalization": [
              "decimal_canonical"
            ],
            "sensitivity": "financial"
          }
        ],
        "pipeline": [
          {
            "id": "exchange",
            "kind": "exchange"
          },
          {
            "id": "extract",
            "kind": "extract",
            "facts": [
              "purchaseOrderNumber",
              "invoiceTotal"
            ]
          },
          {
            "id": "assure",
            "kind": "assure"
          }
        ]
      }
    ],
    "transitions": [
      {
        "id": "invoiceSettlesOrder",
        "fromStep": "purchaseOrder",
        "toStep": "invoice",
        "relationship": "follows",
        "within": "P30D",
        "correlations": [
          {
            "id": "samePurchaseOrder",
            "operator": "equal",
            "left": {
              "kind": "fact",
              "stepId": "purchaseOrder",
              "fact": "purchaseOrderNumber",
              "projection": "value"
            },
            "right": {
              "kind": "fact",
              "stepId": "invoice",
              "fact": "purchaseOrderNumber",
              "projection": "value"
            }
          }
        ],
        "matching": {
          "strategy": "correlate",
          "quantifiers": [
            {
              "kind": "every",
              "scope": "from"
            },
            {
              "kind": "every",
              "scope": "to"
            }
          ],
          "unmatched": "fail"
        }
      }
    ],
    "assertions": [
      {
        "id": "invoiceTotalExists",
        "operator": "exists",
        "left": {
          "kind": "fact",
          "stepId": "invoice",
          "fact": "invoiceTotal",
          "projection": "value"
        }
      }
    ],
    "parameters": [],
    "checkpoints": [],
    "branches": []
  }
}

*.binding.json

ModernEDI ScenarioBinding v1

A tenant-scoped authoring binding that connects every actor and step in one immutable ScenarioDefinition to current workspace partners and executable targets. It references tenant artifacts by identity and contains no copied runtime configuration, credentials, private keys, or other secrets.

Authoring workflow

  1. Publish or select the exact ScenarioDefinition first; copy its namespace, key, version, and contentSha256 into spec.definition.
  2. Bind every actor exactly once. Use one workspace endpoint and one or more current partner endpoints.
  3. Bind every step exactly once to an evidence-constrained runtime mapping, active executable adapter, or observation-only target. Runtime-mapping and observation-only targets do not initiate exchanges.
  4. For every semantic fact declared by a tenant-authored definition step, add one factSources entry. Its expression uses the same X12 Mapper language and functions as an incoming map's primaryKeyExtractor.
  5. Omit syntaxTree for the easiest authoring experience when the chosen target can resolve it. Specify it only when you deliberately need an implementation-guide pin.
  6. Run Validate, then Apply. Apply resolves current artifacts, fails closed on drift or ambiguity, and stores an immutable runtime revision.

Editor and API tooling

  • factSources[].source.expression is an ordinary value-returning X12 Mapper expression. It is parsed and executed by the same language engine as a mapping's primaryKeyExtractor, not by a scenario-only selector dialect.
  • The binding editor opens each fact source in a focused Mapper expression editor. It provides syntax-tree-aware completion, hover information, live diagnostics, and the existing searchable function reference using an explicit draft pin, a selected current runtime mapping, or the Mapper catalog's current default as an authoring preview. Apply independently resolves and freezes the exact authoritative tree.
  • POST /x12mapper/workspace/expression/diagnostics is the public stateless diagnostics operation for external authoring tools. It accepts one expression plus optional X12 release and transaction-set context; it never reads tenant data.
  • Draft diagnostics are fast authoring feedback. Scenario Validate and Apply remain authoritative for the exact tree, definition fact typing and cardinality, tenant artifacts, target authority, and bounded runtime evaluation.

Server semantic checks

  • The definition identity and content hash resolve to exactly one published or managed definition available to this tenant.
  • Actor and step IDs are unique and cover the referenced definition exactly.
  • Exactly one actor endpoint is the workspace and at least one is a current tenant partner.
  • Every runnable step must cross the tenant workspace boundary: exactly one endpoint is the workspace and the other is a bound partner. Apply rejects partner-to-partner and workspace-to-workspace steps because ModernEDI can neither operate nor authoritatively observe them.
  • Runtime mappings match the step direction, partner, transaction set, and resolved syntax tree. They constrain authoritative evidence from the ordinary transaction pipeline; they do not dispatch scenario documents.
  • Tenant-authored steps bind every declared fact exactly once. Mapper expressions are parsed and semantically validated against the resolved syntax tree before Apply, must be capable of an X12 segment or element read, and must produce concrete read provenance at runtime; value type, collection behavior, normalization, and sensitivity are taken from the definition.
  • Adapters are registered and cover the referenced definition and step. An adapter target may additionally pin a runtime mapping when the adapter executes the step but attached evidence must prove that exact mapping.
  • Apply records an immutable, fully resolved execution binding; an optional authoring syntaxTree never makes the runtime artifact ambiguous.

Runtime observation durability

X12 Mapper expressions retain their ordinary language semantics, while the typed fact values and evidence persisted for one observation are deliberately bounded. Collections may contain at most 1,000 scalar values, each string value may contain at most 4,096 UTF-8 bytes, each encoded typed value may contain at most 32,768 bytes, and the combined durable fact projection may contain at most 262,144 bytes. Fact provenance receipts, individual evidence documents, non-fact evidence count, and aggregate evidence JSON have their own documented limits. Every bound is checked before SQL persistence and returns a stable fact or observation capacity diagnostic.

  • Collection maximum: 1,000 scalar values.
  • UTF-8 text maximum per scalar: 4,096 bytes.
  • Encoded typed-value maximum: 32,768 bytes.
  • Combined durable fact projection maximum per observation: 262,144 bytes.
  • Fact provenance receipt maximum: 4,096 bytes.
  • Evidence document maximum: 8,192 bytes; at most 8 non-fact evidence documents per observation.
  • Combined durable evidence maximum per observation: 524,288 bytes.
  • Stable diagnostics: fact_value_limit_exceeded, transaction_observation_capacity_exceeded, transaction_fact_evidence_capacity_exceeded, and transaction_evidence_capacity_exceeded.

Example

{
  "$schema": "https://www.modernedi.com/docs/scenarios/schemas/scenario-binding-v1.schema.json",
  "apiVersion": "modernedi.com/scenario-binding-authoring/v1",
  "kind": "ScenarioBinding",
  "metadata": {
    "id": "retailOrderInvoice",
    "name": "Retail order to invoice"
  },
  "spec": {
    "definition": {
      "namespace": "acme",
      "key": "retail-order-invoice",
      "version": "1.0.0",
      "contentSha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    },
    "environment": "production",
    "actors": [
      {
        "actorId": "retailer",
        "endpoint": {
          "kind": "partner",
          "partnerId": 42
        }
      },
      {
        "actorId": "supplier",
        "endpoint": {
          "kind": "workspace"
        }
      }
    ],
    "steps": [
      {
        "stepId": "purchaseOrder",
        "target": {
          "kind": "runtime-mapping",
          "runtimeMappingId": 101
        },
        "factSources": [
          {
            "fact": "purchaseOrderNumber",
            "source": {
              "kind": "x12-mapper-expression",
              "expression": "ST->BEG(03)"
            }
          }
        ]
      },
      {
        "stepId": "invoice",
        "syntaxTree": {
          "x12Version": "004010",
          "transactionSet": "810"
        },
        "target": {
          "kind": "runtime-mapping",
          "runtimeMappingId": 102
        },
        "factSources": [
          {
            "fact": "purchaseOrderNumber",
            "source": {
              "kind": "x12-mapper-expression",
              "expression": "ST->BIG(04)"
            }
          },
          {
            "fact": "invoiceTotal",
            "source": {
              "kind": "x12-mapper-expression",
              "expression": "ST->TDS(01)"
            }
          }
        ]
      }
    ]
  }
}

Executable examples

Learn from the same definitions the scenario evaluator tests

These files preserve the business semantics of backend definitions that are compiled, checked against the tenant runtime-capacity budget, and evaluated through the scenario interpreter. They cover warehouse, retail, grocery, and ocean conversations without maintaining a second documentation-only model.

The published examples use the reserved modernedi.examples namespace. Change metadata.namespace to one owned by your tenant before validating or publishing a copy.

  1. grocery-order-to-invoiceX12 875, 856, 880; relationships follows; correlations equal; assertions subset, equal; closure fixed; matching correlate, position; quantifiers every:from, every:to, every:pairs; unmatched fail; pipeline exchange, extract; fact types string, set<string>, decimalOpen tested JSON
  2. grocery-product-activityX12 852; assertions exists, unique; closure fixed; pipeline exchange, extract; fact types date, list<string>, list<decimal>Open tested JSON
  3. ocean-booking-to-invoiceX12 300, 301, 303, 304, 315, 313, 312, 310; relationships supersedes, follows, cancels; correlations equal; assertions monotonic, greater_than_or_equal; closure expected_count, fixed, max_reached; matching previous, correlate, position; quantifiers every:to, every:from, exactly:pairs, any:pairs, every:pairs; unmatched record, fail; revision effects observed_at:reevaluate, observed_at:retain; pipeline exchange, extract, checkpoint; fact types string, decimal, timestamp; branches exactly_one, at_most_one; 2 checkpointsOpen tested JSON
  4. retail-order-lifecycleX12 850, 855, 860, 865, 856, 810; relationships follows, supersedes; correlations same_set, equal; assertions monotonic, unique, sum_equal; closure fixed, expected_count; matching correlate, previous, position; quantifiers every:to, exactly:pairs, every:from; unmatched record, fail; revision effects observed_at:retain, value:reevaluate; pipeline exchange, extract; fact types string, set<string>, decimal, timestampOpen tested JSON
  5. warehouse-outboundX12 940, 945; relationships follows; correlations equal; assertions unique, sum_equal; closure fixed, expected_count; matching correlate; quantifiers every:from, every:to, exactly:pairs; unmatched fail; pipeline exchange, extract; fact types string, decimal; 1 time windowOpen tested JSON

Signed-in Workspace API

One contract across editor and automation

This contract serves signed-in ModernEDI workspace users and browser/BFF automation acting with the same tenant session. It is intentionally separate from the public API-key Integration API. An Integration API key does not authenticate tenant routes. The one stateless Mapper expression-diagnostics operation is explicitly public and never reads or changes tenant data.

Authentication: The signed-in workspace session used by app.modernedi.com. Tenant product access and READ or OPERATE permission are enforced in addition to authentication. This is not an Integration API key.

Lifecycle resources return quoted SHA-256 ETags such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa". Runs return opaque revision ETags such as "scenario-run:v1:42:cnVuLTUwMDdkYmYzLWYxMTUtNGNhYy04NTMwLTE4OGZiNDMyNmM0NQ:1". Never construct or edit either form; return the latest value unchanged as the next operation's If-Match.

Download OpenAPI 3.1

  1. GET /tenant/scenarios/catalog

    Returns managed and tenant-published definitions with canonical hashes, topological order, syntax-tree readiness, and managed-adapter information. definition_only means the catalog has no single stored X12 release covering every step; syntax_tree_backed means at least one stored release covers every step but no exact ModernEDI-managed adapter is registered; executable_adapter means one exact registered managed adapter covers the definition identity, hash, and every step. These catalog labels do not decide whether a tenant-specific binding can run: Validate and Apply make that decision from the binding's exact partners, per-step syntax trees, mappings, observation targets, fact expressions, and adapters. The response is private and conditionally cacheable with its strong ETag.

    Permission: READ. Headers: none. Success: 200 ScenarioCatalogResponse.

    Stable error codes: none.

  2. POST /x12mapper/workspaces/{workspaceId}/scenario-authoring/validate

    Runs strict JSON parsing, JSON Schema validation, cross-file resolution, tenant-authority checks, graph checks, fact typing, and current runtime-capability checks without publishing or applying anything.

    Permission: OPERATE. Headers: none. Success: 200 ScenarioValidationResponse.

    Stable error codes: invalid_request.

    {
      "files": [
        {
          "id": "order-invoice.scenario.json",
          "fileType": "SCENARIO_DEFINITION",
          "source": "{\n  \"$schema\": \"https://www.modernedi.com/docs/scenarios/schemas/scenario-definition-v1.schema.json\",\n  \"apiVersion\": \"modernedi.com/scenario/v1\",\n  \"kind\": \"ScenarioDefinition\",\n  \"metadata\": {\n    \"namespace\": \"acme\",\n    \"key\": \"retail-order-invoice\",\n    \"version\": \"1.0.0\"\n  },\n  \"spec\": {\n    \"actors\": [\n      {\n        \"id\": \"retailer\"\n      },\n      {\n        \"id\": \"supplier\"\n      }\n    ],\n    \"steps\": [\n      {\n        \"id\": \"purchaseOrder\",\n        \"fromActor\": \"retailer\",\n        \"toActor\": \"supplier\",\n        \"transaction\": {\n          \"standard\": \"X12\",\n          \"transactionSet\": \"850\",\n          \"businessUsage\": \"purchase_order\"\n        },\n        \"occurrence\": {\n          \"min\": 1,\n          \"max\": 1,\n          \"closure\": {\n            \"kind\": \"fixed\"\n          }\n        },\n        \"assurance\": {\n          \"requirements\": [\n            {\n              \"type\": \"mapping_succeeded\"\n            }\n          ]\n        },\n        \"facts\": [\n          {\n            \"name\": \"purchaseOrderNumber\",\n            \"type\": \"string\",\n            \"cardinality\": \"one\",\n            \"normalization\": [\n              \"trim\"\n            ],\n            \"sensitivity\": \"business\"\n          }\n        ],\n        \"pipeline\": [\n          {\n            \"id\": \"exchange\",\n            \"kind\": \"exchange\"\n          },\n          {\n            \"id\": \"extract\",\n            \"kind\": \"extract\",\n            \"facts\": [\n              \"purchaseOrderNumber\"\n            ]\n          },\n          {\n            \"id\": \"assure\",\n            \"kind\": \"assure\"\n          }\n        ]\n      },\n      {\n        \"id\": \"invoice\",\n        \"fromActor\": \"supplier\",\n        \"toActor\": \"retailer\",\n        \"transaction\": {\n          \"standard\": \"X12\",\n          \"transactionSet\": \"810\",\n          \"businessUsage\": \"invoice\"\n        },\n        \"occurrence\": {\n          \"min\": 1,\n          \"max\": 1,\n          \"closure\": {\n            \"kind\": \"fixed\"\n          }\n        },\n        \"assurance\": {\n          \"requirements\": [\n            {\n              \"type\": \"transport_receipt_accepted\",\n              \"within\": \"PT4H\"\n            },\n            {\n              \"type\": \"functional_or_implementation_acknowledgment_accepted\"\n            }\n          ]\n        },\n        \"facts\": [\n          {\n            \"name\": \"purchaseOrderNumber\",\n            \"type\": \"string\",\n            \"cardinality\": \"one\",\n            \"normalization\": [\n              \"trim\"\n            ],\n            \"sensitivity\": \"business\"\n          },\n          {\n            \"name\": \"invoiceTotal\",\n            \"type\": \"decimal\",\n            \"cardinality\": \"optional\",\n            \"normalization\": [\n              \"decimal_canonical\"\n            ],\n            \"sensitivity\": \"financial\"\n          }\n        ],\n        \"pipeline\": [\n          {\n            \"id\": \"exchange\",\n            \"kind\": \"exchange\"\n          },\n          {\n            \"id\": \"extract\",\n            \"kind\": \"extract\",\n            \"facts\": [\n              \"purchaseOrderNumber\",\n              \"invoiceTotal\"\n            ]\n          },\n          {\n            \"id\": \"assure\",\n            \"kind\": \"assure\"\n          }\n        ]\n      }\n    ],\n    \"transitions\": [\n      {\n        \"id\": \"invoiceSettlesOrder\",\n        \"fromStep\": \"purchaseOrder\",\n        \"toStep\": \"invoice\",\n        \"relationship\": \"follows\",\n        \"within\": \"P30D\",\n        \"correlations\": [\n          {\n            \"id\": \"samePurchaseOrder\",\n            \"operator\": \"equal\",\n            \"left\": {\n              \"kind\": \"fact\",\n              \"stepId\": \"purchaseOrder\",\n              \"fact\": \"purchaseOrderNumber\",\n              \"projection\": \"value\"\n            },\n            \"right\": {\n              \"kind\": \"fact\",\n              \"stepId\": \"invoice\",\n              \"fact\": \"purchaseOrderNumber\",\n              \"projection\": \"value\"\n            }\n          }\n        ],\n        \"matching\": {\n          \"strategy\": \"correlate\",\n          \"quantifiers\": [\n            {\n              \"kind\": \"every\",\n              \"scope\": \"from\"\n            },\n            {\n              \"kind\": \"every\",\n              \"scope\": \"to\"\n            }\n          ],\n          \"unmatched\": \"fail\"\n        }\n      }\n    ],\n    \"assertions\": [\n      {\n        \"id\": \"invoiceTotalExists\",\n        \"operator\": \"exists\",\n        \"left\": {\n          \"kind\": \"fact\",\n          \"stepId\": \"invoice\",\n          \"fact\": \"invoiceTotal\",\n          \"projection\": \"value\"\n        }\n      }\n    ],\n    \"parameters\": [],\n    \"checkpoints\": [],\n    \"branches\": []\n  }\n}\n"
        },
        {
          "id": "order-invoice.binding.json",
          "fileType": "SCENARIO_BINDING",
          "source": "{\n  \"$schema\": \"https://www.modernedi.com/docs/scenarios/schemas/scenario-binding-v1.schema.json\",\n  \"apiVersion\": \"modernedi.com/scenario-binding-authoring/v1\",\n  \"kind\": \"ScenarioBinding\",\n  \"metadata\": {\n    \"id\": \"retailOrderInvoice\",\n    \"name\": \"Retail order to invoice\"\n  },\n  \"spec\": {\n    \"definition\": {\n      \"namespace\": \"acme\",\n      \"key\": \"retail-order-invoice\",\n      \"version\": \"1.0.0\",\n      \"contentSha256\": \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\n    },\n    \"environment\": \"production\",\n    \"actors\": [\n      {\n        \"actorId\": \"retailer\",\n        \"endpoint\": {\n          \"kind\": \"partner\",\n          \"partnerId\": 42\n        }\n      },\n      {\n        \"actorId\": \"supplier\",\n        \"endpoint\": {\n          \"kind\": \"workspace\"\n        }\n      }\n    ],\n    \"steps\": [\n      {\n        \"stepId\": \"purchaseOrder\",\n        \"target\": {\n          \"kind\": \"runtime-mapping\",\n          \"runtimeMappingId\": 101\n        },\n        \"factSources\": [\n          {\n            \"fact\": \"purchaseOrderNumber\",\n            \"source\": {\n              \"kind\": \"x12-mapper-expression\",\n              \"expression\": \"ST->BEG(03)\"\n            }\n          }\n        ]\n      },\n      {\n        \"stepId\": \"invoice\",\n        \"syntaxTree\": {\n          \"x12Version\": \"004010\",\n          \"transactionSet\": \"810\"\n        },\n        \"target\": {\n          \"kind\": \"runtime-mapping\",\n          \"runtimeMappingId\": 102\n        },\n        \"factSources\": [\n          {\n            \"fact\": \"purchaseOrderNumber\",\n            \"source\": {\n              \"kind\": \"x12-mapper-expression\",\n              \"expression\": \"ST->BIG(04)\"\n            }\n          },\n          {\n            \"fact\": \"invoiceTotal\",\n            \"source\": {\n              \"kind\": \"x12-mapper-expression\",\n              \"expression\": \"ST->TDS(01)\"\n            }\n          }\n        ]\n      }\n    ]\n  }\n}\n"
        }
      ]
    }
    
  3. GET /x12mapper/workspaces/{workspaceId}/scenario-authoring/definitions

    Returns definition identities and publication provenance for this tenant. The original source is intentionally represented by its canonical identity and hash.

    Permission: READ. Headers: none. Success: 200 PublishedDefinitionListResponse.

    Stable error codes: invalid_request.

  4. POST /x12mapper/workspaces/{workspaceId}/scenario-authoring/definitions/publish

    Publishes the exact definition source only when its canonical hash matches expectedContentSha256. Reusing an Idempotency-Key with the identical request replays the original result; reusing it for different content is a conflict.

    Permission: OPERATE. Headers: Idempotency-Key (required), If-None-Match (required). Success: 200 PublishedDefinitionMutationResponse; 201 PublishedDefinitionMutationResponse.

    Stable error codes: invalid_request, precondition_required, precondition_failed, definition_identity_conflict, scenario_revision_conflict, idempotency_key_conflict, content_hash_mismatch, scenario_authoring_quota_exceeded.

    {
      "file": {
        "id": "order-invoice.scenario.json",
        "fileType": "SCENARIO_DEFINITION",
        "source": "{\n  \"$schema\": \"https://www.modernedi.com/docs/scenarios/schemas/scenario-definition-v1.schema.json\",\n  \"apiVersion\": \"modernedi.com/scenario/v1\",\n  \"kind\": \"ScenarioDefinition\",\n  \"metadata\": {\n    \"namespace\": \"acme\",\n    \"key\": \"retail-order-invoice\",\n    \"version\": \"1.0.0\"\n  },\n  \"spec\": {\n    \"actors\": [\n      {\n        \"id\": \"retailer\"\n      },\n      {\n        \"id\": \"supplier\"\n      }\n    ],\n    \"steps\": [\n      {\n        \"id\": \"purchaseOrder\",\n        \"fromActor\": \"retailer\",\n        \"toActor\": \"supplier\",\n        \"transaction\": {\n          \"standard\": \"X12\",\n          \"transactionSet\": \"850\",\n          \"businessUsage\": \"purchase_order\"\n        },\n        \"occurrence\": {\n          \"min\": 1,\n          \"max\": 1,\n          \"closure\": {\n            \"kind\": \"fixed\"\n          }\n        },\n        \"assurance\": {\n          \"requirements\": [\n            {\n              \"type\": \"mapping_succeeded\"\n            }\n          ]\n        },\n        \"facts\": [\n          {\n            \"name\": \"purchaseOrderNumber\",\n            \"type\": \"string\",\n            \"cardinality\": \"one\",\n            \"normalization\": [\n              \"trim\"\n            ],\n            \"sensitivity\": \"business\"\n          }\n        ],\n        \"pipeline\": [\n          {\n            \"id\": \"exchange\",\n            \"kind\": \"exchange\"\n          },\n          {\n            \"id\": \"extract\",\n            \"kind\": \"extract\",\n            \"facts\": [\n              \"purchaseOrderNumber\"\n            ]\n          },\n          {\n            \"id\": \"assure\",\n            \"kind\": \"assure\"\n          }\n        ]\n      },\n      {\n        \"id\": \"invoice\",\n        \"fromActor\": \"supplier\",\n        \"toActor\": \"retailer\",\n        \"transaction\": {\n          \"standard\": \"X12\",\n          \"transactionSet\": \"810\",\n          \"businessUsage\": \"invoice\"\n        },\n        \"occurrence\": {\n          \"min\": 1,\n          \"max\": 1,\n          \"closure\": {\n            \"kind\": \"fixed\"\n          }\n        },\n        \"assurance\": {\n          \"requirements\": [\n            {\n              \"type\": \"transport_receipt_accepted\",\n              \"within\": \"PT4H\"\n            },\n            {\n              \"type\": \"functional_or_implementation_acknowledgment_accepted\"\n            }\n          ]\n        },\n        \"facts\": [\n          {\n            \"name\": \"purchaseOrderNumber\",\n            \"type\": \"string\",\n            \"cardinality\": \"one\",\n            \"normalization\": [\n              \"trim\"\n            ],\n            \"sensitivity\": \"business\"\n          },\n          {\n            \"name\": \"invoiceTotal\",\n            \"type\": \"decimal\",\n            \"cardinality\": \"optional\",\n            \"normalization\": [\n              \"decimal_canonical\"\n            ],\n            \"sensitivity\": \"financial\"\n          }\n        ],\n        \"pipeline\": [\n          {\n            \"id\": \"exchange\",\n            \"kind\": \"exchange\"\n          },\n          {\n            \"id\": \"extract\",\n            \"kind\": \"extract\",\n            \"facts\": [\n              \"purchaseOrderNumber\",\n              \"invoiceTotal\"\n            ]\n          },\n          {\n            \"id\": \"assure\",\n            \"kind\": \"assure\"\n          }\n        ]\n      }\n    ],\n    \"transitions\": [\n      {\n        \"id\": \"invoiceSettlesOrder\",\n        \"fromStep\": \"purchaseOrder\",\n        \"toStep\": \"invoice\",\n        \"relationship\": \"follows\",\n        \"within\": \"P30D\",\n        \"correlations\": [\n          {\n            \"id\": \"samePurchaseOrder\",\n            \"operator\": \"equal\",\n            \"left\": {\n              \"kind\": \"fact\",\n              \"stepId\": \"purchaseOrder\",\n              \"fact\": \"purchaseOrderNumber\",\n              \"projection\": \"value\"\n            },\n            \"right\": {\n              \"kind\": \"fact\",\n              \"stepId\": \"invoice\",\n              \"fact\": \"purchaseOrderNumber\",\n              \"projection\": \"value\"\n            }\n          }\n        ],\n        \"matching\": {\n          \"strategy\": \"correlate\",\n          \"quantifiers\": [\n            {\n              \"kind\": \"every\",\n              \"scope\": \"from\"\n            },\n            {\n              \"kind\": \"every\",\n              \"scope\": \"to\"\n            }\n          ],\n          \"unmatched\": \"fail\"\n        }\n      }\n    ],\n    \"assertions\": [\n      {\n        \"id\": \"invoiceTotalExists\",\n        \"operator\": \"exists\",\n        \"left\": {\n          \"kind\": \"fact\",\n          \"stepId\": \"invoice\",\n          \"fact\": \"invoiceTotal\",\n          \"projection\": \"value\"\n        }\n      }\n    ],\n    \"parameters\": [],\n    \"checkpoints\": [],\n    \"branches\": []\n  }\n}\n"
      },
      "expectedContentSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
    }
    
  5. GET /x12mapper/workspaces/{workspaceId}/scenario-authoring/bindings

    Returns every immutable applied binding revision visible to this tenant, including the exact definition, runtime activation, authority state, and ETag.

    Permission: READ. Headers: none. Success: 200 AppliedBindingListResponse.

    Stable error codes: invalid_request.

  6. GET /x12mapper/workspaces/{workspaceId}/scenario-authoring/bindings/{bindingId}

    Reads one exact binding identity and returns the strong ETag required to apply the next revision.

    Permission: READ. Headers: none. Success: 200 AppliedBindingResponse.

    Stable error codes: invalid_request, scenario_binding_not_found.

  7. PUT /x12mapper/workspaces/{workspaceId}/scenario-authoring/bindings/{bindingId}

    Resolves the authoring document against current tenant authority, freezes exact runtime artifacts, and creates a reproducible applied revision. Use If-None-Match: * to create revision zero; use the current strong If-Match ETag for later revisions.

    Permission: OPERATE. Headers: Idempotency-Key (required), If-Match, If-None-Match. Success: 200 AppliedBindingMutationResponse; 201 AppliedBindingMutationResponse.

    Stable error codes: invalid_request, precondition_required, precondition_failed, etag_mismatch, authority_etag_mismatch, scenario_revision_conflict, idempotency_key_conflict, content_hash_mismatch, scenario_authoring_quota_exceeded, scenario_binding_no_change, scenario_binding_not_executable.

    {
      "file": {
        "id": "order-invoice.binding.json",
        "fileType": "SCENARIO_BINDING",
        "source": "{\n  \"$schema\": \"https://www.modernedi.com/docs/scenarios/schemas/scenario-binding-v1.schema.json\",\n  \"apiVersion\": \"modernedi.com/scenario-binding-authoring/v1\",\n  \"kind\": \"ScenarioBinding\",\n  \"metadata\": {\n    \"id\": \"retailOrderInvoice\",\n    \"name\": \"Retail order to invoice\"\n  },\n  \"spec\": {\n    \"definition\": {\n      \"namespace\": \"acme\",\n      \"key\": \"retail-order-invoice\",\n      \"version\": \"1.0.0\",\n      \"contentSha256\": \"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"\n    },\n    \"environment\": \"production\",\n    \"actors\": [\n      {\n        \"actorId\": \"retailer\",\n        \"endpoint\": {\n          \"kind\": \"partner\",\n          \"partnerId\": 42\n        }\n      },\n      {\n        \"actorId\": \"supplier\",\n        \"endpoint\": {\n          \"kind\": \"workspace\"\n        }\n      }\n    ],\n    \"steps\": [\n      {\n        \"stepId\": \"purchaseOrder\",\n        \"target\": {\n          \"kind\": \"runtime-mapping\",\n          \"runtimeMappingId\": 101\n        },\n        \"factSources\": [\n          {\n            \"fact\": \"purchaseOrderNumber\",\n            \"source\": {\n              \"kind\": \"x12-mapper-expression\",\n              \"expression\": \"ST->BEG(03)\"\n            }\n          }\n        ]\n      },\n      {\n        \"stepId\": \"invoice\",\n        \"syntaxTree\": {\n          \"x12Version\": \"004010\",\n          \"transactionSet\": \"810\"\n        },\n        \"target\": {\n          \"kind\": \"runtime-mapping\",\n          \"runtimeMappingId\": 102\n        },\n        \"factSources\": [\n          {\n            \"fact\": \"purchaseOrderNumber\",\n            \"source\": {\n              \"kind\": \"x12-mapper-expression\",\n              \"expression\": \"ST->BIG(04)\"\n            }\n          },\n          {\n            \"fact\": \"invoiceTotal\",\n            \"source\": {\n              \"kind\": \"x12-mapper-expression\",\n              \"expression\": \"ST->TDS(01)\"\n            }\n          }\n        ]\n      }\n    ]\n  }\n}\n"
      },
      "expectedContentSha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
      "expectedAuthorityEtag": "\"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\""
    }
    
  8. POST /x12mapper/workspace/expression/diagnostics

    Returns tree-aware X12 Mapper diagnostics for exactly one value-returning expression. This is the fast editor/tooling check used while authoring a binding; scenario Validate remains authoritative for definition fact types, exact fact coverage, tenant artifacts, and Apply eligibility.

    Permission: Public and stateless; no tenant data. Headers: none. Success: 200 MapperExpressionDiagnosticsResponse.

    Stable error codes: none.

    {
      "source": "ST->BEG(03)",
      "x12Version": "004010",
      "transactionSetId": "850"
    }
    
  9. GET /tenant/scenario-runs

    Returns a bounded tenant-scoped summary of recent runs for discovery and navigation without exposing fact values or evidence payloads.

    Permission: READ. Headers: none. Success: 200 ScenarioRunCollection.

    Stable error codes: invalid_request, server_error.

  10. POST /tenant/scenario-runs

    Starts a durable run from exact definition and binding hashes. Optional typed parameters are checked against the definition before any operation is accepted. Registered adapter targets prepare their current runtime dependencies before the run is inserted; temporary preparation failures are retryable and return Retry-After.

    Permission: OPERATE. Headers: Idempotency-Key (required). Success: 201 ScenarioRunCommandResponse.

    Stable error codes: invalid_request, scenario_environment_not_executable, scenario_definition_changed, scenario_preparation_unavailable, scenario_binding_incomplete, scenario_target_executor_unavailable, idempotency_key_conflict, scenario_binding_changed, scenario_active_run_quota_exceeded, scenario_start_rate_limited, server_error.

    {
      "definition": {
        "namespace": "acme",
        "key": "retail-order-invoice",
        "version": "1.0.0",
        "contentSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
      },
      "environment": "production",
      "binding": {
        "id": "retailOrderInvoice",
        "revision": 0,
        "contentSha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
      },
      "parameters": {}
    }
    
  11. POST /tenant/implementation-verifications/test-partner-order-invoice/runs

    Starts the named ModernEDI-managed test-partner order/invoice flow without asking the caller to create or select a binding. This is a deliberate guided shortcut for the exact bundled 850 to 810 conversation; every resulting run still uses the same scenario evaluator as a custom run and can be inspected through the general run routes.

    Permission: OPERATE. Headers: Idempotency-Key (required). Success: 201 ScenarioRunCommandResponse.

    Stable error codes: invalid_request, scenario_definition_not_executable, scenario_environment_not_executable, scenario_preparation_unavailable, scenario_binding_incomplete, idempotency_key_conflict, scenario_binding_changed, scenario_active_run_quota_exceeded, scenario_start_rate_limited, server_error.

    {}
    
  12. POST /tenant/test-as2-partner/warehouse-outbound/setup

    Idempotently creates or refreshes the ModernEDI-owned test partner and managed X12 940 runtime mapping used by the warehouse outbound example. This prepares tenant-owned dependencies but does not publish a definition, apply a binding, or start a run. Validate and Apply an exact warehouse binding in Mapper, then start it through POST /tenant/scenario-runs.

    Permission: OPERATE. Headers: none. Success: 200 WarehouseOutboundSetupResponse.

    Stable error codes: none.

    {}
    
  13. GET /tenant/scenario-runs/{runId}

    Returns the current durable revision, evidence-bearing observations, checks, outcome, and strong ETag. Sensitive fact values are redacted from the public representation.

    Permission: READ. Headers: none. Success: 200 ScenarioRunViewResponse.

    Stable error codes: invalid_request, scenario_run_not_found, server_error.

  14. GET /tenant/scenario-runs/{runId}/timeline

    Returns a bounded, newest-first audit timeline without idempotency hashes, attempt tokens, transient credentials, or operation result payloads. The cursor is opaque and bound to both the tenant and run.

    Permission: READ. Headers: none. Success: 200 ScenarioRunTimelineResponse.

    Stable error codes: invalid_request, scenario_run_not_found, server_error.

  15. GET /tenant/scenario-runs/{runId}/evidence-report

    Creates the report once from terminal durable state and thereafter returns the exact persisted canonical JSON. It records the frozen authority and redacted evidence needed to substantiate the bounded implementation-verification claim; it is not editable scenario source, raw X12, or a compliance certificate. Stable failure codes are included, while detailed failure messages remain in the run timeline so the credential-free proof stays within its fixed export bound. If a retry creates another audit record for the same successful state change, the report counts that change once and keeps its earliest record; the timeline still shows every attempt.

    Permission: READ. Headers: none. Success: 200 ScenarioEvidenceReport.

    Stable error codes: invalid_request, scenario_run_not_found, scenario_run_not_terminal, scenario_evidence_report_too_large, server_error.

  16. POST /tenant/scenario-runs/{runId}/cancel

    Records an actor-attributed operator cancellation as an inconclusive terminal result while preserving all evidence already gathered. Cancellation is optimistic-concurrency controlled and idempotent, and it does not interrupt a command that still owns the run. If a command stops without saving a result and its temporary ownership period expires, ModernEDI records that attempt as failed and claims cancellation as one durable change. If the abandoned command may already have affected an external system, its failed timeline entry remains available for manual reconciliation. Each run can store at most 256 command records. The initial start and all later ordinary commands share 253 records; the remaining three are held for one retry record, cancellation, and a retry of cancellation. Result documents for ordinary commands share a 32 MiB budget, with additional space held for those same three reserved records.

    Permission: OPERATE. Headers: Idempotency-Key (required), If-Match (required). Success: 200 ScenarioRunCommandResponse.

    Stable error codes: invalid_request, precondition_required, etag_mismatch, scenario_run_not_found, scenario_run_terminal, idempotency_key_conflict, scenario_operation_in_progress, scenario_run_operation_limit_exceeded, scenario_run_result_bytes_limit_exceeded, scenario_operation_ownership_lost, server_error.

    {}
    
  17. POST /tenant/scenario-runs/{runId}/advance

    When runtime guidance selects a server-controlled step, this command dispatches or reconciles that step. Before external dispatch, ModernEDI prepares the current runtime dependencies and reconfirms the managed adapter target against the run's frozen binding authority. A temporary preparation outage is retryable and may return Retry-After; an incomplete or changed binding, or an unavailable target executor, rejects the command before dispatch. A failed adapter or preparation advance is durable: retry it with the current run ETag and a fresh Idempotency-Key. Reusing the failed operation's Idempotency-Key is a pure replay and never attempts preparation or dispatch again. Transient downstream rejections use scenario_adapter_dispatch_retryable; when the supplied x-api-key must be corrected they use scenario_adapter_dispatch_api_key_correction_required. The selected step and occurrence stay in structured run guidance instead of changing the stable error code. Observation-only and runtime-mapping steps still advance through the observation operation. For a waiting scenario run, the same empty-body command can safely ask the evaluator to recheck elapsed time: before every declared transition window and evidence deadline expires it returns HTTP 409 with scenario_observation_required, creates no operation, and leaves the run revision and ETag unchanged; once durable evidence reevaluation reaches a terminal outcome, it atomically persists a reevaluate_graph_clock operation and the completed run. The reevaluate_graph_clock value is the stable operation action recorded for this time-based reevaluation; it does not name another API. This time reevaluation never accepts x-api-key. The command rejects a stale ETag (optimistic concurrency), and replaying the same Idempotency-Key safely returns the original result (idempotency). x-api-key, when required by a selected adapter, is a transient Integration API credential used for that adapter operation only; it is not Workspace API authentication and is never persisted.

    Permission: OPERATE. Headers: Idempotency-Key (required), If-Match (required), x-api-key. Success: 200 ScenarioRunCommandResponse.

    Stable error codes: invalid_request, precondition_required, etag_mismatch, scenario_run_not_found, scenario_run_terminal, scenario_adapter_dispatch_response_invalid, scenario_adapter_dispatch_unavailable, scenario_adapter_not_ready, scenario_adapter_reply_ambiguous, scenario_adapter_transaction_ambiguous, scenario_binding_changed, scenario_binding_incomplete, scenario_observation_required, scenario_predecessor_fact_not_ready, scenario_predecessor_observation_required, scenario_preparation_unavailable, scenario_target_executor_unavailable, scenario_target_not_adapter, scenario_target_occurrence_unavailable, scenario_target_partner_authority_invalid, scenario_target_step_unavailable, scenario_adapter_dispatch_api_key_correction_required, scenario_adapter_dispatch_retryable, idempotency_key_conflict, scenario_operation_in_progress, scenario_run_operation_limit_exceeded, scenario_run_result_bytes_limit_exceeded, scenario_operation_ownership_lost, integration_api_key_required, integration_api_key_not_allowed, server_error.

    {}
    
  18. POST /tenant/scenario-runs/{runId}/observations

    Attaches one exact tenant-visible ModernEDI transaction to an attachable runtime-mapping or observation-only occurrence. The body identifies persisted transaction metadata; raw X12 is never accepted. The transaction must carry the exact partner-configuration fingerprint frozen into the applied binding; legacy or mismatched transactions are ineligible, while acknowledgments and receipts produced under a different configuration remain pending. Repeating the same slot and transaction with the current ETag and a new Idempotency-Key re-reads trusted transaction detail, refreshes pending mapping or acknowledgment evidence, and reevaluates the graph atomically. Reusing the original key is a pure replay and does not refresh evidence. Adapter-controlled steps reject client attachment. Mapper-derived facts use ordinary X12 Mapper semantics, with dynamic durability limits enforced before SQL persistence: collections contain at most 1000 scalar values; text scalars contain at most 4096 UTF-8 bytes; one canonical typed value contains at most 32768 bytes; and one observation's facts JSON contains at most 262144 bytes. A fact provenance receipt contains at most 4096 bytes. Each evidence document contains at most 8192 bytes, with at most 8 non-fact evidence documents and 524288 bytes of aggregate evidence JSON per observation. Capacity failures use fact_value_limit_exceeded, transaction_observation_capacity_exceeded, transaction_fact_evidence_capacity_exceeded, or transaction_evidence_capacity_exceeded. fact_evaluation_timeout and fact_evaluation_busy_or_limited return HTTP 409 with retryable=true and operationStatus=failed; reload the run if needed, then retry with its current ETag and a fresh Idempotency-Key to re-read trusted transaction evidence.

    Permission: OPERATE. Headers: Idempotency-Key (required), If-Match (required). Success: 200 ScenarioRunCommandResponse.

    Stable error codes: invalid_request, precondition_required, etag_mismatch, scenario_run_not_found, scenario_run_terminal, observation_step_not_bound, observation_target_controlled, observation_occurrence_out_of_range, scenario_observation_identity_conflict, scenario_checkpoint_conflict, scenario_observation_attempt_expired, transaction_not_found, transaction_messageid_mismatch, transaction_transactionkey_mismatch, transaction_transaction_set_mismatch, transaction_x12_syntax_tree_version_mismatch, transaction_partner_mismatch, transaction_partner_configuration_mismatch, transaction_mapping_mismatch, transaction_timestamp_in_future, transaction_timestamp_invalid, transaction_direction_invalid, transaction_direction_mismatch, transaction_acknowledgment_timestamp_missing, binding_fact_source_missing, binding_route_not_observable, transaction_fact_extraction_failed, fact_evaluation_timeout, fact_evaluation_busy_or_limited, transaction_observation_capacity_exceeded, transaction_fact_evidence_missing, transaction_fact_evidence_inconsistent, transaction_fact_evidence_capacity_exceeded, transaction_evidence_capacity_exceeded, fact_value_limit_exceeded, transaction_observation_unavailable, idempotency_key_conflict, scenario_operation_in_progress, scenario_run_operation_limit_exceeded, scenario_run_result_bytes_limit_exceeded, scenario_operation_ownership_lost, scenario_observation_unavailable, scenario_observation_failed, scenario_observation_completion_failed, scenario_run_revision_changed, scenario_binding_changed, server_error.

    {
      "stepId": "purchaseOrder",
      "occurrence": 1,
      "messageId": "msg-01K5QED4DP89F67V3MKRK9R5JM",
      "transactionKey": "tx-01K5QED4DP89F67V3MKRK9R5JM"
    }
    
  19. GET /tenant/scenario-context/transactions/{messageId}/{transactionKey}

    Projects existing run membership and currently attachable occurrences by matching the tenant-visible persisted transaction against the exact frozen partner, direction, X12 release, transaction set, and runtime mapping authority. This read never performs fact extraction or changes a run.

    Permission: READ. Headers: none. Success: 200 ScenarioTransactionContext.

    Stable error codes: invalid_request, scenario_transaction_not_found, server_error.

  20. GET /tenant/scenario-context/partners/{partnerId}

    Shows every active applied binding step that freezes this partner, including non-current activation state, plus currently eligible open occurrences for active scenario runs.

    Permission: READ. Headers: none. Success: 200 ScenarioPartnerContext.

    Stable error codes: invalid_request, server_error.

  21. GET /tenant/scenario-context/mappings/{mappingId}

    Shows every active applied binding step that freezes this exact runtime mapping, including non-current activation state, plus currently eligible open occurrences for active scenario runs.

    Permission: READ. Headers: none. Success: 200 ScenarioMappingContext.

    Stable error codes: invalid_request, server_error.

Fast locally, authoritative on the server.

JSON Schema catches document shape, closed fields, constants, formats, and operator operands. Server validation additionally resolves references, tenant-owned artifacts, conversation semantics, fact types, and whether the current scenario runtime can execute the definition. Publish and Apply remain fail-closed.