Skip to main content

Tersalang

Tersalang is a small, word-based programming language designed to be written by language models and scored by reinforcement-learning harnesses. Blocks open with do and close with end, every effect a function uses is declared with uses, contracts (requires, ensures, invariant) are checked at run time, and every diagnostic has a stable code and a JSON form.

This repository holds tersa, the reference interpreter, and an exported copy of the language specification.

module hello

import std.console exposing print

public function main() returns Unit
  uses Console
do
  print("Hello, world!")
end

The language version is 0.1-draft and the tool version is 0.1.0. Both can still change in incompatible ways.

Install

You need CPython 3.12 or newer and uv. The interpreter has no runtime dependencies.

git clone https://github.com/kevindm-design/tersalang.git
cd tersalang
uv sync
uv run tersa version

pip install -e . also works and puts tersa on your PATH. The examples below write tersa for uv run tersa.

Quickstart

Save this as area.tersa:

module area

import std.console exposing print

public record Rect
  width: Int
  height: Int
  invariant width >= 0 and height >= 0
end

public function area(r: Rect) returns Int
  ensures result >= 0
do
  return r.width * r.height
end

test "a 3 by 4 rectangle has area 12"
do
  expect area(Rect(width = 3, height = 4)) == 12
end

public function main() returns Unit
  uses Console
do
  print(show(area(Rect(width = 3, height = 4))))
end

Check parses and type-checks the file. It prints nothing and exits 0 when the file is clean:

$ tersa check area.tersa

Run calls main. Effects are granted by the host, so Console must be allowed:

$ tersa run area.tersa --allow Console
12
$ tersa run area.tersa
error[E4010]: main uses Console, but Console was not granted
  --> area.tersa:23:8
  = fix: run with --allow Console

Test runs the test blocks and doc examples and ends with a summary line:

$ tersa test area.tersa
1 test passed, 0 doc examples passed

Format rewrites files into the one canonical layout. --check only reports, prints a diff, and exits 1 when a file would change:

$ tersa fmt --check messy.tersa
would reformat messy.tersa
...
-      return r.width*r.height
+  return r.width * r.height
$ tersa fmt messy.tersa

check, run, test, and sandbox accept --json, which ends stdout with one line holding the diagnostics as a tersa.diagnostic/0.1 array:

$ tersa check --json bad.tersa
[{"schema": "tersa.diagnostic/0.1", "code": "E3033", "severity": "error", "category": "type", "message": "expected Int, found Text", ...}]

Each code links to a page in docs/diagnostics.md with a wrong and a fixed example. Exit codes, execution modes, limits, and every flag are in docs/cli.md.

Harness

tersa harness scores one program against a task. That is the loop an RL trainer runs. A task is a directory:

examples/tasks/add_one/
  task.toml              limits, effect grants, reward settings
  prompt.md              what the agent is asked to do
  interface.tersa        the functions the attempt must define, with contracts
  visible_tests.tersa    tests the agent may see
  hidden/tests.tersa     tests that score the attempt
  reference/solution.tersa
uv run tersa harness run examples/tasks/add_one --attempt my_attempt.tersa
uv run tersa harness run examples/tasks/add_one --attempt my_attempt.tersa --agent-view
uv run tersa harness validate examples/tasks/add_one

harness run prints one tersa.result/0.9 episode as JSON. The harness:

  • Checks that the attempt defines the functions interface.tersa requires, with the same signatures.
  • Merges the attempt with the hidden tests in a private namespace, so the attempt cannot reach or redefine hidden code.
  • Runs each hidden test in a fresh interpreter under fixed fuel and memory limits, in a child process with OS isolation where the host supports it.
  • Scores the episode as reward = (1 - w) * C + w * C * E. C is the fraction of hidden tests passed (with the default check_credit of 0), E compares fuel used with the reference solution, and w defaults to 0.1.

--agent-view prints the copy an agent may see. That copy withholds hidden-test detail and rounds the resource counts. harness validate checks a task before training: the reference must pass, and sampled mutants of it must not.

The full rules are in docs/harness.md. They cover the reward, isolation backends, scored traps versus discarded episodes, and the reward-hacking defenses.

Grammars

tersa grammar prints the grammar as EBNF (the default), Lark, or GBNF. The GBNF export works with stock llama.cpp, so a model can be constrained to write only Tersalang that parses:

uv run tersa grammar --format gbnf                      # every layout the parser accepts
uv run tersa grammar --format gbnf --profile decoding   # the formatter's whitespace, for generation

See docs/gbnf.md.

Documentation

Document Contents
spec/ The Design Doc and the Language Reference, plus the grammars and catalogs
docs/cli.md Every tersa command, flag, execution mode, and exit code
docs/harness.md Task layout, reward formula, agent view, isolation, and reward-hacking defenses
docs/gbnf.md The GBNF export, its two profiles, and how it is checked against llama.cpp
docs/diagnostics.md Every diagnostic code with examples (generated from spec/diagnostics.yaml)
docs/spec-notes.md Where this interpreter settles a point the specs leave open
CHANGELOG.md What changed in each release

Repository layout

Path Contents
src/tersalang/ The interpreter. The package docstring in __init__.py lists each module
spec/ Specification exports, tersa.ebnf, tersa.lark (the grammar oracle and source of tersa.gbnf), the diagnostic, fuel, and limit catalogs, and JSON schemas
conformance/ .tersa programs whose header says what each must produce, such as # expect: check-error E3033
examples/ A hello-world program and the add_one harness task
tests/ Unit, conformance, property, and fuzz tests
scripts/ CI checks: formatting, GBNF drift, llama.cpp agreement, determinism bytes, and the generated diagnostics page
teps/ The template for Tersalang Enhancement Proposals

What this version runs

The interpreter lexes, parses, type-checks, and evaluates one file plus the built-in standard library: List, Map, Set, Text, Bytes, Option, Result, math, console, files, clock, random, and JSON. Int is arbitrary precision with a 65,536-bit cap, and Int64 traps on overflow. Not yet included: multi-file packages, the language server, Net, and container isolation beyond bubblewrap.

The language was formerly called AIOWL.

Contributing and license

See CONTRIBUTING.md. Every commit needs a Signed-off-by trailer. Language changes go through a TEP.

The code is Apache-2.0. The specification and docs are CC BY 4.0. See LICENSE and NOTICE.

Metadata

Release files for tersalang 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for tersalang 0.1.0
File Size Uploaded Provenance
tersalang-0.1.0.tar.gz 410.0 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for tersalang 0.1.0
File Interpreter ABI Platform
tersalang-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 588.1 kB

Release files / tersalang-0.1.0.tar.gz

Download URL tersalang-0.1.0.tar.gz
Size 410.0 kB
Tags Source
SHA-256 checksum
How to use checksums
0bda560fd40f7f6c866ce866f55bd83c84c3b996fa92799e3c81ac6755b7df88
BLAKE2b-256 checksum
How to use checksums
27034cae5b5bd8a42764624a1e2d482a68d022056844918de74d4fc0c1b428b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / tersalang-0.1.0-py3-none-any.whl

Download URL tersalang-0.1.0-py3-none-any.whl
Size 178.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a7601c95c1b43d5f0fc234285fc619bfdbecab710b0165086368ceccc19bf1f2
BLAKE2b-256 checksum
How to use checksums
de799e5df7aeb6e067d59e0a4dc374724a02121f35f24580c7092c19e547fbe9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for tersalang 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for tersalang-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page