Skip to content
Phero Lang
Menu

.dmn

Decision model

Decision requirements and decision services

Backend

consumed byphero-backend-dmn

The decision-requirements graph, business knowledge models, knowledge sources, decision services, and external markdown decision tables.

Why it exists

What .dmn is for

A .dmn file declares one decision model whose central structure is the decision-requirements graph: input data, decisions, business knowledge models, knowledge sources, decision services, and the three requirement kinds — information, knowledge and authority — that wire the graph.

Logic is attached to a node, never the node itself: a decision with no logic clause at all is a valid, first-class declaration, which is the architecture-first reading of DMN. Inputs, outputs and parameters resolve against the imported .mox domains, and a decision’s emits block names the .evt contracts its outcome publishes.

Vocabulary

What it models

The concepts .dmn declares, and what each one means to the compiler.

decision_model
One per file, with a namespace.
inputs
Typed input data; each entry resolves against the imported domain union.
decision
A graph node with output or outputs, and optional logic. The logic is an implementation detail of the node.
knowledge model
A reusable function with declared parameters and an output type (model assess_refund { … }).
knowledge source
The authority behind decisions: a name and a reference.
requirements
The three edge groups: information, knowledge and authority.
decision service
The invocation contract: inputs, outputs and the set of nodes it encapsulates.
logic kinds
table "<path>" for an external markdown decision table, expression "<FEEL>", and invoke <model> { … }.
emits
Maps a decision outcome to declared events, checked against the .evt contracts.

Source

A working example

Quoted from the example this page's artifact was compiled from — not a snippet written for the website.

Lines 34–46 of examples/support/support.dmn, reproduced byte for byte, read from the file at build time:

examples/support/support.dmn · lines 34–46
        decision RefundEligibility {
            output boolean;
            logic expression "helper.active and ticket.needsRefund and requested_cents > 0"
        }
        /// The approval ladder: who must sign off and how much they may release.
        decision RefundAuthority {
            outputs {
                requires_approval: boolean;
                approver_role: string;
                maximum_amount: int;
            }
            logic table "./tables/refund-authority.md"
        }

Two decisions: one whose logic is a FEEL expression, one whose logic is an external markdown decision table. The third, `RefundAssessment`, composes them with an `invoke` and emits `RefundApproved`.

The whole file is CI-tested: pherolang check examples/ checks every surface in the tree, and the example harness compiles each one on every run. What you see above is the input to the artifact below.

Neighbours

How it relates to the other surfaces

A decision model consumes domain types and declared events — never a design or policy artifact: .mox supplies the types, .evt the contracts it may emit to. The link is one-way. .ddd service operations point at a decision service (invokes, or inject decision on the module, optionally version-pinned), and .cmmn decision tasks invoke a service such as RefundDecisions.AssessRefund as case work. A decision model imports neither.

Read alongside

Commands

How to compile and validate

Three commands, one file. They run from the repository root against the example on this page.

bash
pherolang check examples/support/support.dmn
pherolang ir examples/support/support.dmn -o site/data/artifacts/dmn.json
pherolang artifact check site/data/artifacts/dmn.json

check parses, resolves, validates and type-checks the file and printsOK examples/support/support.dmn. ir writes the artifact and prints nothing on success. artifact check then validates the serialized JSON on its own — no model, no import resolution, no compiler — and prints OK site/data/artifacts/dmn.json.

Directories work too: pherolang check examples/ enters project mode and checks every supported surface under the tree, each file's imports resolving from the snapshot.

Artifact

What it produces

One versioned JSON artifact, emitted by the compiler and consumed by whatever reads this surface.

One DmnModel: inputs, knowledge sources, business knowledge models, decisions, the three requirement groups, services and views — the shape the DMN backend lowers into its engine model.

The artifact is site/data/artifacts/dmn.json, and it is committed here exactly as the released pherolang binary emits it. Its top-level shape:

  • name"RefundDecisions"
  • namespace"nz.example.support.decisions"
  • inputs3 entries
  • knowledgeSources1 entry
  • businessKnowledgeModels1 entry
  • decisions3 entries
  • informationRequirements6 entries
  • knowledgeRequirements1 entry
  • authorityRequirements2 entries
  • services1 entry
  • views1 entry

Jump to the compiled artifact

Provenance

formatVersion = 2
The compatibility gate. A reader accepts this number or refuses the file.
pheroVersion — not present
This standalone surface artifact is versioned on its ownformatVersion; only the domain model artifact carries the compiler-version stamp.
6,092 bytes
270 lines, two-space indented, in the file's own key order.

The compiled artifact

The first 40 of 270 lines, verbatim — the exact bytes pherolang ir writes, not a hand-written sample. The slice stops at a JSON boundary; the ellipsis marker is outside the JSON, and the full file is site/data/artifacts/dmn.json.

artifacts/dmn.json · lines 1–40
{
  "formatVersion": 2,
  "name": "RefundDecisions",
  "namespace": "nz.example.support.decisions",
  "inputs": [
    {
      "name": "ticket",
      "typeRef": {
        "type": "class",
        "value": {
          "package": "nz.example.support",
          "name": "Ticket"
        }
      }
    },
    {
      "name": "helper",
      "typeRef": {
        "type": "class",
        "value": {
          "package": "nz.example.support",
          "name": "User"
        }
      }
    },
    {
      "name": "requested_cents",
      "typeRef": {
        "type": "primitive",
        "value": "int"
      }
    }
  ],
  "knowledgeSources": [
    {
      "name": "ConsumerGuaranteesAct",
      "displayName": "Consumer Guarantees Act 1993",
      "reference": "https://www.legislation.govt.nz/act/consumer-guarantees-1993"
    }
  ],

… 230 more lines in site/data/artifacts/dmn.json

Regenerate it from the repository root — the second command validates the serialized bytes with no compiler in the loop:

bash
pherolang ir examples/support/support.dmn -o site/data/artifacts/dmn.json
pherolang artifact check site/data/artifacts/dmn.json

The whole data directory is regenerated by node scripts/sync-model.mjs (run from site/) with the released binary; CI fails on a one-byte difference.

Reference

Documentation

The normative reference for this surface, rendered from the repository's own documentation.