Get started

µLang v1

µLang v1 is a small language for contracts that decide actions before they happen. An application describes a request as typed facts and asks whether an action may go ahead. It gets back PERMIT or DENY, and the id of the clause that decided it.

policy/deploy.ultut-final
// Production deploys: who may ship, and when.
CONTRACT ProductionDeploy {
  ENFORCEMENT_MODE: enforced
  CONTEXT {
    ENTITIES DeployRequest {
      environment: string
      tests_passed: bool
      approvals: int
      author_approved_own_change: bool
      error_rate_pct: float
      change_freeze: bool
    }
    CONSTANTS {
      min_approvals: int == 2 [SOURCE:ENG-HANDBOOK-7.1]
      max_error_rate_pct: float == 1.5 [SOURCE:SRE-SLO-3]
    }
  }
  TRIGGER {
    deploy()
    rollback()
  }
  GUARANTEE {
    ENSURE deploy() WHEN DeployRequest.tests_passed == true [SOURCE:tests_green]
    ENSURE deploy() WHEN DeployRequest.approvals >= min_approvals [SOURCE:two_approvals]
  }
  PROHIBITION {
    FORBID deploy WHEN DeployRequest.change_freeze == true AND DeployRequest.environment == "production" [SOURCE:change_freeze]
    FORBID deploy WHEN DeployRequest.author_approved_own_change == true [SOURCE:no_self_approval]
    FORBID deploy WHEN DeployRequest.error_rate_pct > max_error_rate_pct [SOURCE:error_budget]
    FORBID rollback WHEN DeployRequest.environment != "production" AND DeployRequest.environment != "staging" [SOURCE:known_environments]
  }
  OBSERVABILITY {
    LOG "deploy decision" ON decision
  }
}

valid ProductionDeploy 6 clauses · sha256 686358ddc154b77b5b7b3a24870b8dd6f79b23d376ed039d6824a923284e4059

Facts of the first request; each other request changes only the fields shown.

{
  "DeployRequest": {
    "environment": "production",
    "tests_passed": true,
    "approvals": 2,
    "author_approved_own_change": false,
    "error_rate_pct": 0.4,
    "change_freeze": false
  }
}
RequestActionChangedVerdictClause
a normal deploydeployas abovePERMITProductionDeploy.deploy.permit
freeze and self-approved: the first FORBID winsdeployauthor_approved_own_change: true change_freeze: trueDENYProductionDeploy.change_freeze
self-approved and tests failing: FORBID before ENSUREdeploytests_passed: false author_approved_own_change: trueDENYProductionDeploy.no_self_approval
tests failing and one approval: the first ENSURE that failsdeploytests_passed: false approvals: 1DENYProductionDeploy.tests_green

How it fits into an application

  1. The application builds the facts of one request: a flat record of int, float, bool and string values.
  2. It asks the contract to decide one action against those facts.
  3. The contract returns a verdict and the deciding clause. The application acts on it, and records it with the contract's digest.

Everything a rule needs is in the facts. A contract cannot read the clock, call a service or do arithmetic. That is why a decision is deterministic, cheap and easy to audit. Anything the rules need computed, such as a projected total, whether two ids are the same person or the hour of day, the application computes and passes in.

Where to start

If you want toRead
try it without installing anythingthe playground
run it in five minutesQuickstart
learn the language by building a contractTutorial
see the whole language on one pageLanguage tour
embed it in a serviceNode.js, Cloudflare Workers, Browser
look up an errorDiagnostics
implement it yourselfthe specification, the grammar and the test vectors

About these docs

These docs describe µLang v1 as implemented by ulang-lite 61af4281ed, the reference implementation (MIT, zero dependencies). Every contract, decision, diagnostic, digest, command output and HTTP response on this site is produced by that release when the site is built. The example project the guides use is run end to end at the same time. If anything here disagrees with ulang-lite, the docs are wrong.