µLang v1 · ulang-lite 0.1.0 · MIT
Contracts that decide before anything happens.
Write the rules for an action as a small, typed contract. Ask it about one request at a time, and get back PERMIT or DENY with the clause that decided. Deterministic and auditable, with zero dependencies in Node.js, Cloudflare Workers and the browser.
policy/deploy.ulexample project// 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
}
}$ ./ulang-lite check policy/deploy.ul
policy/deploy.ul: ok ProductionDeploy (6 clauses; actions deploy, rollback; sha256 686358ddc154b77b5b7b3a24870b8dd6f79b23d376ed039d6824a923284e4059)$ ./ulang-lite eval policy/deploy.ul --action deploy --facts facts/freeze.json
{"verdict":"DENY","clause_id":"ProductionDeploy.change_freeze","contract_sha256":"686358ddc154b77b5b7b3a24870b8dd6f79b23d376ed039d6824a923284e4059"}$ ./ulang-lite eval policy/deploy.ul --action rollback --facts facts/freeze.json
{"verdict":"PERMIT","clause_id":"ProductionDeploy.rollback.permit","contract_sha256":"686358ddc154b77b5b7b3a24870b8dd6f79b23d376ed039d6824a923284e4059"}Deterministic
No clock, randomness, network or model in the decision path. The same contract and facts give the same decision, everywhere.
Attributable
Every DENY names one clause, every clause cites a source, and every contract has one SHA-256 digest.
Bounded
Input is size-, nesting- and depth-limited and checked in one linear pass before parsing. Anything outside the language gets one precise diagnostic.
Portable
ulang-lite is TypeScript with zero dependencies: Node.js 22.18+, Cloudflare Workers and browsers run the same engine.
Specified
A full specification, an EBNF grammar, and machine-readable test vectors.
In production
µLang Git decides its governed actions with twelve v1 contracts.
Learn
- QuickstartCheck, decide and call a contract from code in five minutes.
- TutorialBuild a deploy-approval contract one rule at a time.
- Language tourThe whole language on one page.
- PatternsAllow-lists, ranges, computed values, time, and saying "not".
Build with it
- Node.jsA decision endpoint that compiles the contract once.
- Cloudflare WorkersThe same endpoint, with the contract bundled as text.
- TestingDecision tests, and a digest pin that forces review.
- Audit trailDecision records anyone can replay.
Reference
- APIGenerated from the released source.
- Command line
check,evalandformat. - DiagnosticsAll 40 codes, each with an example and a fix.
- SpecificationSyntax, subset, validation, evaluation, canonical forms, limits.