← All guides

Developer quickstart — from a fresh machine to your first application

Correction (2026-09-23), scoped (2026-09-25). This correction is about EARL modifying its own code. Where this document describes EARL "authoring", "self-modifying" or repairing its own mechanism, read: EARL's governed loop replaces one bounded expression by random search under a grammar the lab supplied, accepted by a lab-frozen gate; nothing in that apparatus learns from its attempts, and self-repair has not been demonstrated. Autonomous code authorship is not an earned claim. Record: earl/genesis/g9/CORRECTION-2026-09-23-CODE-AUTHORSHIP.md; the original text is preserved as written.

It does not describe repair.develop, the code-repair developer preview, which is a different and narrower capability: EARL diagnoses, constructs and verifies supported repairs in the Rust code you designate, from taught operator meanings plus the requirement you supply, and applies them only on your approval. Its scope and limits are its own — see code-repair.md.

You are building your own software with EARL as its cognitive runtime. The platform runs the engine, keeps every application's state and records, and gives you one API (/api/v1) and one Python SDK (earl_sdk). This page takes you from a fresh machine to an application that evaluates evidence, reasons, remembers and is deployable, in about twenty minutes.

This build is an intermediate build: the cognitive capabilities below are measured as the register states. EARL modifying its own faculties (governed self-modification, self-repair, inherited development) is a set of qualified research results with no developer interface yet, and installed-release adoption is what an application can invoke of it today; the release gate is in the register's roadmap section. Repair of your designated Rust code is a different and narrower thing, and it does have an interface — see code-repair.md.

Before you start, read capability-limitations.md: it says, per capability, what is qualified, what is measured, what execution path it runs on, and what is not available. evidence.evaluate is exposed for bounded development and evaluation and is not qualified for unattended approval decisions.

0. Which of these are you?

A hosted evaluator. Someone gave you a platform URL and an account, and you have no repository checkout. Skip section 1 entirely — your platform is already running. Everything below that says http://localhost:8000 means your platform URL instead. Get the SDK and the reference applications from the running platform:

curl -fsSL -o earl-sdk.tar.gz https://<your-platform-host>/api/docs/sdk
tar xzf earl-sdk.tar.gz
pip install -e earl-sdk/python

Use -o earl-sdk.tar.gz, not -O: the URL path ends in sdk, so -O saves a file called sdk and the tar line then fails.

That download is built from the SDK inside the image you are calling, so it always matches the API you get. The guides you are reading are served the same way, at /api/docs/guides.

To check the platform end to end first, run python live_walkthrough.py from earl-sdk/examples with EARL_BASE_URL and your account set (the password is prompted for). It creates an application and key, trains the reference domain, reproduces its recorded outcomes through the SDK, verifies the signed records and an evidence package offline, and archives what it created. Every check prints PASS or FAIL. On Windows PowerShell, use curl.exe (plain curl is an alias for Invoke-WebRequest), tar -xzf earl-sdk.tar.gz, and set the variables with $env:EARL_BASE_URL = "https://<your-platform-host>" and $env:EARL_USERNAME = "<your account>".

Then go to section 2 and read it as follows. Sections 2 to 4 are API and SDK calls and work unchanged — substitute your platform URL wherever a command says http://localhost:8000. Everything in this guide that names a repository path (deploy/developer/..., platform/sdk/examples/...) belongs to the self-hosted path and does not exist in your download; the reference applications are inside earl-sdk/examples, and the environment-verification step in section 1 is not yours to run. Section 5 (deployment) assumes you are running the platform yourself.

Running it yourself. You have the repository and Docker, and you want your own instance. Start at section 1.

Either a user or an auditor account can follow this whole guide. An auditor is deliberately able to drive the platform end to end — an audit that cannot exercise what it is auditing is not an audit — and additionally reaches the read-only auditor surfaces. Only administration (creating accounts and organisations, installing engines) needs a super_admin.

1. Run the developer environment

Requirements: Docker (with compose), 8 GB RAM, 10 GB disk. From the repository root:

cp deploy/developer/.env.example deploy/developer/.env   # set the passwords
docker compose -f deploy/developer/docker-compose.yml up --build -d
docker compose -f deploy/developer/docker-compose.yml logs -f backend   # until "bootstrap complete"

The container installs the engine candidate (v0.66.0-rc20, Linux bundle, static musl) on first boot, creates a super-admin, an organisation and a developer account from .env, and serves the API on http://localhost:8000. The guides are served at /api/docs/guides; the UI's landing page is Applications.

Verify the environment reproduces the recorded artifacts before you build on it:

docker compose -f deploy/developer/docker-compose.yml exec backend python3 /app/deploy/developer/verify.py

2. Sign in once and create your application

Sign in to the UI as the developer account, or mint a session token:

curl -s -X POST http://localhost:8000/api/auth/token -H 'Content-Type: application/json' \
  -d '{"username":"developer","password":"<from .env>"}' | python -c 'import sys,json;print(json.load(sys.stdin)["access_token"])'

A session token lives for one hour (expires_in: 3600); mint a new one for a long authoring session. GET /api/auth/me tells you who a token or key is: your own account here, the application's service identity (app-<slug>, role user, your organisation) once you call it with an API key below.

Then create the application — in the UI (Build › Applications › Create) or through the SDK:

pip install -e platform/sdk/python
from earl_sdk import EarlClient

admin = EarlClient("http://localhost:8000", SESSION_TOKEN)
app = admin.create_application("Journal-entry review", "Reviews journal entries against approval policy")
issued = app.create_credential("ci")
API_KEY = issued["api_key"]            # shown once; the platform keeps only a hash
print(app.next_steps)

An application lives in your organisation and has its own service identity; every capability call made with one of its keys is recorded under that identity. From here on, your software uses the API key, never your session:

client = EarlClient("http://localhost:8000", API_KEY)
# GET /api/auth/me with the key answers {"username": "app-journal-entry-review", "role": "user", ...}

3. Connect data: a domain your application owns

The application reasons over a domain: a corpus you wrote, a vocabulary of the nouns your claims are about, a curriculum, and a policy. Creating and training one is the nested path inside the application flow (UI: Builder › Domains; the application page links there). The reference applications under platform/sdk/examples/ ship one each; train it through the documented HTTP flow with the helper the examples use, then connect it:

from pathlib import Path
from _common.platform_domain import PlatformDomain, urllib_http
out = PlatformDomain(urllib_http("http://localhost:8000", SESSION_TOKEN)).train(
    Path("platform/sdk/examples/procurement_review/domain"),
    name="Orbit procurement", description="my first domain",
    foundational_kb_package_id=1, earl_engine_id=ENGINE_ID)
app.connect_domain(out["domain_id"])

Two ids go into train:

Hosted evaluators: run this from inside the earl-sdk/examples directory you downloaded, so that _common imports, and pass Path("procurement_review/domain") and your platform URL.

Read authoring-domains.md before writing your own: nouns only in the vocabulary bands, one fact per sentence, propositions in their natural direction. The school refuses a curriculum the vocabulary cannot ground and names the lesson and token; generated curricula receive the vocabulary as a hard constraint.

4. Bind the cognitive runtime and invoke capabilities

bound = app.bind_workflow()                   # once, as the developer: the application's persistent EARL runtime over the trained domain
wf = client.workflow(bound.id)                # your software: the same workflow, called with the application's API key
record = wf.evaluate("Helix supplies software")            # standalone earl-verify: VERIFIED / CONTESTED / UNCERTAIN / HALLUCINATED
answer = wf.ask("What does a purchase require?")            # plain-English question over the domain's facts, with its evidence (natural-language-questions.md)
claim = record.result["claim_results"][0]
print(claim["verdict"], claim["endpoints"], claim["predicate"], claim["asserted_by"], claim["asserted_source"])
proof = wf.prove("helix requires supplier")                 # persistent runtime: a proof only when a derivation chain closes (see persistent-workflows.md: a single stated fact is not a derivation)
wf.submit("Nimbus supplies hardware.")                      # persistent runtime: remembered across calls and restarts; persistence is not truth
print(wf.beliefs("nimbus"))
plan = wf.plan("resolve the missing certification")
census = wf.observe()
assert client.verify_offline(record)["valid"]

Every call returns a typed outcome: a Result, a SemanticUncertainty (the engine declined with a reason), or an OperationalError (the environment failed). Every call is an append-only, Ed25519-signed record carrying the execution path it ran on (persistent_runtime or standalone) and the engine identity; a claim result names the pair, the predicate, the polarity and the source clause behind a VERIFIED verdict. Verify records offline, pinned to the platform's issuer key.

The UI's application page has a capability console that makes the same calls and shows the evidence line under each record.

5. Deploy

Freeze the trained domain and deploy the adjudicator (UI: Adjudication › Deployments; the application page lists the domain's deployments). A deployed container runs the standalone verifier (earl-verify) over the frozen checkpoint and answers POST /verify with the same claim results and a signed evidence package. The persistent runtime is not deployed as a container in this release: your software reaches it through the platform API with the application's key.