Skip to content

Language Overview

Use this section as the formal reference for Branchline syntax and semantics.

Read this first

Reference sections

Input Policies

  • JSON object keys must be unique; duplicates are rejected in CLI and playground input parsing.
  • JSON number parsing defaults to safe mode: large integers become BigInt and high-precision decimals become BigDec.
  • Use --json-numbers strict to reject values outside the safe JSON numeric range.
  • JSON numeric key conversion is opt-in via --json-key-mode numeric; it converts non-negative integer keys without leading zeros (except 0) for nested objects (top-level input keys remain strings).
  • JSON bytes are accepted only when contracts declare bytes; they must be base64 strings using the standard alphabet with = padding and no line breaks.
  • Inferred contracts are flow-sensitive and emitted in V3 node form (root.kind/children/element) with explicit obligations. Coalesce reads (a ?? b) emit oneOf obligations instead of forcing both fields as unconditional required inputs.
  • In inferred input contracts, discovered read paths are descriptive and usually optional in the node tree; enforceable requiredness is carried by obligations.
  • Wildcard output signatures (-> _ / -> _?) run in hybrid mode: declared input type seeds static inference and output remains inferred.
  • XML input maps attributes to @name keys.
  • XML pure text content maps to $; mixed content text segments map to $1, $2, ...
  • XML repeated sibling elements map to arrays.
  • XML empty elements with no attributes or children map to "".
  • XML reserves @*, $, and $n keys for attributes and text segments.
  • XML also provides #text as a compatibility alias for $ on pure text nodes.
  • XML namespace declarations are normalized into @xmlns, where default namespace is @xmlns.$ and prefixed declarations use @xmlns.<prefix>.
  • XML element and attribute names preserve prefixes (for example x:item and @x:id).

Output Policies

  • JSON output can be emitted in canonical form (json-canonical) with deterministic key ordering and normalized numeric formatting.
  • Safe JSON output encodes BigInt/BigDec as strings; use --json-numbers extended to emit numeric literals.
  • JSON output encodes bytes as base64 strings using the standard alphabet with = padding and no line breaks.
  • Sets serialize as JSON arrays with deterministic ordering (null, boolean, number, string, array, object).
  • XML output is available via --output-format xml|xml-compact.
  • XML output sorts attributes lexicographically by name.
  • XML output preserves array order for repeated sibling elements of the same name.
  • XML output sorts sibling element names lexicographically unless @order is provided.
  • XML output accepts @order as an explicit sibling name order list, then appends remaining siblings lexicographically.
  • XML output validates prefixed element and attribute names against in-scope @xmlns declarations in strict mode.
  • CLI emits conversion-loss warnings to stderr when known lossy JSON/XML conversions occur.

Contract JSON Modes

  • bl inspect <script.bl> --contracts-json emits V3 JSON by default.
  • bl inspect <script.bl> --contracts-json --contracts-version v2 keeps compatibility output during migration.
  • bl inspect <script.bl> --contracts-json --contracts-witness includes synthesized strict-valid input/output samples.
  • bl inspect <script.bl> --contracts-json --contracts-debug additionally emits debug metadata (origin, spans, and inferred-rule metadata such as confidence/ruleId).

Example (default):

{
  "version": "v3",
  "root": {
    "required": true,
    "kind": "object",
    "children": {
      "greeting": {
        "required": true,
        "kind": "text",
        "children": {}
      }
    }
  },
  "obligations": [],
  "mayEmitNull": false,
  "opaqueRegions": []
}

Example (--contracts-debug):

{
  "version": "v3",
  "root": {
    "required": true,
    "kind": "object",
    "origin": "OUTPUT",
    "children": {
      "greeting": {
        "required": true,
        "kind": "text",
        "origin": "OUTPUT",
        "children": {}
      }
    }
  },
  "obligations": [],
  "mayEmitNull": false,
  "opaqueRegions": []
}

Internal Interchange

  • Branchline runtime now provides internal CBOR encode/decode helpers for lossless Branchline-to-Branchline interchange.
  • CBOR map keys are restricted to text or integer keys; other key types are rejected.
  • Extended types are preserved with tags: BigInt (2/3), BigDecimal (4), and Set (267).
  • CBOR byte strings are used for binary values, so internal interchange does not require base64.
  • Deterministic CBOR is available via CborEncodeOptions(deterministic = true) and applies canonical ordering for map keys and set elements.

Standard Library