Skip to content

The tenor CLI provides 26 subcommands for elaboration, evaluation, analysis, code generation, serving, source wiring, migration, template management, cryptographic signing, testing, and interactive tooling.

Global Flags

Every subcommand accepts these flags:

FlagDescription
--output text|jsonOutput format (default: text)
--quietSuppress non-essential output

Environment Variables

VariableUsed ByDescription
ANTHROPIC_API_KEYtenor connect, tenor ambiguity, LlmPolicyAnthropic API key for Claude
TENOR_REGISTRY_TOKENtenor publishAuth token for template registry
TENOR_REGISTRY_URLtenor publish, tenor deployRegistry endpoint override
TENOR_PLATFORM_TOKENtenor deployAuth token for hosted platform
RUST_LOGAll cratesLogging level (tracing-subscriber)

Core Commands

tenor check

Run the full static analysis suite (S1-S8) against one or more .tenor files.

tenor check [files...]

Flags:

FlagDescription
--analysis s1,s4,s6Run only the specified analyses (comma-separated)
--authorityPrint the authority topology (S4)
--verbosePrint detailed analysis results per property
--jsonOutput analysis report as JSON

Static Analysis Properties:

PropertyDescription
S1Complete state space enumeration
S2Reachable/dead state detection
S3aStructural admissibility per state
S4Authority topology derivation
S5Verdict and outcome space
S6Flow path enumeration
S7Evaluation complexity bounds
S8Verdict uniqueness (pre-verified by elaboration Pass 5)

Example usage:

bash
# Run all static analyses
tenor check contract.tenor

# Run only authority topology and flow path enumeration
tenor check contract.tenor --analysis s4,s6

# Check multiple files with verbose output
tenor check trade.tenor inspection.tenor --verbose

# Authority topology as JSON
tenor check contract.tenor --authority --json

Example output:

tenor check escrow.tenor

  S1 State Space
     EscrowAccount:  4 states  (held, released, refunded, disputed)
     DeliveryRecord: 3 states  (pending, confirmed, failed)

  S2 Reachability
     EscrowAccount:  4/4 reachable, 0 dead
     DeliveryRecord: 3/3 reachable, 0 dead

  S3a Admissibility
     EscrowAccount.held:
       escrow_agent  → release_escrow, refund_escrow
       buyer, seller → flag_dispute
     EscrowAccount.disputed:
       compliance_officer → release_escrow_with_compliance
       escrow_agent       → refund_escrow

  S4 Authority Topology
     buyer             → {flag_dispute}
     seller            → {confirm_delivery, flag_dispute}
     escrow_agent      → {release_escrow, refund_escrow, record_delivery_failure, revert_delivery_confirmation}
     compliance_officer → {release_escrow_with_compliance}

  S5 Verdict Space
     6 verdict types: line_items_validated, delivery_confirmed, delivery_failed,
                      within_threshold, refund_requested, release_approved,
                      compliance_review_required, refund_approved

  S6 Flow Paths
     standard_release: 5 paths, max depth 4, all terminal
     refund_flow:      1 path,  max depth 1, all terminal

  S7 Complexity
     Max predicate depth: 3
     Max quantifier nesting: 1
     Max flow depth: 4

  S8 Verdict Uniqueness
     All verdict types produced by exactly one rule. ✓

  ✓ All 8 analyses passed.

tenor elaborate

Elaborate .tenor source files into the canonical JSON interchange format through the six-pass pipeline.

tenor elaborate [files...]

Flags:

FlagDescription
--output PATHWrite interchange JSON to a file instead of stdout
--prettyPretty-print the JSON output
--manifestGenerate a TenorManifest wrapping the interchange bundle with etag

Example usage:

bash
# Elaborate and write to file
tenor elaborate contract.tenor > contract.json

# Pretty-printed output
tenor elaborate contract.tenor --pretty

# Generate manifest with etag for deployment
tenor elaborate contract.tenor --manifest > manifest.json

# Multiple source files
tenor elaborate trade.tenor types/common.tenor

Example JSON output (abbreviated):

json
{
  "constructs": [
    {
      "id": "buyer",
      "kind": "Persona",
      "provenance": { "file": "escrow.tenor", "line": 1 },
      "tenor": "1.0"
    },
    {
      "id": "escrow_amount",
      "kind": "Fact",
      "source": {
        "path": "accounts.{id}.balance",
        "source_id": "escrow_service"
      },
      "tenor": "1.0",
      "type": { "base": "Money", "currency": "USD" }
    }
  ],
  "id": "escrow",
  "kind": "Bundle",
  "tenor": "1.0",
  "tenor_version": "1.1.0"
}

tenor evaluate

Evaluate rules against a fact set and produce verdicts. Optionally execute a specific flow as a given persona.

tenor evaluate [files...] --facts facts.json

Flags:

FlagDescription
--facts PATHPath to JSON file containing fact values (required)
--flow FLOW_IDExecute a specific flow
--persona PERSONAPersona executing the flow (required with --flow)
--entity-states PATHJSON file with initial entity state map
--instance-bindings PATHJSON file with entity-to-instance bindings

Example usage:

bash
# Evaluate rules and see verdicts
tenor evaluate contract.tenor --facts facts.json

# Execute a specific flow as a persona
tenor evaluate contract.tenor --facts facts.json \
  --flow standard_release --persona escrow_agent

# With entity states and instance bindings
tenor evaluate contract.tenor --facts facts.json \
  --flow standard_release --persona escrow_agent \
  --entity-states states.json \
  --instance-bindings bindings.json

Example verdict output:

tenor evaluate escrow.tenor --facts facts.json

  FactSet assembled: 5 facts

  Stratum 0:
    ✓ line_items_validated    (Bool = true)
    ✓ delivery_confirmed      (Bool = true)
    ✗ delivery_failed         (not produced)
    ✓ within_threshold        (Bool = true)
    ✗ refund_requested        (not produced)

  Stratum 1:
    ✓ release_approved        (Text = "auto")
    ✗ compliance_review_required (not produced)
    ✗ refund_approved         (not produced)

  ResolvedVerdictSet: 4 verdicts

tenor simulate

Execute a flow simulation with full provenance tracking. Produces an execution trace showing every step, entity state change, and decision point.

tenor simulate [files...] --flow FLOW_ID --persona PERSONA --facts facts.json

Flags:

FlagDescription
--facts PATHPath to JSON file containing fact values (required)
--flow FLOW_IDFlow to simulate (required)
--persona PERSONAPersona initiating the flow (required)
--entity-states PATHJSON file with initial entity state map
--instance-bindings PATHJSON file with entity-to-instance bindings

Example output:

tenor simulate escrow.tenor --flow standard_release \
  --persona escrow_agent --facts facts.json

  Flow: standard_release
  Persona: escrow_agent
  Snapshot: frozen at initiation (4 verdicts)

  Step 1: step_confirm (OperationStep)
    Operation: confirm_delivery
    Persona:   seller ✓
    Precondition: ∀ item ∈ line_items . item.valid = true → true ✓
    Effect: DeliveryRecord: pending → confirmed ✓
    Outcome: confirmed → step_check_threshold

  Step 2: step_check_threshold (BranchStep)
    Condition: verdict_present(within_threshold) → true
    Route: → step_auto_release

  Step 3: step_auto_release (OperationStep)
    Operation: release_escrow
    Persona:   escrow_agent ✓
    Precondition: verdict_present(release_approved) → true ✓
    Effect: EscrowAccount: held → released ✓
    Outcome: released → Terminal(success)

  Result: success
  Steps executed: 3
  Entity changes:
    DeliveryRecord: pending → confirmed
    EscrowAccount:  held → released

  Provenance chain:
    release_approved ← line_items_validated + delivery_confirmed + within_threshold
    within_threshold ← escrow_amount (8500.00 USD) ≤ compliance_threshold (10000.00 USD)
    delivery_confirmed ← delivery_status = "confirmed"
    line_items_validated ← ∀ item ∈ line_items . item.valid = true

tenor actions

Compute the action space for a given persona. Shows which flows the persona can initiate and which are blocked, with reasons.

tenor actions [files...] --persona PERSONA --facts facts.json

Flags:

FlagDescription
--facts PATHPath to JSON file containing fact values (required)
--persona PERSONAPersona to compute actions for (required)
--entity-states PATHJSON file with entity state map
--jsonOutput as structured JSON

Example usage:

bash
# Text output
tenor actions escrow.tenor --persona escrow_agent --facts facts.json

# JSON for agent consumption
tenor actions escrow.tenor --persona escrow_agent --facts facts.json --json

Example text output:

tenor actions escrow.tenor --persona escrow_agent --facts facts.json

  Persona: escrow_agent
  Verdicts: 4 active

  Available Actions:
    ✓ standard_release
      Instances: {EscrowAccount: "esc-001", DeliveryRecord: "del-001"}
      Enabling verdicts: release_approved, delivery_confirmed
    ✓ refund_flow
      Blocked — verdict refund_approved not present

  Blocked Actions:
    ✗ refund_flow
      Reason: precondition not met — verdict_present(refund_approved) = false

Example JSON output:

json
{
  "persona": "escrow_agent",
  "current_verdicts": ["line_items_validated", "delivery_confirmed", "within_threshold", "release_approved"],
  "actions": [
    {
      "flow_id": "standard_release",
      "instance_bindings": {
        "EscrowAccount": ["esc-001", "esc-002"],
        "DeliveryRecord": ["del-001"]
      },
      "verdicts_enabling": ["release_approved"],
      "personas": ["escrow_agent"]
    }
  ],
  "blocked_actions": [
    {
      "flow_id": "refund_flow",
      "reason": "precondition_not_met",
      "details": "verdict_present(refund_approved) = false"
    }
  ]
}

tenor explain

Generate a natural-language explanation of a contract. Useful for onboarding, documentation, and agent orientation.

tenor explain [files...]

Flags:

FlagDescription
--verboseInclude detailed analysis of all constructs
--format text|markdownOutput format (default: text)

Example usage:

bash
# Brief explanation
tenor explain escrow.tenor

# Detailed markdown for documentation
tenor explain escrow.tenor --verbose --format markdown

Example output:

tenor explain escrow.tenor

  Escrow Release Contract

  This contract manages escrow transactions between buyers and sellers.
  Payment is held in escrow and released upon delivery confirmation,
  or refunded if delivery fails.

  Participants:
    buyer              — Can flag disputes
    seller             — Confirms delivery
    escrow_agent       — Releases/refunds escrow, records delivery failure
    compliance_officer — Approves high-value releases

  Entities:
    EscrowAccount   — States: held → released, refunded, or disputed
    DeliveryRecord  — States: pending → confirmed or failed

  Key Rules:
    - Escrow release is auto-approved when amount ≤ compliance threshold
    - High-value releases require compliance officer approval
    - Refunds require delivery failure AND buyer request

  Flows:
    standard_release — Confirm delivery → threshold check → release (auto or compliance)
    refund_flow      — Direct refund when conditions met

  External Systems:
    escrow_service     (HTTP) — Account balances
    delivery_service   (HTTP) — Shipment status
    order_service      (HTTP) — Line items
    compliance_service (Database) — Threshold configuration

Code Generation

tenor generate typescript

Generate TypeScript types, Zod validation schemas, and an API client from a contract's interchange JSON.

tenor generate typescript INPUT

Flags:

FlagDescription
--out PATHOutput directory (default: ./generated/)
--sdk-import MODULESDK import path (default: @tenor/sdk)

Generated files:

FileContents
types.tsTypeScript interfaces for all Facts, Entities, Verdicts, Operations
schemas.tsZod schemas for runtime validation of all types
client.tsAPI client class with typed methods for evaluate, execute, simulate
index.tsRe-exports from all generated modules

Example usage:

bash
# Generate with defaults
tenor generate typescript contract.json

# Custom output and SDK import path
tenor generate typescript contract.json \
  --out ./src/generated \
  --sdk-import @tenor/sdk

Example generated types:

typescript
// generated/types.ts
export interface EscrowFacts {
  escrow_amount: Money;
  delivery_status: "pending" | "confirmed" | "failed";
  line_items: LineItemRecord[];
  compliance_threshold: Money;
  buyer_requested_refund: boolean;
}

export type EscrowAccountState = "held" | "released" | "refunded" | "disputed";
export type DeliveryRecordState = "pending" | "confirmed" | "failed";

export interface EscrowVerdicts {
  line_items_validated?: boolean;
  delivery_confirmed?: boolean;
  within_threshold?: boolean;
  release_approved?: string;
  compliance_review_required?: boolean;
  refund_approved?: boolean;
}

tenor ui

Generate a complete React application from a contract. The generated app includes entity state viewers, fact input forms, flow execution panels, verdict displays, and an action space dashboard.

tenor ui CONTRACT

Flags:

FlagDescription
--out PATHOutput directory (default: ./ui/)
--api-url URLBackend API URL (default: http://localhost:8080)
--contract-id IDContract identifier for multi-contract servers
--theme PATHCustom theme configuration file
--title TEXTApplication title

Generated structure:

ui/
├── src/
│   ├── components/     Entity viewers, fact forms, verdict displays
│   ├── pages/          Dashboard, flow execution, entity detail
│   ├── hooks/          React hooks for evaluation and state
│   ├── api/            API client targeting tenor serve endpoints
│   └── types/          TypeScript types from contract
├── package.json
├── tsconfig.json
├── vite.config.ts
└── tailwind.config.ts

Example usage:

bash
# Generate and run
tenor ui escrow.tenor --out ./my-app --api-url http://localhost:8080
cd my-app && npm install && npm run dev

Server & Interactive

tenor serve

Start an HTTP API server that exposes contract elaboration, evaluation, simulation, and action space computation over REST endpoints.

tenor serve [contracts...]

Flags:

FlagDescription
--port PORTListen port (default: 8080)
--tls-cert PATHTLS certificate file (enables HTTPS)
--tls-key PATHTLS private key file
--hostedEnable hosted platform mode (multi-tenant)
--adapter-config PATHTOML adapter configuration file

Endpoints:

MethodPathDescription
GET/.well-known/tenorContract manifest with etag (E10)
POST/elaborateElaborate DSL source to interchange JSON
POST/evaluateEvaluate rules against facts
POST/evaluate/flowExecute a flow
POST/simulateDry-run evaluation (no side effects)
POST/actionsCompute action space for a persona
GET/healthHealth check

Example usage:

bash
# Start with a single contract
tenor serve escrow.tenor

# Custom port with TLS
tenor serve escrow.tenor --port 3000 \
  --tls-cert cert.pem --tls-key key.pem

# Multiple contracts with adapter config
tenor serve trade.tenor inspection.tenor settlement.tenor \
  --adapter-config adapters.toml

Adapter configuration (TOML):

toml
[global]
timeout_ms = "30000"

[sources.order_service]
base_url = "https://api.example.com/v2"
auth_header = "Bearer <token>"

[sources.compliance_db]
connection_string = "postgresql://user:pass@host/db"

tenor agent

Start an interactive agent shell with policy-driven action selection. The agent observes the contract state, evaluates available actions, selects an action using the configured policy, and executes it.

tenor agent FILE

The agent shell supports multiple action-selection policies:

PolicyDescription
AlwaysApproveApprove every proposed action
NeverApproveReject every proposed action (observation only)
FirstAvailablePolicySelect the first available flow in declaration order
PriorityPolicySelect based on a priority ordering of flow IDs
RandomPolicySelect uniformly at random
HumanInTheLoopPolicyInteractive approval via stdin
LlmPolicyAI-powered selection via Claude API
CompositePolicyThree-stage pipeline: proposer, predicate, approver

Example session:

$ tenor agent escrow.tenor

tenor agent v1.0 — interactive contract shell
Contract: escrow (4 personas, 7 operations, 2 flows)
Policy: HumanInTheLoopPolicy

> status
  EscrowAccount:  held
  DeliveryRecord: pending
  Verdicts: line_items_validated, delivery_confirmed, within_threshold, release_approved

> actions escrow_agent
  Available:
    1. standard_release  (EscrowAccount: held, DeliveryRecord: pending)
  Blocked:
    - refund_flow       (verdict refund_approved not present)

> execute standard_release --persona escrow_agent
  Step 1: confirm_delivery (seller) → confirmed
  Step 2: check_threshold → true → step_auto_release
  Step 3: release_escrow (escrow_agent) → released
  Result: success

  Entity state:
    EscrowAccount:  released
    DeliveryRecord: confirmed

> quit

tenor builder dev / tenor builder build

Start the visual contract Builder development server or produce a production build.

tenor builder dev
tenor builder build

Flags:

FlagDescription
--contract PATHPre-load a contract file on startup
--port PORTDev server port (default: 5173)
--openOpen browser automatically

Example usage:

bash
# Start Builder in dev mode
tenor builder dev

# Pre-load a contract and open browser
tenor builder dev --contract escrow.tenor --open

# Custom port
tenor builder dev --port 3000

# Production build
tenor builder build

The Builder provides visual editors for entities (drag-and-drop state machines), flows (DAG editor with outcome routing), predicates (structured expression builder), rules, operations, facts, personas, sources, and systems. It includes a simulation mode powered by the WASM evaluator running in the browser.


Source Wiring

tenor connect

Introspect a contract's Source declarations and generate adapter scaffolding. Supports LLM-powered mapping (default), heuristic pattern matching, batch review, and application of reviewed mappings.

tenor connect CONTRACT

Modes:

ModeFlagDescription
Bare(none)Introspect sources, show summary
Environment--environment SPECMatch against OpenAPI, GraphQL SDL, or SQL schema
Heuristic--heuristicPattern-matching mode (no LLM required)
Batch--batch FILEGenerate review file for human approval
Apply--apply FILEApply reviewed mappings, generate adapter code

Additional flags:

FlagDescription
--verboseShow detailed matching rationale
--out PATHOutput directory for generated adapters

Example usage:

bash
# Introspect sources
tenor connect contract.tenor

# Match against an OpenAPI spec
tenor connect contract.tenor --environment api-spec.yaml

# Heuristic mode (no LLM, no API key needed)
tenor connect contract.tenor --heuristic --verbose

# Generate review file for human approval
tenor connect contract.tenor --batch review.json

# Apply reviewed mappings and generate adapter code
tenor connect contract.tenor --apply reviewed.json --out ./adapters

Example output (bare mode):

tenor connect escrow.tenor

  Source declarations:
    escrow_service     (http)     — https://api.escrow.com/v1
    delivery_service   (http)     — https://delivery.internal/api
    order_service      (http)     — https://api.orders.com/v2
    compliance_service (database) — postgres

  Fact → Source mappings:
    escrow_amount          → escrow_service   { path: "accounts.{id}.balance" }
    delivery_status        → delivery_service  { path: "shipments.{id}.status" }
    line_items             → order_service     { path: "orders.{id}.line_items" }
    compliance_threshold   → compliance_service { path: "compliance_thresholds.release_amount" }
    buyer_requested_refund → (freetext: "buyer_portal.refund_requested")

  Run with --environment to match against your API spec.

Migration

tenor diff

Compute a structural diff between two interchange bundles. Classifies each change as BREAKING, NON_BREAKING, REQUIRES_ANALYSIS, or INFRASTRUCTURE.

tenor diff V1 V2

Flags:

FlagDescription
--breakingShow only breaking and requires-analysis changes
--jsonOutput as structured DiffEntry JSON
--migrationGenerate a Tenor migration contract from the diff

Example usage:

bash
# Full structural diff
tenor diff v1.json v2.json

# Show only breaking changes
tenor diff v1.json v2.json --breaking

# Machine-readable diff
tenor diff v1.json v2.json --json

Example output:

tenor diff v1.json v2.json

  Entity: EscrowAccount
    states:      + suspended            NON_BREAKING (additive state)
    transitions: + (held, suspended)    NON_BREAKING (additive transition)
    transitions: + (suspended, released) NON_BREAKING (additive transition)

  Operation: release_escrow
    precondition: changed               REQUIRES_ANALYSIS
      v1: verdict_present(release_approved)
      v2: verdict_present(release_approved) and verdict_present(kyc_cleared)

  Fact: kyc_status
    (added)                             NON_BREAKING (new construct)

  Rule: kyc_check
    (added)                             REQUIRES_ANALYSIS (new rule at stratum 0)

  Source: kyc_service
    (added)                             NON_BREAKING (new source)

  Summary: 2 REQUIRES_ANALYSIS, 4 NON_BREAKING
  Migration policy required: YES (treat REQUIRES_ANALYSIS as BREAKING per M6)

tenor migrate

Full migration analysis between two contract versions. Includes diff, breaking change classification, entity state migration plan, and in-flight flow compatibility assessment.

tenor migrate V1 V2

Flags:

FlagDescription
--yesSkip confirmation prompt
--policy blue-green|force-migrate|abortDeclare in-flight flow migration policy

Example usage:

bash
# Interactive migration analysis
tenor migrate v1.json v2.json

# Non-interactive with policy declaration
tenor migrate v1.json v2.json --yes --policy blue-green

Example output:

tenor migrate v1.json v2.json

  Structural diff: 6 changes (2 REQUIRES_ANALYSIS, 4 NON_BREAKING)

  Entity state migration:
    EscrowAccount: no instances in removed states ✓
    DeliveryRecord: unchanged ✓

  In-flight flow analysis:
    standard_release:
      Position step_confirm: COMPATIBLE (all forward paths exist in v2)
      Position step_auto_release: INCOMPATIBLE
        Layer 3: precondition requires verdict_present(kyc_cleared),
                 not in frozen snapshot

  Recommendation: Blue-Green deployment
    - New flows use v2
    - In-flight flows at step_auto_release complete under v1
    - In-flight flows at step_confirm can be force-migrated

  Proceed? [y/N]

Template Management

tenor pack

Package the current directory as a reusable contract template. Reads tenor-template.toml for metadata.

tenor pack

Creates a .tar.gz archive containing the contract files, interchange JSON, and template metadata.

Template metadata (tenor-template.toml):

toml
[template]
name = "escrow-release"
version = "1.0.0"
description = "Standard escrow release with compliance review"
category = "finance"
tags = ["escrow", "compliance", "payment"]

[author]
organization = "riverline-labs"

tenor publish

Publish a packaged template to the Tenor template registry. Requires TENOR_REGISTRY_TOKEN.

tenor publish

Templates go through a review workflow before becoming publicly available.


Search the template registry by name, description, category, or tags.

tenor search QUERY

Flags:

FlagDescription
--category CATEGORYFilter by category (e.g., finance, supply-chain)

Example usage:

bash
# Search by keyword
tenor search "escrow"

# Filter by category
tenor search "compliance" --category finance

Example output:

tenor search "escrow"

  @riverline/escrow-standard   v1.0.0   finance
    Standard escrow release with compliance review and multi-persona authority.

  @riverline/escrow-milestone  v0.9.0   finance
    Milestone-based escrow with phased release and inspection gates.

  2 templates found

tenor install

Install a template from the registry to the local directory.

tenor install TEMPLATE

Example usage:

bash
tenor install @riverline/escrow-standard

tenor deploy

Deploy a template directly to the hosted platform for a given organization.

tenor deploy TEMPLATE --org ORG_ID

Requires TENOR_PLATFORM_TOKEN. Creates a new contract deployment on the hosted platform from the template, provisioning all necessary infrastructure.

Example usage:

bash
tenor deploy @riverline/escrow-standard --org my-org

Example output:

tenor deploy @riverline/escrow-standard --org my-org

  Deploying escrow-standard v1.0.0 to organization my-org...

  Contract ID:   ct_a1b2c3d4
  API endpoint:  https://my-org.tenor.run
  Manifest:      https://my-org.tenor.run/.well-known/tenor
  Etag:          3f7a9b2c...

  Personas mapped:
    buyer              → API key required
    seller             → API key required
    escrow_agent       → API key required
    compliance_officer → API key required

  ✓ Deployed successfully.

Cryptography

tenor keygen

Generate an Ed25519 signing keypair for contract and WASM bundle signing.

tenor keygen

Flags:

FlagDescription
--prefix NAMECustom filename prefix (default: tenor-key)

Example usage:

bash
# Default keypair
tenor keygen
# Creates: tenor-key.secret, tenor-key.public

# Custom prefix
tenor keygen --prefix my-signer
# Creates: my-signer.secret, my-signer.public

Output:

tenor keygen

  Generated Ed25519 keypair:
    Secret key: tenor-key.secret
    Public key: tenor-key.public

  Keep tenor-key.secret safe. Do not commit it to version control.

tenor sign

Sign an interchange bundle with an Ed25519 secret key. Produces a signed bundle with an embedded attestation.

tenor sign BUNDLE --key SECRET_KEY

The attestation includes: signer public key, signature (base64), algorithm (ed25519), signed-at timestamp, and signed etag (SHA-256 of bundle content).

Example usage:

bash
tenor sign contract.json --key tenor-key.secret
# Creates: contract.signed.json

Example output:

tenor sign contract.json --key tenor-key.secret

  Bundle etag:  3f7a9b2c4d5e6f...
  Signer:       tenor-key.public (ed25519)
  Signed at:    2026-03-01T12:00:00Z
  Output:       contract.signed.json

  ✓ Bundle signed.

tenor verify

Verify the signature on a signed interchange bundle.

tenor verify BUNDLE

Example usage:

bash
tenor verify contract.signed.json

Example output:

tenor verify contract.signed.json

  Algorithm:   ed25519
  Signer:      Hx7Kp2... (public key)
  Signed at:   2026-03-01T12:00:00Z
  Signed etag: 3f7a9b2c4d5e6f...
  Current etag: 3f7a9b2c4d5e6f...

  ✓ Signature valid. Bundle has not been modified since signing.

tenor sign-wasm

Sign a WASM evaluator binary, binding it to a specific contract bundle via etag. Prevents substitution attacks where a signed WASM module is used with a different contract.

tenor sign-wasm WASM --key SECRET_KEY --bundle-etag ETAG

Example usage:

bash
tenor sign-wasm evaluator.wasm --key tenor-key.secret --bundle-etag "3f7a9b2c..."
# Creates: evaluator.wasm.sig

tenor verify-wasm

Verify a WASM evaluator binary's signature against a public key.

tenor verify-wasm WASM --sig SIG --pubkey PUBLIC_KEY

Example usage:

bash
tenor verify-wasm evaluator.wasm --sig evaluator.wasm.sig --pubkey tenor-key.public

Example output:

tenor verify-wasm evaluator.wasm --sig evaluator.wasm.sig --pubkey tenor-key.public

  WASM hash:    a9f3c7...
  Bundle etag:  3f7a9b2c4d5e6f...
  Signer:       Hx7Kp2... (public key)

  ✓ WASM signature valid. Binary is bound to bundle etag 3f7a9b2c...

Testing

tenor test conformance

Run the elaborator conformance test suite. The suite validates all six elaboration passes against 127 test fixtures covering positive, negative, numeric precision, type promotion, shorthand expansion, cross-file, parallel entity conflict, and verdict uniqueness cases.

tenor test conformance

Output uses TAP v14 format.

Example output:

tenor test conformance

  TAP version 14
  1..127
  ok 1 - positive/basic_fact.tenor
  ok 2 - positive/entity_transitions.tenor
  ok 3 - positive/rule_stratification.tenor
  ...
  ok 41 - positive/integration_escrow.tenor
  ok 42 - negative/pass0_unterminated_comment.tenor
  ok 43 - negative/pass1_import_cycle.tenor
  ...
  ok 90 - negative/pass5_duplicate_outcome.tenor
  ok 91 - numeric/decimal_precision.tenor
  ...
  ok 100 - numeric/money_comparison.tenor
  ok 101 - promotion/int_decimal_cross.tenor
  ok 102 - promotion/mul_type_promotion.tenor
  ok 103 - shorthand/simple_rule.tenor
  ok 104 - shorthand/operation_single_effect.tenor
  ok 105 - cross_file/import_types.tenor
  ok 106 - cross_file/import_facts.tenor
  ok 107 - parallel/overlapping_effects.tenor
  ok 108 - parallel/non_overlapping.tenor
  ...
  ok 127 - manifest/basic_manifest.tenor

  # 127 tests, 127 passed, 0 failed

tenor ambiguity

Run AI-powered ambiguity testing against a contract. Uses Claude to identify potential ambiguities between the contract's behavior and the formal specification, then generates test cases targeting those ambiguities.

tenor ambiguity CONFORMANCE_DIR --spec SPEC_PATH

Requires ANTHROPIC_API_KEY.

Example usage:

bash
tenor ambiguity conformance/ --spec docs/tenor-language-specification.md

Example output:

tenor ambiguity conformance/ --spec docs/tenor-language-specification.md

  Analyzing conformance suite against specification...

  Ambiguity 1: §7.3 stratum equality prohibition
    The spec says "equality is not permitted" for same-stratum references.
    Existing tests cover cross-stratum references but not same-stratum
    with zero dependencies between rules.
    Generated: ambiguity_stratum_same_no_dep.tenor

  Ambiguity 2: §4.2 Duration cross-unit promotion
    The spec defines Duration(days) + Duration(hours) → Duration(hours).
    No conformance test exercises Duration arithmetic with mixed units.
    Generated: ambiguity_duration_cross_unit.tenor

  Ambiguity 3: §10.6 Entity state in predicate
    The spec prohibits entity state in predicates.
    No negative test verifies the error message for this case.
    Generated: ambiguity_entity_state_predicate.tenor

  3 ambiguity test cases generated.

LSP

tenor lsp

Start the Language Server Protocol server for .tenor files. Communicates over stdio and integrates with any LSP-compatible editor.

tenor lsp

The LSP server is typically launched automatically by the VS Code extension, but can be used with any editor that supports LSP.

Capabilities:

FeatureDescription
DiagnosticsReal-time elaboration errors and warnings as you type
Go-to-definitionNavigate to construct declarations (facts, entities, rules, operations, flows, personas, sources)
HoverType information, source declarations, construct details on hover
AutocompleteContext-aware completion for construct references, persona names, entity states, verdict types
Semantic tokensSyntax highlighting for all Tenor constructs
ReferencesFind all references to a construct across files

VS Code extension setup:

The VS Code extension (editors/vscode/) uses vscode-languageclient to connect to the LSP server. Install the extension, and it will automatically start the tenor lsp process when you open a .tenor file.


Validation

tenor validate

Validate an existing interchange JSON bundle against the formal JSON Schema (schema/interchange-schema.json).

tenor validate BUNDLE

Example usage:

bash
tenor validate contract.json

Example output:

tenor validate contract.json

  Schema:  interchange-schema.json v1.0
  Bundle:  contract.json
  Constructs: 4 Personas, 4 Sources, 5 Facts, 2 Entities, 8 Rules, 7 Operations, 2 Flows

  ✓ Valid interchange bundle.