Documentation

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.

1

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
2

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
3

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)
4

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

FieldTypePurpose
namestringScoped npm package name, e.g. @org/tool
versionstringSemver version string
inputJSON SchemaValidates inputs before resolve() is called
outputJSON SchemaValidates outputs before entering the step context
deterministicbooleanWhether the same input always produces the same output
sideEffectsbooleanWhether 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.

TestEnforces
R-005Resolver metadata contract
R-006Resolver runtime shape
R-007Failure contract
R-008Input validation
R-009Retry semantics
R-010Output contract
R-011Determinism
R-012Side-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-005

Metadata contract

resolverName + version must exist and be traceable

R-006

Runtime shape

resolve(input) → {output} or {error} — never both

R-007

Failure contract

Invalid input returns {error}, never throws uncaught

R-008

Input validation

Malformed actions explicitly rejected at boundary

R-009

Retry semantics

retriable must be boolean if present

R-010

Output contract

Output must always be JSON-serializable

R-011

Determinism

Same input → same output, no hidden state

R-012

Side-effect safety

No observable side effects during validation

  1. 1.Run the conformance suite locally — all 8 tests must pass:
    pip install olang-resolver-test && olang-test --jsonornpx olang-test --json
  2. 2.A certification badge is generated (badge.txt) — include it in your repo README to confirm O-Lang CERTIFIED status.
  3. 3.Publish to npm or PyPI, then submit via the Tool Registry.
  4. 4.The O-Lang team independently re-runs the full conformance suite and reviews governance compatibility before approving listing.
  5. 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
live on PyPI

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-testscaffold

Reference implementation and starter scaffold. Use this as the template when building any new Python resolver.

pip install olang-resolver-testPyPI ↗
olang-semantic-doc-searchutils

Embedding-powered semantic document search with governed output scope and result format enforcement.

pip install olang-semantic-doc-searchPyPI ↗

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.

npm install @o-lang/kernel

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.

pip install olang-kernel  # coming soon

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

1

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.

2

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.

3

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.

4

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.

Read the spec ↗