Skip to main content
IntentLang
Draft documentation. Syntax and behavior are illustrative and will change before v1.

Export Adapters (DMN, BPMN, model checking)

The Intent Graph is the source of truth, but it does not have to be the only place the intent is checked. Decisions and lifecycles are exactly the structures that mature, standardized tooling already reasons about: decision-table engines, process modelers, and model checkers. Export adapters render those slices of the graph into the industry formats so intent can be validated by existing tools without leaving IntentLang.

Nine adapters ship, all deterministic and pure (string in, string out):

Format From For
DMN 1.3 decisions decision-table engines (Camunda, Drools, jDMN)
BPMN 2.0 lifecycles process modelers (Camunda, bpmn.io, Signavio)
NuSMV lifecycles + temporal model checkers (NuSMV, nuXmv)
JSON Schema typed input/output fields validators, codegen, mock servers
OpenAPI 3.1 the mission as an operation API tooling (Swagger, clients, gateways)
Design Tokens (DTCG) style intent tokens Style Dictionary, Figma Tokens
CSS style intent tokens a drop-in :root custom-property sheet
Mermaid the whole Intent Graph a paste-anywhere diagram
Playwright experiences + journeys an E2E test scaffold

Each exports only what is declared: a mission with no decisions produces an empty-but-valid DMN document, and a mission with no lifecycle produces an SMV note rather than a broken model.

DMN , decisions become decision tables

A decision block maps to a DMN decision table with hit policy FIRST: rules are ordered, the first match wins, and the mission default becomes the final catch-all rule. The when expression is preserved verbatim (XML-escaped) so nothing about the condition is lost in translation.

intent export eligibility.intent --format dmn

BPMN , lifecycles become processes

A lifecycle state machine maps to a BPMN process: each state is a task, each transition is a named sequence flow, the initial state is entered from a start event, and terminal states flow to an end event. Open it in any BPMN modeler to see the declared flow as a diagram.

intent export enrollment.intent --format bpmn

NuSMV , lifecycles become checkable models

The state machine becomes a NuSMV module with a faithful transition relation. The adapter emits the specs it can derive with certainty:

  • SPEC EF (state = T) for every terminal T , the terminal is reachable.
  • For each always / eventually / until declaration, a SPEC skeleton with the intent text as a comment and a p_i proposition to bind. Because the temporal statements are free text, the adapter emits the temporal shape and leaves the atomic proposition for a human to bind, rather than guessing.
intent export enrollment.intent --format smv
MODULE main
VAR
  state : {Draft, Submitted, Approved, Rejected};
ASSIGN
  init(state) := Draft;
  next(state) := case
      state = Draft : Submitted;
      state = Submitted : {Approved, Rejected};
      state = Approved : Approved;
      state = Rejected : Rejected;
    esac;

SPEC EF (state = Approved);   -- terminal "Approved" is reachable
-- always: application is never lost  ->  SPEC AG (p_0)

JSON Schema and OpenAPI , typed fields become a data contract

A mission's input / output typed fields are a data shape, and data shapes are what API tooling already speaks. The JSON Schema adapter maps each field's semantic type to a JSON Schema fragment (Email → {type:string, format:email}, Money → number, List<Order> → array, Secret → writeOnly, an id → string, an unknown entity → an opaque object), and marks every declared field required unless it carries an optional modifier.

intent export mission.intent --format jsonschema

The OpenAPI adapter goes one step further and renders the whole mission as an operation: the input schema becomes the request body, the output schema becomes the 200 response, and declared errors become named error responses with inferred status codes (NotFound → 404, Duplicate → 409, Unauthorized → 403). Path and method come from a declared api block when present, else default to POST /<mission>.

intent export mission.intent --format openapi

So a mission with typed inputs and outputs is, for free, a validatable JSON Schema and a usable OpenAPI operation, no hand-written contract.

Design tokens (from style intent)

A style_intent declares brand tokens against a canonical address space. --format tokens renders them as a W3C Design Tokens (DTCG) document , the shape Style Dictionary, Figma Tokens, and CSS pipelines consume. Dotted addresses become nested groups, and each token carries the inferred $type (color.primary → color, typography.scale → number, typography.families.body → fontFamily, shape.radius → dimension).

intent export mission.intent --format tokens
{
  "color": { "primary": { "$value": "#0B5FFF", "$type": "color" } },
  "typography": { "scale": { "$value": 1.25, "$type": "number" } },
  "$extensions": {
    "dev.intentlanguage": {
      "schema": "intent-design-tokens-v1",
      "styleIntents": [{ "name": "CheckoutLook", "accessibility": { "target": "WCAG_2_2_AA", "classification": "proposed", "verified": false } }]
    }
  }
}

Accessibility targets ride along in $extensions as proposed claims, never as verified conformance, so a token pipeline never mistakes "aiming for AA" for "is AA."

For the direct, no-external-tool path, --format css emits a ready-to-use stylesheet: every canonical address becomes a --kebab-case custom property on :root, a mode token drives color-scheme, and brand.logo becomes a url(...). intent export style.intent --format css > theme.css is a usable theme with no build step.

:root {
  --color-primary: #0B5FFF;
  --typography-families-body: Inter;
  color-scheme: light dark;
}

Mermaid (the whole graph as a diagram)

--format mermaid renders the entire Intent Graph as a Mermaid graph TD , every canonical node shaped by category (rounded for states and lifecycles, hexagon for guarantees/never/constraints, rhombus for decisions and rules, rectangle for the rest) and every relationship as a labeled edge. Node ids are made Mermaid-safe and labels are sanitized, so the output pastes straight into GitHub, Markdown, or Notion as a live diagram.

intent export mission.intent --format mermaid
graph TD
  n_mission_upgrade["Mission: Upgrade a customer to a higher tier"]
  n_lifecycle_state_upgradeflow_charged(["LifecycleState: Charged"])
  n_decision_canupgrade{"Decision: CanUpgrade"}
  n_mission_upgrade -->|represented_by| n_lifecycle_upgradeflow

Unlike the mission-summary diagram written into the build's .mmd artifact, this is the complete graph, so it is the fastest way to see an entire intent at a glance.

Playwright (experience -> E2E test scaffold)

--format playwright turns declared experience blocks into a Playwright spec skeleton: each experience becomes a test.describe, each journey a test whose steps become test.step stubs, and each state a reachability test (failure states get a recovery-path test). It is a scaffold , the structure of the test that proves the experience, with TODOs for selectors and assertions , not a passing test. The accessibility target rides along as a comment (a proposed goal, never assumed met).

intent export mission.intent --format playwright

This is the test-plan target for the experience profile: it turns "what the UI must do" into the shape of the test that proves it, deterministically.

Usage

intent export <file> --format <dmn|bpmn|smv|jsonschema|openapi|tokens|mermaid|css|playwright> prints to stdout, or writes a file when --out <dir> is given. From the library, toDMN(ast), toBPMN(ast), toSMV(ast), toJSONSchema(ast), toOpenAPI(ast), toDesignTokens(ast), toMermaid(ast), toCss(ast), toPlaywright(ast), and exportIntent(ast, format) are exported from @skillstech/intentlang (toDesignTokens and toCss are also browser-safe via /core). The exports are byte-deterministic: the same intent always produces the same document, so they diff cleanly and belong in version control alongside the intent.