Build governed AI
with O-Lang
O-Lang is a workflow language for AI systems that require auditability, safety enforcement, and cryptographic accountability. Built for Finance, Healthcare, Government, and IoT — every execution is governed, not hoped for.
Quickstart
Get O-Lang running and execute your first governed workflow in under 5 minutes.
Install the kernel and tools
The JS kernel is the runtime — stable, production-ready, and language-agnostic. Tools are separate npm (or pip) packages you install and declare in your workflow.
Terminal
npm install @o-lang/olang npm install @o-lang/llm-groq npm install @o-lang/bank-account-lookup
Write your first workflow
Create my-workflow.ol. The Allow resolvers: block is your governance contract — only listed tools can execute.
my-workflow.ol
Workflow "Balance Check" with customer_id, user_question Allow resolvers: - @o-lang/bank-account-lookup - @o-lang/llm-groq Step 1: Ask @o-lang/bank-account-lookup "{customer_id}" Save as account_info Step 2: Ask @o-lang/llm-groq "{user_question}. Balance: {account_info.balance}" Save as response Return response
Run it
Pass inputs and receive a governed response with a full cryptographic audit trail.
run.js
const { runWorkflow } = require('@o-lang/olang');
const result = await runWorkflow('my-workflow.ol', {
customer_id: 'CUST-001',
user_question: 'What is my current balance?'
});
console.log(result.response);
// → "Your current balance is $12,450.00."
console.log(result.audit.execution_hash);
// → sha3:a3f8c2d1... (cryptographic proof of execution)What you get
Governed response
Output produced only through declared tools in the declared order.
Execution trace
Every step logged with resolver name, policy check, and timestamp.
Audit hash chain
SHA3-256 fingerprint chained from genesis block to final output.
Safety enforcement
Prohibited intents blocked before any tool is called.
Building Tools
In O-Lang, tools are called resolvers internally — modular, schema-validated functions the kernel calls during workflow execution. Resolvers can be written in any language (Node.js, Python, Go, Rust, and more). The only requirement: JSON in, JSON out, and a passing conformance test suite. Both npm and PyPI resolvers are first-class citizens in the registry.
Anatomy of a resolver
Every resolver exports a declaration (what it is and what it can do) and a resolve function (the actual logic).
index.js — minimal resolver
const declaration = {
name: "@my-org/my-tool",
version: "1.0.0",
input: {
type: "object",
properties: {
id: { type: "string", description: "Record ID to look up" }
},
required: ["id"]
},
output: {
type: "object",
properties: {
result: { type: "string" },
found: { type: "boolean" }
}
},
properties: {
deterministic: true, // same input → same output
sideEffects: false, // read-only
requiresAuth: false
}
};
async function resolve(input) {
const record = await db.find(input.id);
return { result: record.value, found: !!record };
}
module.exports = { declaration, resolve };Declaration fields
| Field | Type | Purpose |
|---|---|---|
| name | string | Scoped npm package name, e.g. @org/tool |
| version | string | Semver version string |
| input | JSON Schema | Validates inputs before resolve() is called |
| output | JSON Schema | Validates outputs before entering the step context |
| deterministic | boolean | Whether the same input always produces the same output |
| sideEffects | boolean | Whether the resolver writes to external state |
Testing your resolver
test.js
const myTool = require('./index');
// Verify declaration shape
console.assert(myTool.declaration.name, 'name required');
console.assert(typeof myTool.resolve === 'function', 'resolve must be a function');
// Test the resolver
const result = await myTool.resolve({ id: 'test-001' });
console.log(result);
// → { result: "...", found: true }Conformance test suite (R-005 → R-012)
Every O-Lang resolver — in any language — must pass 8 conformance tests before it can be used in production or listed in the registry. The tests are JSON-defined and language-neutral: the runner adapts, the contract does not.
| Test | Enforces |
|---|---|
| R-005 | Resolver metadata contract |
| R-006 | Resolver runtime shape |
| R-007 | Failure contract |
| R-008 | Input validation |
| R-009 | Retry semantics |
| R-010 | Output contract |
| R-011 | Determinism |
| R-012 | Side-effect safety |
Run olang-test --json (Python) or npx olang-test --json (Node.js). A passing run generates badge.txt — the O-Lang CERTIFIED confirmation required before registry submission.
Publishing to the Tool Registry
Two gates. No exceptions.Every resolver — Node.js or Python — must pass the same 8 conformance tests (R-005 → R-012) before it can be submitted. When you submit, the O-Lang team independently re-runs the full suite on their end. A tool is only listed if it passes both times.
R-005Metadata contract
resolverName + version must exist and be traceable
R-006Runtime shape
resolve(input) → {output} or {error} — never both
R-007Failure contract
Invalid input returns {error}, never throws uncaught
R-008Input validation
Malformed actions explicitly rejected at boundary
R-009Retry semantics
retriable must be boolean if present
R-010Output contract
Output must always be JSON-serializable
R-011Determinism
Same input → same output, no hidden state
R-012Side-effect safety
No observable side effects during validation
- 1.Run the conformance suite locally — all 8 tests must pass:
pip install olang-resolver-test && olang-test --jsonornpx olang-test --json - 2.A certification badge is generated (
badge.txt) — include it in your repo README to confirm O-Lang CERTIFIED status. - 3.Publish to npm or PyPI, then submit via the Tool Registry.
- 4.The O-Lang team independently re-runs the full conformance suite and reviews governance compatibility before approving listing.
- 5.Once approved, your tool receives a verified badge and appears in the registry — searchable by language, domain, and tag.
conformance suite output
✅ R-005 resolver-metadata-contract
✅ R-006 resolver-runtime-shape
✅ R-007 resolver-failure-contract
✅ R-008 resolver-input-validation
✅ R-009 resolver-retry-semantics
✅ R-010 resolver-output-contract
✅ R-011 resolver-determinism
✅ R-012 resolver-side-effects
🎉 Resolver is O-Lang CERTIFIED
🏷️ Badge generated: badge.txt
Python resolvers follow the same declaration + resolve contract as Node.js resolvers. Since the JS kernel is language-agnostic, Python resolvers integrate today via a lightweight HTTP bridge — no Python kernel required. Two reference packages are already published on PyPI and have passed the full conformance suite (R-005 → R-012):
olang-resolver-testscaffoldReference implementation and starter scaffold. Use this as the template when building any new Python resolver.
olang-semantic-doc-searchutilsEmbedding-powered semantic document search with governed output scope and result format enforcement.
Python resolver anatomy
A Python resolver exposes a declaration dict and a resolve(input) function served over HTTP. The JS kernel calls it via the standard resolver protocol — the language is invisible to the workflow author. When the native Python kernel ships, the same resolver code works without any changes. See olang-resolver-test for the full scaffold with examples.
Governance
Governance in O-Lang is declarative — rules live in the workflow file itself. The kernel reads them at load time and enforces them at every execution step, with no way to bypass them at runtime.
Tool Allowlists
Only tools declared in Allow resolvers: can be called. Any unlisted tool is rejected before the step executes.
Verified Intent
Declare scope and prohibited actions. The kernel validates intent before and after execution.
Safety Policy
Built-in filters block PII leakage, hallucinations, speculative outputs, and prompt injection.
Tool allowlists
The most fundamental governance primitive. If a tool is not listed, any step that tries to call it is rejected — even if injected via prompt manipulation.
Allowlist declaration
Allow resolvers: - @o-lang/bank-account-lookup # approved: read-only DB access - @o-lang/llm-groq # approved: LLM inference # These would be REJECTED at runtime — even if a step tried to call them: # - @o-lang/send-email # - @o-lang/modify-balance # - any tool not in this list
Intent scope and prohibited actions
Declare the semantic scope and the actions the workflow must never perform. The kernel catches violations in the user query before any tool is called.
Intent declarations
Prohibit actions: - transfer_funds - modify_balance - speculative_balance Intent scope: "balance_inquiry_only"
What happens on a violation
If a user query matches a prohibited action (e.g. "transfer $500 to James"), the kernel raises a safety_halt before Step 1 runs. No resolver is called. The violation is recorded in the audit trail with the exact matched pattern and policy name.
Output safety policy
The kernel inspects LLM outputs before returning them. Built-in rules block responses that contain speculative data, PII, or content outside the declared scope.
🛡 No PII in output
Account numbers, routing numbers, SSNs stripped before returning.
🛡 No speculative balances
Projected figures not sourced from a resolver are blocked.
🛡 No transaction confirmation
Any response implying a transaction occurred is rejected.
🛡 Scope enforcement
Responses outside the declared intent scope are flagged and blocked.
Kernel Architecture
The O-Lang kernel is the runtime between your workflow definition and tool execution. It parses, validates, governs, executes, and signs — in that order, every time, with no shortcuts. The JavaScript kernel is stable and production-ready. It is language-agnostic: any tool or client can integrate over HTTP, regardless of runtime.
JavaScript Kernel — Stable
The JS kernel is complete, tested, and production-ready. It parses .ol workflows, enforces governance policies, executes tool calls, and produces signed audit chains.
Python Kernel — In Development
A native Python kernel is under development for pip-native integration, familiar tooling, and seamless adoption in Python-first environments. Python tools can already integrate today via HTTP.
Language-agnostic by design. The JS kernel exposes a standard HTTP API — Python, Go, Rust, or any HTTP-capable runtime can call it directly. Python tools published on PyPI (like olang-semantic-doc-search) already use this bridge. The native Python kernel, when released, will wrap the same protocol in a pip-installable package for a seamless local experience.
Execution pipeline
Parse
The .ol file is tokenised and validated against the O-Lang grammar. Malformed workflows are rejected here — nothing executes on a parse error.
Output: AST with resolved step graph, input bindings, and governance profile.
Govern
The tool allowlist, intent scope, prohibited actions, and safety policy are locked into an immutable governance profile. The profile hash is committed to the genesis audit block before execution.
Output: gov_profile_hash committed to the genesis audit block.
Execute
Steps run in declaration order. Each tool call is validated against the allowlist before dispatch. Outputs are schema-validated before being placed into context for the next step.
Output: populated context object with all Save as variables resolved.
Sign
The final output is SHA3-256 fingerprinted and chained to the previous execution hash. If an ED25519 private key is configured, the chain is signed before returning.
Output: execution_hash, merkle_root, and optional ED25519 signature.
Audit chain format
Every execution produces a linked hash chain. Each entry has a previousHash pointing to the prior block, making the chain tamper-evident. A merkle root covers all entries.
Audit response shape
{
"execution_hash": "sha3:a3f8c2d1e9b4...",
"previous_hash": "sha3:0000000000...", // GENESIS on first run
"governance_profile_hash": "sha256:7c2a1f...",
"kernel_version": "1.2.15-alpha",
"merkle_root": "sha256:4d9e8a...",
"signature": "ed25519:...", // if key configured
"integrity": {
"valid": true,
"totalEntries": 2
}
}Context isolation
Each workflow execution runs in an isolated context. Variables saved with Save as are scoped to the execution and cannot bleed between concurrent runs. The kernel enforces this at the runtime level — it is not a convention.
Official Kernel Specification — v1.1
Full grammar reference, execution model, audit chain format, safety policy schema, resolver contract specification, and integration guide.