# MeTTa

> MeTTa, Hyperon's AGI language, implemented in SWI-Prolog, with `metta` as its
> Python surface. Atoms are Python values, spaces are queryable stores,
> equations rewrite, and any Python library maps onto those forms. Every line
> below is a signature, an exact return shape, or a contract you cannot guess.
> Names here are checked against the live engine and the real file tree by
> `check.sh`'s `llms` lane, so a rename breaks the build instead of misleading
> you. That covers call heads, paths and the library roster, and it does NOT
> cover the name of a distribution published elsewhere: nothing here owns an
> oracle for one, and a lane reading a sibling checkout would go red for that
> checkout's reasons. This file said `metta-fabric-pc` for a package that calls
> itself `metta-fabricpc` until 2026-09-03, and the lane had no opinion.
> Counts are dated; treat an undated number as unverified.

## Every source of information in this repository

Prose can drift; the first four rows cannot, because a gate lane regenerates or
re-runs them.

| source | what it is | kept true by |
|---|---|---|
| `examples/**/*.metta` | 366 executable programs, the semantics documentation, in 20 chapters numbered to 22 whose order is the order a reader meets each construct. Read these BEFORE writing down what MeTTa can express | every one runs in the `examples` gate lane; `tests/data/example_skips.txt` names the five that do not, each with its reason |
| `tests/data/syntax_introductions.txt` | the construct each example chapter introduces, so a file uses nothing it has not met | the `cumulative-syntax` gate lane, which also carries a permanent negative control it must keep catching |
| `website/reference/metta-*.md` | 37 pages reproducing source signatures and docstrings | `extensions/python/tools/reference.py` |
| `website/reference/metta-libraries.md` | every library's own `(@doc ...)` atoms, plus a coverage row per library counting every head it declares, defines or REGISTERS | `extensions/python/tools/libdoc.py`, which renders `metta.library.rows`, the same query a card renders |
| `website/reference/refusals.md` | the engine's own `(refusal ...)` rows: the class each seat raises, the ground and the remedy | `extensions/python/tools/refusalsdoc.py` |
| `tests/prolog/suites/*/*.plt` | plunit suites over the engine itself, grouped by the engine unit each one tests | the `plunit` gate lane |
| `extensions/python/tests/*/test_*.py` | blackbox, hypothesis-fuzzed, in the same 20 chapters `examples/` uses, plus `conformance/` for the arbiters and `repository/` for the tests whose subject is this repository | the `pytest` gate lane |
| `extensions/python/examples/language-feature-examples/**/*.py` | one Python file per twinned MeTTa example, at that example's own path (an example with no twin is a row of the `twins` lane's derived backlog), written with no MeTTa source text, proving with `assert` every claim its original's `(test ...)` forms make or explicitly declining a structured-residue form, and priced by the engine's inference counter against a two-sided `BUDGET` at the foot of the file. Three further declarations sit beside it, each with the measurement that settled it: `ALLOWANCE` widens the point band where a twin's count tracks something that is not its work, `DIVERGENCE` pins the stored-content difference a twin means to have (a Python annotation IS a `(: ...)` row and a docstring IS an `(@doc ...)` row, so the two spaces are not obliged to be equal, only to differ exactly as declared), and `OVERRUN` names what the twin's own program costs beyond its example's 10% band. Read these for how a MeTTa program is spelled in Python | the `twins` gate lane, with `twins-selftest` planting one failure of each of the four |
| `CODEC.md` | the wire codec: the tagged form every atom crosses as, what a new binding implements | `extensions/python/tools/codecdoc.py`, whose tables come from `tests/codec/corpus.json` |
| `extensions/python/metta/_pygments.py` | the MeTTa Pygments lexer, GENERATED from `website/.vitepress/metta.tmLanguage.json`, the one TextMate grammar the site and the editor colour from. Registered under the `pygments.lexers` entry point with the alias `metta`, every filename ending in `.metta`, and the MIME type `text/x-metta`, so Sphinx, mkdocs, rich, IPython, nbconvert and a Jupyter kernel colour MeTTa once `pymetta` is installed and nothing has to be imported to arrange it. It carries no semantic colouring: the grammar's twelve groups are lexical, and meaning (a definition against a call, a known type) is what the language server's semantic tokens add | `extensions/python/tools/pygmentsgen.py`, the `pygments-sync` gate lane, and the `tokenisation` gate lane, which runs the grammar's OWN tokeniser through `website/scripts/tokenise.mjs` and requires the two to agree about every character of every `.metta` file in the tree |
| `extensions/python/metta/vocabularies.py` | the catalog's value vocabularies as StrEnum classes, one per `(vocabulary ...)` row; each member IS its wire word and encodes as its symbol, and bare words stay the runtime escape hatch | `extensions/python/tools/vocabgen.py`, the `vocab-sync` gate lane |
| `extensions/python/metta/_errors/refusals.py` | the seat's refusal table: one row per kind carrying the class THIS seat raises, the row's own seat-independent name, the departure reason where the two differ, the ground and the remedy template. `metta._errors.errors.refuse` and the crossing both read it | `extensions/python/tools/refusalgen.py`, the `refusal-sync` gate lane, which also holds every class it names to the fields its kind declares |
| every closed set in `extensions/python/metta/` | 49 of them, each stating one of three answers ADJACENT to it: `generated` naming its generator and sync lane, `seam` naming the point a registrant extends it through, or `decides` naming the policy and the row it reads. A module's `__all__` and a generated file's tables answer structurally and need no line | the `closed-sets` gate lane, with `closed-sets-selftest` planting a FOURTH answer and each of five malformed ones |
| `README.md` | the tour, and the argument for the design | |
| `CHANGELOG.md` | every user-facing change, with the reasoning | |
| `website/guide/*.md` | 16 pages of prose: concepts, run-query, spaces, atoms-terms, python-functions, define, structures, threads, observability, notebook, contract, extending-a-seat, getting-started, where-code-runs, pettorch | |
| `website/tutorials/*.md` | 9 numbered lessons, atoms through graph-view | |
| `website/integrations/*.md` | dataframes, pydantic, duckdb, SQLite blobs, arrays and embeddings, http routes | |
| `website/reasoning/*.md` | weighted relations, matchers and measure | |
| `extensions/python/examples/*/*.py` | runnable Python programs, each printing checked claims through `_common.py`: `check(label, got, expected)` raises `CheckFailed` rather than asserting, because `python -O` strips an assert while the print under it still runs, and `done(name)` refuses to print its OK line when nothing was checked, so an example that verified nothing cannot report success; the six under `gallery/` also check adjacent emitted-MeTTa and output comments plus bilingual `@example` atoms | the `examples` and `gallery` gate lanes |
| `extensions/python/notebooks/tour.ipynb` | the notebook surface, every structural argument a built term | the `notebook` lane |
| `engine/**/*.pl` | `engine/metta.pl` declares `metta_engine`, the bootstrap including the 25 `engine/metta/*.pl` units (limits, terms, operators, input_guards, types, type_aliases, type_unions, refinements, effects, completion, algebra_operations, algebra_formula, algebra_polynomial, algebra_fixpoint, space_hooks, runtime, control, interop, references, reference_sources, reference_loading, reference_refresh, properties, registration, prelude), `engine/translator.pl` compilation facade over the seven `engine/translator/*.pl` units (analysis, lowering, folding, constructors, special_forms, typing, runtime), `engine/spaces.pl` store facade over the twelve `engine/spaces/*.pl` units (catalog, lifecycle, foreign, bounded_matching, native_matching, segment_matching, generic_join, arrow_products, tokens, receipts, owned_records, vocabulary_seed); vocabulary_seed has its own module and compiles the guarded initial vocabulary atoms, `engine/filereader.pl` loader over `engine/filereader/source_lifecycle.pl`, `engine/parser.pl` reader and writer (with `engine/c/reader.c`, 949 lines of C parsing shipped-grammar sources and handing back each source's signature and declaration summaries from the same walk when `engine/reader.so` is built beside it; the Prolog grammar stays the specification, the custom-token path, and the fallback), `engine/json_codec.pl` the one JSON door this repository reads and writes through (with `engine/c/json_codec.c`, 1,219 lines of C answering a document exactly as `library(json)` answers it or declining to it, when `engine/json_codec.so` is built beside it), `engine/kernel.pl` the performance vocabulary beyond the conforming stdlib, `engine/type_rules.pl` the typing registry, `engine/translator_rules.pl` the translator rule registry, `engine/support_graph.pl` derived-artifact dependencies, plus `engine/packages.pl` the package laws every implementation owes a manifest, `engine/owned_resources.pl` the outcome-preserving release combinator it and three libraries share, `engine/specializer.pl`, `engine/duals.pl`, `engine/scc.pl`, `engine/tracer.pl`, `engine/trs.pl` and `engine/narrowing.pl` metatheory, `engine/prelude.pl` the vocabulary tier (Prolog bodies of the 37 prelude heads). Each included unit is a plain source file owned by its umbrella module. `engine/main.pl` declares `metta_main`. Engine facades declare their own module and explicit exports; `metta_engine_reexport/2` publishes the subsystem operations the host tier needs. Execution resolves through the space parents, `&self`, `prelude`, `metta_engine`, `user`, then `system` | |
| `engine/ext_points.pl` | every extension seam, each declared with its KIND in the `seam` module's multifile `kind/2`: most clauses here, the rest as `seam:kind/2` beside the unit that owns the seam (`engine/json_codec.pl`, `engine/metta/interop.pl`, `engine/metta/limits.pl`, `engine/metta/registration.pl`, `engine/support_graph.pl`). Five of them, and the count of each: `host_service` 146, `service` 96, `ownership` 41, `event` 23, `declaration` 20. Ownership, event and declaration clauses are contributed by an extension; the two service kinds are defined by the engine and called by an extension (`clauses_from/2`). `metta_space_registered/1` reflects existing native and foreign namespaces independently of their value species. `metta_with_trailed/3` restores context at each answer; `metta_with_trailed_enumeration/3` retains it until the generator finishes; `metta_with_trailed_push/3` pushes one item onto a stack-shaped root for that span. `metta_atom_index_new/1`, `metta_atom_index_bind/4` and `metta_atom_index_get/3` own temporary atom-key bindings with original values and trailed insertion. A `seam:context_reader/3` directive derives the callable reader and its inline read from one `context_reader/4` declaration. The contract for extending the engine | `ext_points.plt` |
| `lib/*/` | 60 MeTTa libraries, each a directory holding a `pkg.metta` manifest, implemented in `.metta`, `.pl`, or both; all 40 shipped Prolog halves own distinct modules with explicit exports: 37 are libraries' own `lib_*` modules, including the builtin and minimal-MeTTa ones, with local autoload tables, and 3 are the helpers under `lib/_support/` that libraries share. Libraries load with `!(import! &self (library lib_x))`; from Python the write door imports them, `m += lib.x` | `extensions/python/tests/ch08_data/test_library_door.py` |
| `lib/builtin_mods/*` | modules the engine SHIPS, imported by bare name: `!(import! &self skel)` | `builtin_modules` |
| `extensions/*/extension.pl` | one control file per seat, read when argv carries `extensions` and never read without it; a seat's `entry(engine, _)` loads only where its declared needs hold and its `entry(host, _)` is recorded for the seat's own runtime to consult, so the engine names neither a host nor a backend | |
| `extensions/node/src/*.ts` | MeTTa as a TypeScript library, the engine embedded in a Node process over the patched WebAssembly SWI-Prolog in `extensions/node/_host/` and the seam's second consumer: interned atoms, spaces as collections, lazy thenable answers, a lowered-source `define`, a traced generator `define`, host `op`s the engine calls back into, and `using` scopes. `extensions/node/bridge.pl` is its Prolog half and calls published surface only | the `node-binding` gate lane, and `extensions/python/tests/ch21_another_language_at_the_seam/test_node_binding.py` answers the same corpus in both hosts |
| `extensions/cmetta/cmetta.h`, `extensions/cmetta/cmetta.c` | the engine embedded in a C process through SWI's own foreign interface, the seam's third consumer and the only one IN the engine's process, so it reads `term_t` directly and has no wire codec. `extensions/cmetta/bridge.pl` is its Prolog half and calls published surface only | the `c-binding` gate lane, and `extensions/python/tests/ch21_another_language_at_the_seam/test_c_binding.py` requires this seat and the Python host to answer the same programs |
| `EXTENDING.md`, `DEVELOPING.md` | writing an extension; working on the engine | |
| `KERNEL.md` | every head the translator gives meaning to, core or derived, with the reason and the numbers | the `kernel-ledger` and `kernel-ledger-selftest` gate lanes |
| `website/guide/getting-started.md`, and any page writing `::: run <example>` | the site RUNS its examples. A `::: run` container around a `metta` fence renders a Run button; the first press boots one engine in a Web Worker from the site's own static assets and every press after it evaluates the fence's exact text in a space of its own. No server beyond the static host. What it cannot run: a program needing a host seat (`py-atom` and its family are refused by name before they run, because a call to one otherwise ANSWERS ITSELF), a platform library this WebAssembly build has not got (`hyperpose`, `timeout`, `git-import!`, `lib_thread`, refused by the engine's own capability census with what the absence costs), a file beside itself (only the fence's own bytes cross), or more than the fence's inference budget, 1,000,000 by default. 225 of the 258 runnable examples run in it [measured 2026-09-07] | the `docs` gate lane refuses a fence that does not name an example the corpus runner runs or whose text has drifted from that file; `test_every_run_fence_runs_the_corpus_file_it_names` asks the same without node |
| `check.sh` | the gate. `GATE_ONLY=1 sh tools/check.sh` is what CI blocks on | |
| `extensions/python/metta/*.py` | the library. `extensions/python/metta/_spaces/handle.py` is the `MeTTa` context and the `Space` handle; a leading `_` means internal | |

Seam and library counts re-measured 2026-09-14; other counts re-measured 2026-09-07. The `llms` lane derives every explicit count in
this table, checks the library roster and every backticked path, rejects names
the live engine does not know, and asks the reverse question too: every
engine-known call head the example corpus exercises must be named here.

The corpus answers the other half of that question. `corpus-coverage` reads the
engine's own callable set and `metta.library`'s carried rows and requires each
name to appear in CALL position in some example: `(name `, `(name)` or `(name`
at a line end, with full-line comments and `_fixtures/` removed first, so a
name spelled in prose proves nothing. It costs one engine boot for each of its
two sources and about eleven seconds. Its exception list is
`tests/data/corpus_coverage_allowlist.txt`, four rows today, each a name whose
TYPE makes a call meaningless -- the three Types `DontEvalType`, `FTree` and
`TP`, and the nullary constructor `FTEmpty` -- and it refuses in three
directions: an allowlisted head an example calls, an allowlisted head the
corpus never writes at all, and a row for a head nothing carries.

## Install and first call

The distribution is `pymetta` and the module it installs is `metta`, for
Python 3.12+. The engine is the Prolog one that carries the 1.0 line, and a
Rust engine will soon replace it (README.md, Architecture); the MeTTa
libraries carry over. The engine runs only on a PATCHED SWI-Prolog
(`docs/patched-host.md`), and it refuses to boot on a stock one, naming the
patches it lacks. pymetta's Linux x86_64 wheels for CPython 3.12, 3.13 and 3.14
carry that host in `metta/_host`, with the janus bridge built against it, so
there `pip install pymetta` is the whole install. Anywhere else, build the
patched host and install its janus bridge as `docs/patched-host.md` describes,
then `pip install 'pymetta[engine]'`: the `engine` extra names `janus-swi`, the
bridge, on exactly the platforms whose wheel carries no host, and the bridge
built from the patched tree already satisfies it. The engine tree,
the libraries and the codec corpus ride in every wheel. Without a bridge the
package still imports and the first engine call says what to do. The other
extras are integration packages, one row each in the extras table under
"Integrating any library"; a door whose extra is missing raises naming it. `pip install .`
from a checkout builds the pure wheel, and `METTA_PATH` points an installed
`metta` at a clone's engine tree instead of the bundled one.

Run one MeTTa file with `sh tools/run.sh path/to/program.metta`. Add `--verbose`
before the path when the program's authoring diagnostics matter, including
equation-head interpretation and source-reload reports; the default suppresses
informational messages. Python callers make the same choice with
`MeTTa(verbose=True)`.

```python
from metta import MeTTa, S, V, G, ground, Expression, equation, rules, parse, forms
from metta.vocabularies import EffectClass
context = MeTTa()                         # owns one engine context
m = context.self                          # the home Space, bound as &self
m.run("(= (f) 1) !(f) !(+ 1 2)")         # [[Grounded(1)], [Grounded(3)]]
context.close()                           # or `with MeTTa() as m:`
```

`m` in every block below is that home SPACE. The two receivers differ and the
difference is checked: a context carries the evaluation doors and forwards them
home (`run`, `eval`, `match`, `add`, `define`, `op`, `transaction`, `limits`,
`stats`, `trace`, `debug`, `space`, `close`) plus the collection protocols,
while storage and introspection stay on the space and are reached as
`context.self.atoms()` (`atoms`, `type`, `cast`, `digest`, `blame`, `source`, `save`,
`is_function`, `arities`, `builtins`, `space_names`, `lint`, `derivation`,
`effect_plan`, `subscribe`, `watch`, every declaration verb). Asking the
context for a space door raises an `AttributeError` naming `m.self`, rather
than a bare one. Two contexts are two engines' worth of state in one process,
so a library never has to own the global one.

Known issue: a long-lived process that creates and releases many contexts and
imports libraries into them can grow the engine's predicate registry with its
history, so a later import costs far more than the same import in a fresh
process. In one test run replayed in a single process (measured 2026-09-26),
the process held 7.7 million predicates, 1.55 million clauses and 4.4 GB by
its 5,255th test, and a property test creating a fresh `MeTTa()` and importing
`lib.file` for each example took about 130 s and added about 1.37 million
predicates, against 4.8 s and under 500 predicates in a fresh process. The fix
lands after this release.

Module-level `metta.run/match/eval/add/remove/parse/fn/trace` act on one lazily
created default engine, for scripts that never need a second space.

```python
metta.llms() -> None    # print THIS file to stdout, the way help() prints
```

`python -m metta llms` prints the same document from a shell. `llms.txt` ships
inside the wheel beside the engine tree, so an install answers it without a
checkout, and it never pages: the door writes and returns whatever stdout is.

`python -m metta run` is a Unix filter. The operand `-` reads the program from
standard input, and so does no operand at all; `-` with nothing else to run and
a terminal on standard input is a usage error naming `-`, rather than a
process that blocks. `--json` frames the answers as JSON Lines instead of
printing them, one object a line, `{"query": "<the ! form's own text, without
its !>", "answers": ["<atom text>", ...]}`; `--json=wire` puts the tagged wire
forms in `answers` instead, which `metta._atoms.factories._atom_from_wire` reads back, so
a number stays a number where text has only a spelling. An error is one object
a line on stderr, `{"error": "<the sentence>", "line": <the input line, or
null>}`: the reader names its line and nothing else in the engine carries a
source position, so a failure inside a `!` form answers null there. The exit
status is the one the same run without the flag gives, and the program's own
`println!` moves to stderr for the duration so the JSON stream stays
parseable. `--json` frames, it does not rerun: each operand runs exactly once,
through `load` for a file (which is a consult, so a relative `import!` resolves
against that file) and through `run` for standard input. Its extra cost is one
read of the source WITHOUT evaluating it, to pair each `!` form's text with its
group; a file that read cannot open is reported by it rather than by the run,
so the sentence for a missing file is Python's rather than the engine's.

```sh
echo '!(+ 1 2)' | python -m metta run -            # 3
python -m metta run --json prog.metta | jq -c .    # one object a line
python -m metta run --json=wire - < prog.metta     # tagged atoms in answers
```

`metta.config` is the process-wide `Config` object. Inspect all seven settings
with `config.as_dict()` and set them atomically with
`config.configure(stack_limit=..., heartbeat_interval=...,
declaration_limit=..., display_rows=..., chunk_cap=...,
subscription_queue=..., repr_items=...)`. The stack byte ceiling and Janus
heartbeat interval freeze after the first engine starts; the other five are the
`(limit ...)` rows under "Bounds" below and remain live. Set the first four
before import with `METTA_STACK_LIMIT`, `METTA_HEARTBEAT_INTERVAL`,
`METTA_DECLARATION_LIMIT`, and `METTA_DISPLAY_ROWS`; invalid or nonpositive
values stop import by name. The last three have no environment variable.

## Atoms: built in Python, no engine call

`S.likes` is the symbol `likes`; `S["+"]`, `S["my-name"]` for non-identifiers.
`V.x` is the variable `$x`. `ground(obj)` / `G(obj)` wraps a Python value.
Applying a symbol builds an expression: `S.likes(S.Ada, S.Music)` ->
`(likes Ada Music)`. `Expression` collects any iterable into one ordered
atom: `Expression((S.f, 1, 2))` is `S.f(1, 2)`.
`parse("(f $x)")` reads exactly one form without evaluating it.
`forms("(a) (b)")` reads every top-level form without evaluating any.
Root builders `if_`, `and_`, `or_`, `not_`, and `in_` spell language heads
that are Python keywords or need variadic folding without raw bracket syntax.

FOURTEEN ATTRIBUTE NAMES ON `S` ARE OPERATOR WORDS, NOT SPELLINGS. Python's
`operator` module owns these words, and `S.<word>` reaches the engine head the
word NAMES rather than a symbol spelled like the word. Thirteen reach a head
and `S.floordiv` refuses, for the reason given under the table:

| `S.<attr>` | builds | | `S.<attr>` | builds |
|---|---|---|---|---|
| `S.eq` | `==` | | `S.add` | `+` |
| `S.ne` | `!=` | | `S.sub` | `-` |
| `S.lt` | `<` | | `S.mul` | `*` |
| `S.le` | `<=` | | `S.mod` | `%` |
| `S.gt` | `>` | | `S.truediv` | `/` |
| `S.ge` | `>=` | | `S.pow` | `pow-math` |
| `S.neg` | `(- 0 x)` | | `S.floordiv` | refused, see below |

So `S.sub(a, b)` is `(- a b)`, a SUBTRACTION, and nothing downstream can tell:
it stores, matches, digests and round-trips like any other expression. If you
wanted a symbol named `sub`, the bracket door gives it exactly:
`S["sub"]` is `sub`, and `S["add"]` is `add`. That is the general rule
(brackets are exact, attributes map) applied to a case where the map is a
lookup table rather than the underscore-to-hyphen rewrite, so unlike
`S.car_atom` -> `car-atom` the name you typed is not visibly present in what
you get.

The failure this produces is quiet. A relation genuinely named `sub`, built
with `S.sub(a, b)`, is stored as arithmetic; a later query for `sub` facts
answers `[]` against a graph that obviously connects, and the first suspicion
falls on the query rather than on the write.

`S.floordiv` REFUSES rather than guessing, because its settled image is
composite (`floor-math` over `/`) and no single head spells it. `S.neg` is
composite too but settled, so it builds `(- 0 x)`.

Four kinds, all immutable with `__slots__` and one-subpattern
`__match_args__`: `Symbol`, `Variable`, `Grounded`, `Expression`. So
`match atom: case Expression([head, *args]): ...`, `case Symbol(name):`,
`case Grounded(value):` all bind.
`Expression.head`, `.args`, `.children`. Free functions in `metta._atoms.factories`:
`unify`, `substitute`, `order_key`, `arrow`, `typed`, `fresh`, `seg`, and
`register_object_repr` with its `unregister_` twin to control how a foreign
object prints as an atom. `metta.convert` owns `encode`, `decode`,
`from_wire` and `atom_from_wire`, beside the projection and cast verbs. `seg(V.rest)` is the named sequence variable and `...` the
anonymous one; the language-surface section below carries the gap rules, the
fence and the cost.
The atom's OWN methods carry the rest: `a.alpha_eq(b)` for equality modulo
variable renaming, `a.map(f)` to rewrite every subterm, `a.vars` for the
variables it contains (so `not a.vars` is the ground test), and `repr(a)` for
the laid-out reading, the same layout `(pretty-atom $x)` gives on the MeTTa
side.
The object-level round trip is `bindings = pattern.unify(fact)` followed by
`template.subs(bindings)`. Its keys are variable atoms, not their names;
`Atom.subs` also accepts a query `Row` directly.
`metta.paths.path("profile", "age", to=V.age)` occupies an opaque handle's
pattern position, reads only those live attributes after the stored match, and
binds the reached value. `metta.paths.Key("name")` selects a subscription key
instead.
`metta.spaces.object_view(obj, relation="py-field")` exposes the same object's
current public fields as `(py-field obj name value)` atoms. Pass another
relation name to avoid colliding with an application's existing facts. Compose
it with a stored space through `spaces.union`, or register it directly so
adding a field atom calls `setattr`.

Arithmetic and logic operators BUILD terms, ALWAYS, whether or not an operand
is a variable: `S.x + 1` is `(+ x 1)` and `G(2) + G(3)` is `(+ 2 3)`, not `5`.
Unwrap with `.value` when Python arithmetic is what you meant.
`&` `|` `~` build `and`/`or`/`not`, `^` builds `xor`, `<<` and `>>` build
`bit-shift-left` and `bit-shift-right`, `**` builds `pow-math`, unary `-`
builds the subtraction image `(- 0 $n)`, unary `+` answers the identical atom,
`abs()` builds `(abs-math $n)`, `math.floor`, `math.ceil`, `math.trunc` and
`round` build their `-math` heads, `@` builds the library-provided name
`matmul`, and `//` lowers through `floor-math`.
Rich COMPARISONS do not build: `a < b` and friends answer Python
booleans in the engine's own `msort` order (so atoms sort), and `a == b`
is ordinary Python equality. Comparing an atom with a plain Python value
refuses and the message names the three ways out. A comparison TERM is spelled
at the bracket door, `S[">="](V.n, 60)`, or built by `a.eq(b)`, `a.ne(b)`,
`a.lt(b)`, `a.le(b)`, `a.gt(b)` and `a.ge(b)`; `a.alpha(b)` builds
`(=alpha a b)`. `Expression.__bool__` raises on comparison
and boolean heads, so `if S[">"](V.x, 1):` is refused rather than
silently truthy.

The MeTTa `==` is `(-> $a $b Bool)`, two independent type variables, and it
asks no type question at all: it is identity of the two evaluated operands.
So `!(== 1 "S")`, `!(== True 1)` and `!(== 1 a)` all answer `False` rather
than refusing, `!(!= 1 "S")` answers `True`, and `!(== (collapse ...) ())`
compares the collapsed tuple. This engine refused a cross-type pair until
2026-08-30; nothing does now. `=alpha` carries no arrow declaration and takes
anything, comparing modulo variable renaming. Python's `a == b` answers
`False` across kinds for the same reason.

<!-- begin generated door contracts -->
## Python door contracts

`metta.doors` is the engine-free source of host door contracts. `door-sync` checks Space, the async mirror, module and context methods, remote client and operation schemas, stubs, reference, and shrink ledger against it. The same typed rows enter `&metta` at boot; `seam.publish(context)` refreshes them after registration changes.

Package doors are accessor namespaces resolved from `seam.door` rows on first access. Current workspace namespaces: `m.arrays`, `m.live`, `m.remote`, `m.tables`.

A convenience declares its base and fixed arguments. A second declaration of the same parameter point on one receiver is refused. Ownership and rollback operations keep their implementation contracts.

| convenience | longhand |
|---|---|
| `space:answers` | `space:eval(..., answer='answers')` |
| `space:one` | `space:eval(..., answer='one', delivery='values', on_error='abort')` |
| `space:first` | `space:eval(..., answer='first', delivery='values', on_error='abort')` |
| `space:pure` | `space:op(..., effect='pureStructural')` |
| `space:reads` | `space:op(..., effect='readOnlyLookup')` |
| `space:writes` | `space:op(..., effect='writesState')` |
| `space:io` | `space:op(..., effect='oracleIO')` |
| `tables:to-df` | `rows:to(..., library='pandas')` |
| `rows:to-df` | `rows:to(..., library='pandas')` |
| `answers:to-df` | `answers:to(..., library='pandas')` |
| `tables:to-pl` | `rows:to(..., library='polars')` |
| `rows:to-pl` | `rows:to(..., library='polars')` |
| `answers:to-pl` | `answers:to(..., library='polars')` |

The declarations below omit the implicit receiver. Hyphens in a MeTTa-facing door name become underscores in Python. A namespace entry `tables:add` is called as `m.tables.add(...)`; a context entry belongs to `MeTTa`. The detailed contracts, input types, delivery, refusal witnesses and tests are in `website/reference/python-door-contracts.md`.

### space declarations

`space:eval`: `evaluation`, returns `value`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`, `module`, `context`.

```python
@overload
eval(target: Any, /, *more: Any, timeout: float | None=None, inferences: int | None=None, under: Any=_UNSET, theory: Any | None=None, interpreter: Any | None=None, answer: EvaluationAnswer | str='all', delivery: ArgumentDelivery | str, limit: int | None=None, image: ImageMode | str | None=None, on_error: OnError | str='keep', determinism: Determinism | str='nondet', **values: Any) -> Any
@overload
eval(target: Any, /, *more: Any, timeout: float | None=None, inferences: int | None=None, under: Any=_UNSET, theory: Any | None=None, interpreter: Any | None=None, answer: EvaluationAnswer | str, delivery: ArgumentDelivery | str='atoms', limit: int | None=None, image: ImageMode | str | None=None, on_error: OnError | str='keep', determinism: Determinism | str='nondet', **values: Any) -> Any
@overload
eval(target: Any, /, *, timeout: float | None=..., inferences: int | None=..., under: Any=..., theory: Any | None=..., interpreter: Any | None=..., **values: Any) -> list[Atom | Undefined]
@overload
eval(target: Any, _second: Any, /, *more: Any, timeout: float | None=..., inferences: int | None=..., under: Any=..., theory: Any | None=..., interpreter: Any | None=..., **values: Any) -> list[list[Atom | Undefined]]
eval(target: Any, /, *more: Any, timeout: float | None=None, inferences: int | None=None, under: Any=_UNSET, theory: Any | None=None, interpreter: Any | None=None, answer: EvaluationAnswer | str='all', delivery: ArgumentDelivery | str='atoms', limit: int | None=None, image: ImageMode | str | None=None, on_error: OnError | str='keep', determinism: Determinism | str='nondet', **values: Any) -> Any
```

Evaluate a term, returning every answer.

- `answer`: `all`, `answers`, `rows`, `atom`, `one`, `first`, `count`, `exists`, `none`, `stream`.
- `delivery`: `atoms`, `values`.
- `image`: `opaque`, `transparent`, `auto`.
- `on_error`: `keep`, `empty`, `abort`.
- `determinism`: `det`, `semidet`, `nondet`.

`space:answers`: `evaluation`, returns `Answers`, effect `oracleIO`, determinism `nondet`; tiers `sync`.

```python
answers(target: Any, /, *, timeout: float | None=None, inferences: int | None=None, under: Any=_UNSET, theory: Any | None=None, interpreter: Any | None=None, **values: Any) -> _root.Answers[Any]
```

Evaluate as an immutable, cached and replayable view.

`space:parallel`: `evaluation`, returns `list`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`.

```python
parallel(*targets: Any, timeout: float | None=None) -> list[Atom | Undefined]
```

Evaluate every target concurrently, answering every branch's answers.

`space:pool`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`.

```python
pool(workers: int | None=None) -> Any
```

A pool of worker threads that each hold their own Prolog engine.

`space:reducible`: `introspection`, returns `bool`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
reducible(target: Any) -> bool
```

Whether a head reduces here, asked without evaluating anything.

`space:eval-status`: `evaluation`, returns `list`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`.

```python
eval_status(target: Any, /, *, timeout: float | None=None, inferences: int | None=None, theory: Any | None=None, interpreter: Any | None=None, **values: Any) -> list[tuple[str, Atom | Undefined | None]]
```

Evaluate a term, pairing each answer with how it was produced.

`space:run-status`: `evaluation`, returns `list`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`.

```python
run_status(source: str, *, timeout: float | None=None, inferences: int | None=None) -> list[list[tuple[str, Atom | Undefined | None]]]
```

run(), with each directive's answers paired with how they arose.

`space:one`: `evaluation`, returns `value`, effect `oracleIO`, determinism `det`; tiers `async`.

```python
one(target: Any, *, timeout: float | None=None, inferences: int | None=None) -> Any
```

Return the sole answer as a plain Python value for internal callers.

`space:first`: `evaluation`, returns `value`, effect `oracleIO`, determinism `det`; tiers `async`.

```python
first(target: Any, *, timeout: float | None=None, inferences: int | None=None) -> Any
```

The first answer as a plain Python value, or None for no answers.

`space:name`: `introspection`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
name -> _SpaceId
```

The live engine name represented by this handle.

`space:self`: `introspection`, returns `space`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
self -> Self
```

The space this receiver's doors work in, which for a space is itself.

`space:space-names`: `introspection`, returns `list`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
space_names() -> list[str]
```

Every space name this engine registers, sorted: '&self' and

`space:drop`: `lifecycle`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
drop() -> None
```

Clear this space and release its owned resources.

`space:dropped`: `lifecycle`, returns `bool`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
dropped -> bool
```

Whether this handle's space has been released, by any party.

`space:to-wire`: `introspection`, returns `list`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
to_wire() -> list
```

Encode the live engine reference as a portable space operand.

`space:metatype`: `introspection`, returns `str`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
metatype -> str
```

Read Space.metatype.

`space:bind`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
bind(values: _abc.Mapping[str, Any] | None=None, /, **named: Any) -> _spaces_scope_module._BoundValues
```

Scope named host values for :meth:`run` without a call flag.

`space:runtime`: `introspection`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
runtime -> Runtime
```

The engine bridge itself, for callers going under the surface.

`space:metta`: `introspection`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
metta -> _root.MeTTa
```

The owning evaluation context, so a handle can reach every

`space:alpha`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
alpha(other: Any) -> Expression
```

The alpha-equality TERM, (=alpha self other); alpha_eq answers now.

`space:alpha-eq`: `introspection`, returns `bool`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
alpha_eq(other: Atom) -> bool
```

Whether two atoms differ only by consistent variable renaming.

`space:args`: `introspection`, returns `tuple`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
args -> tuple[Atom, ...]
```

Read Space.args.

`space:children`: `introspection`, returns `tuple`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
children -> tuple[Atom, ...]
```

Read Space.children.

`space:eq`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
eq(other: Any) -> Expression
```

The equality TERM, (== self other); == itself compares atoms.

`space:ge`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
ge(other: Any) -> Expression
```

The greater-or-equal TERM, (>= self other).

`space:gt`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
gt(other: Any) -> Expression
```

The strictly-greater TERM, (> self other).

`space:head`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
head -> Atom | None
```

Read Space.head.

`space:le`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
le(other: Any) -> Expression
```

The less-or-equal TERM, (<= self other).

`space:lt`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
lt(other: Any) -> Expression
```

The strictly-less TERM, (< self other).

`space:map`: `introspection`, returns `Atom`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
map(transform: Callable[[Atom], Atom]) -> Atom
```

Transform every node, children before parents, without recursion.

`space:ne`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
ne(other: Any) -> Expression
```

Read Space.ne.

`space:subs`: `introspection`, returns `Atom`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
subs(bindings: Mapping[Atom, Any] | Any) -> Atom
```

Replace each atom the bindings name, everywhere it occurs.

`space:unify`: `introspection`, returns `mapping`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
unify(other: Atom, *more: Atom) -> Mapping[Atom, Atom] | None
```

Unify with the others, returning bindings or ``None``.

`space:vars`: `introspection`, returns `tuple`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
vars -> tuple[Variable, ...]
```

The variables in first-appearance order; none means ground.

`space:value`: `introspection`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
value -> Any
```

The inherited payload slot remains unset: a Space is a Handle, and reading value raises AttributeError.

`space:profile`: `introspection`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
profile(source: str | TemplateLike, /, *, timeout: float | None=None, inferences: int | None=None, **values: Any) -> tuple[list[list[Atom]], EngineProfile]
```

Run source under the engine's statistical profiler, answering

`space:profile-extension`: `introspection`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
profile_extension(source: str | TemplateLike, /, *, extension: str | None=None, names: _abc.Sequence[str] | None=None, timeout: float | None=None, inferences: int | None=None, **values: Any) -> tuple[list[list[Atom]], list[FunctionCost]]
```

Run source under the profiler, reporting only YOUR functions.

`space:stats`: `introspection`, returns `context`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
stats() -> _StatsBlock
```

The engine's own counters over a with-block, as deltas.

`space:get-property`: `introspection`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
get_property(head: str | Symbol, /) -> tuple[Atom, ...]
```

Return visibility, origins and declared properties of a head.

`space:match`: `query`, returns `value`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`, `module`, `context`.

```python
match(*patterns: Any, where: Any | None=None, limit: int | None=None, timeout: float | None=None, inferences: int | None=None, under: Any=_UNSET, into: _builtins.type | None=None, derivations: bool | None=None, **values: Any) -> Any
```

Lazily match patterns against this space as one conjunction.

`space:stream`: `query`, returns `stream`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`.

```python
stream(*patterns: Any, where: Any | None=None, limit: int | None=None, timeout: float | None=None, inferences: int | None=None, under: Any=_UNSET) -> _spaces_cursor_module.Cursor
```

match(), pulled: the same conjunction and guard, answered one

`space:solve`: `evaluation`, returns `value`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`, `module`, `context`.

```python
solve(pattern: Any, subject: Any) -> Any
```

Run relational ``let`` and return bindings keyed by its variables.

`space:prepare`: `query`, returns `value`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
prepare(*patterns: Any, where: Any | None=None) -> Prepared
```

A query whose shape is fixed and whose facts are not: the wire

`space:assuming`: `scope`, returns `context`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
assuming(*facts: Any) -> _Assuming
```

Facts held only inside a with-block: the assumptions reading of

`space:transaction`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
@overload
transaction(target: Callable[[], _R], /) -> _R
@overload
transaction(target: Atom | str, /) -> list[Atom | Undefined]
transaction(target: Callable[[], _R] | Any, /) -> Any
```

Run one callable or term inside a closed engine transaction.

`space:limits`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
limits(*, timeout: float | None=None, inferences: int | None=None, stack: int | None=None) -> ScopedLimits
```

Scoped default bounds for every call in the with-block:

`space:capture`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
capture() -> _spaces_execution_module.CapturedOutput
```

Collect printed engine text without changing answer shapes.

`space:scope`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
scope() -> _root.parallel.Scope
```

Join children and release resources created in this block.

`space:atomic`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
atomic() -> _spaces_execution_module.ScopedExecution
```

Make each CALL in the block one committing engine transaction.

`space:speculative`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
speculative() -> _spaces_execution_module.ScopedExecution
```

Run each CALL against a snapshot and discard its writes.

`space:batch`: `scope`, returns `context`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
batch() -> _Batch
```

Collect this space's add() calls and cross once at exit:

`space:transactional`: `scope`, returns `callable`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
transactional(fn: Callable[_P, _R], /) -> Callable[_P, _R]
```

transaction()'s decorator twin, the atomic shape Django made

`space:run`: `evaluation`, returns `list`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`, `module`, `context`.

```python
run(source: str | TemplateLike, /, *, timeout: float | None=None, inferences: int | None=None, **values: Any) -> list[list[Atom]]
```

Run MeTTa source: one list of answers per ! directive.

`space:save`: `introspection`, returns `int`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
save(path: str | os.PathLike[str], *, format: SaveFormat=SaveFormat.metta, timeout: float | None=None, inferences: int | None=None) -> int
```

Write the authored atoms of this space, equations included, as

- `format`: `metta`, `fast`.

`space:source`: `introspection`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
source() -> str
```

Return this space's authored atoms as loadable MeTTa text.

`space:load`: `introspection`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
load(path: str | os.PathLike[str], *, timeout: float | None=None, inferences: int | None=None) -> list[list[Atom]]
```

Add a text program or trusted fast cache to this space.

`space:parse`: `introspection`, returns `Atom`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
parse(source: str | TemplateLike, /, **values: Any) -> Atom
```

Read one form into an atom without evaluating it.

`space:register-token`: `provider`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
register_token(pattern: str | _re.Pattern[str], constructor: Callable[[str], Any]) -> None
```

Register a full-token regex and its Atom constructor.

`space:unregister-token`: `provider`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
unregister_token(pattern: str | _re.Pattern[str]) -> None
```

Remove a reader-token class; an absent pattern is already removed.

`space:-repr-html-`: `introspection`, returns `str`, effect `readOnlyLookup`, determinism `det`; tiers `sync`.

```python
_repr_html_() -> str
```

Show this space's loadable MeTTa source in rich notebooks.

`space:add`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
add(*atoms: Any) -> None
```

Add atoms to this space, one engine round-trip for the lot.

`space:from-`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
from_(source: Any, map: Any=None) -> None
```

Reference a library or space through a stored ``(from source map)`` row.

`space:remove`: `write`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
remove(atom: Any, *more: Any) -> bool | int
```

Remove ONE unifying occurrence and say whether one was there,

`space:transfer`: `write`, returns `int`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
transfer(*atoms: Any, to: _root.Space) -> int
```

Move ONE unifying occurrence of each atom into another space.

`space:atoms`: `introspection`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
atoms() -> list[Atom]
```

Every stored atom in this space.

`space:peek`: `query`, returns `Atom`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`.

```python
peek(pattern: Any, *, where: Any | None=None, deadline: float | None=None) -> Atom
```

Wait for one matching atom and leave it in this space.

`space:take`: `write`, returns `Atom`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
take(pattern: Any, *, where: Any | None=None, deadline: float | None=None) -> Atom
```

Wait for and remove exactly one matching atom from this space.

`space:cast`: `introspection`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
@overload
cast(type_: _builtins.type[_CastT], /) -> _CastT
@overload
cast(type_: Atom | str, /) -> Any
@overload
cast(value: Any, type_: _builtins.type[_CastT], /) -> _CastT
@overload
cast(value: Any, type_: Atom | str, /) -> Any
cast(value: Any, type_: Any=..., /) -> Any
```

Cast this space atom ambiently with one argument, or answer value

`space:copy`: `lifecycle`, returns `space`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
copy() -> _root.Space
```

This space's contents in a new anonymous space, restored the way

`space:digest`: `introspection`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
digest() -> str
```

A sha256 hex digest of this space's content: every stored atom,

`space:__len__`: `introspection`, returns `int`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__len__() -> int
```

Read Space.__len__.

`space:__bool__`: `introspection`, returns `bool`, effect `pureStructural`, determinism `det`; tiers `sync`, `context`.

```python
__bool__() -> bool
```

Always true: a space is a handle to a store, not a value that

`space:__contains__`: `introspection`, returns `bool`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__contains__(atom: Any) -> bool
```

Read Space.__contains__.

`space:clear`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
clear() -> None
```

Remove everything stored here, compiled equations included.

`space:__iadd__`: `write`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__iadd__(atom: Any) -> _SpaceT
```

add()'s operator spelling for one atom or one fact stream.

`space:__isub__`: `write`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__isub__(atom: Any) -> _SpaceT
```

Read Space.__isub__.

`space:__ior__`: `write`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__ior__(other: Any) -> _SpaceT
```

Merge into this space in one bulk crossing: every atom of

`space:__iter__`: `introspection`, returns `stream`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__iter__()
```

Iterate one assembly-order snapshot of the stored atoms.

`space:__getitem__`: `introspection`, returns `Rows`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__getitem__(i: Any) -> _root.Rows
```

Subscription is query. A tuple headed by an atom is one built

`space:__delitem__`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
__delitem__(pattern: Any) -> None
```

Del m[pattern] removes every unifying occurrence, the bulk

`space:watch`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
watch(pattern: Any, *, on: SubscriptionEdge=SubscriptionEdge.add, where: Any | None=None, deadline: float | None=None, queue_max: int | None=None)
```

Yield matching changes, raising Timeout after each quiet deadline.

- `on`: `add`, `remove`, `both`.

`space:subscribe`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
subscribe(pattern: Any, callback: Callable | None=None, *, on: SubscriptionEdge=SubscriptionEdge.add, where: Any | None=None, queue_max: int | None=None)
```

A standing query on this space: every added (or removed, or

- `on`: `add`, `remove`, `both`.

`space:integrate`: `provider`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
integrate(target: Any) -> str
```

Install a library integration; see metta.integrate.

`space:handles`: `provider`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
handles(pattern: str | Atom, fidelity: Fidelity, *, det: Determinism | None=None) -> Atom
```

Declare how faithfully a space answers queries of one shape.

- `fidelity`: `Exact`, `Partial`, `Sound`, `Refuse`.
- `det`: `det`, `semidet`, `nondet`.

`space:annotations`: `provider`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
annotations(subject_or_algebra: str, algebra: str | None=None, *, capabilities: _abc.Iterable[str]=()) -> Atom
```

Declare the algebra a context's answer annotations live in.

`space:algebra`: `provider`, returns `Atom`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
algebra(name: str, *, combine: str, extend: str, zero: Any, one: Any, laws: _abc.Iterable[str]=(), carrier: _abc.Iterable[Any]=(), type: Any=None, requires: _abc.Iterable[str]=(), order: SemiringOrder | None=None, negate: Any=None, saturated: Any=None, variable: Any=None) -> Atom
```

Declare operations with carrier membership and optional checked laws.

- `order`: `ascending`, `descending`.

`space:covers`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
covers(effect: EffectClass | str) -> Atom
```

Declare the strongest effect this reified world can handle.

- `effect`: `pureStructural`, `readOnlyLookup`, `nondeterministicReadOnly`, `writesState`, `oracleIO`.

`space:compensates`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
compensates(operation: str, compensation: str) -> Atom
```

Declare one recovery operation for an effectful operation.

`space:add-tagged-fact`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
add_tagged_fact(tag: Any, proposition: Any) -> Atom
```

Store ``(fact tag proposition)``, the normative annotation form.

`space:add-tagged-rule`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
add_tagged_rule(tag: Any, head: Any, *premises: Any, where: Any=None) -> Atom
```

Store one rule generated by the algebra-agnostic tag threader.

`space:image`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
image(type_name: str, setting: ImageMode) -> Atom
```

Choose how one Python type crosses one context boundary.

- `setting`: `opaque`, `transparent`, `auto`.

`space:sample`: `evaluation`, returns `list`, effect `oracleIO`, determinism `nondet`; tiers `sync`, `async`.

```python
sample(query: str | Atom, *, k: int=10, seed: int=7) -> list[Atom]
```

Choose ``k`` tagged alternatives with replacement by ``(rate n)``.

`space:consumption`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
consumption(kind: SourceKind) -> Atom
```

Declare a space's consumption discipline.

- `kind`: `linear`, `repeated`, `peek`.

`space:on-error`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
on_error(subject_or_pattern: str | Atom, pattern_or_mode: str | Atom, mode: OnError | None=None) -> Atom
```

Declare what a context's failure becomes, per query shape.

- `mode`: `keep`, `empty`, `abort`.

`space:merge`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
merge(pattern: str | Atom, policy: AnswerPolicy) -> Atom
```

Declare how the engine merges one query shape's answers

- `policy`: `depth`, `fair`, `best-first`.

`space:context`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
context(world: World) -> Atom
```

Record what a space's absence means.

- `world`: `closed-world`, `open-world`.

`space:agenda`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
agenda(policy: AgendaPolicy, function: str | None=None) -> Atom
```

Declare which reaction fires first when several match one write.

- `policy`: `declaration`, `recency`, `specificity`, `priority`, `user`.

`space:reacts`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
reacts(pattern: str | Atom, operation: str | Atom, priority: int | None=None) -> Atom
```

Declare a reaction, stored as an (on ...) atom: when an atom

`space:admits`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
admits(type_name: str) -> Atom
```

Type a pool's membership: only TYPE-carrying atoms enter.

`space:capacity`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
capacity(limit: int) -> Atom
```

Bound a pool: an add beyond LIMIT atoms is refused loudly.

`space:atomicity`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
atomicity(atomicity: Atomicity) -> Atom
```

Declare what a space's writes promise inside a transaction.

- `atomicity`: `transactional`, `atomic-single`, `best-effort`.

`space:emits`: `write`, returns `Atom`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
emits(policy: AnswerPolicy) -> Atom
```

Declare the order a context emits its own answers in.

- `policy`: `depth`, `fair`, `best-first`.

`space:events`: `write`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
events(delivery: Delivery | None=None, order: EventOrder=EventOrder.unordered) -> Atom | Any
```

Return the event stream, or declare what this context promises.

- `delivery`: `at-most-once`, `at-least-once`, `per-write-exactly`.
- `order`: `ordered`, `unordered`.

`space:define`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
@overload
@dataclass_transform(eq_default=False)
define(fn: _builtins.type[_T], /, *, accessors: bool=..., methods: bool=...) -> _builtins.type[_T]
@overload
define(fn: Callable[_P, _R], /, *, name: str | None=..., accessors: bool=..., methods: bool=...) -> _root.Defined[_P, _R]
@overload
define(*, name: str) -> Callable[[Callable[_P, _R]], _root.Defined[_P, _R]]
@overload
define(*, prolog: str | os.PathLike[str], name: str | None=None) -> Callable[[Callable[_P, _R]], _declare_define_module.PrologBacked[_P, _R]]
define(fn: Callable[..., Any] | None=None, *, prolog: str | os.PathLike[str] | None=None, name: str | None=None, accessors: bool=True, methods: bool=True) -> Any
```

Compile a Python function into MeTTa equations, decorator-style.

`space:rules`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
rules(fn: Callable[..., Any]) -> _declare_rules_module.Rules
```

Collect and land a non-exclusive equation bundle in this space.

`space:pre-add`: `write`, returns `callable`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
pre_add(fn: _root.Defined[..., Any] | Callable[..., Any]) -> _root.Defined[..., Any]
```

Compile or accept one unary judge and claim this space's write hook.

`space:type`: `introspection`, returns `Atom`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
type(atom: Any) -> Atom
```

Return this space's first ``get-type`` answer, including undefined.

`space:infer-types`: `write`, returns `list`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
infer_types(*, declare: bool=False) -> list[Atom]
```

Propose a `(: head (-> ...))` for every head here that has none.

`space:doc`: `introspection`, returns `Atom`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
doc(atom: Any) -> Atom
```

Return this space's structured ``get-doc`` answer for one subject.

`space:builtins`: `introspection`, returns `list`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
builtins() -> list[str]
```

Every function callable from this space, plus every special form.

`space:is-function`: `introspection`, returns `bool`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
is_function(name: str) -> bool
```

Report whether the name is registered as a function anywhere.

`space:is-function-here`: `introspection`, returns `bool`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
is_function_here(name: str) -> bool
```

Whether a function would answer from THIS space: it has clauses

`space:arities`: `introspection`, returns `list`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
arities(name: str) -> list[int]
```

Compiled predicate arities for a name: MeTTa arity plus one each.

`space:fn`: `introspection`, returns `value`, effect `readOnlyLookup`, determinism `det`; tiers `sync`.

```python
fn -> _FunctionNamespace
```

Functions visible here, as bound attribute or exact-name handles.

`space:op`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
@overload
op(fn: Callable[_P, _R], /, *, name: str | None=..., transport: Transport=..., effect: EffectClass | str, declarations: Iterable[Atom]=..., arities: list[int] | None=..., inverse: Callable | None=...) -> Callable[_P, _R]
@overload
op(*, name: str | None=..., transport: Transport=..., effect: EffectClass | str, declarations: Iterable[Atom]=..., arities: list[int] | None=..., inverse: Callable | None=...) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]
op(fn: Callable | None=None, *, name: str | None=None, transport: Transport='encoded', effect: EffectClass | str | None=None, declarations: Iterable[Atom]=(), arities: list[int] | None=None, inverse: Callable | None=None) -> Any
```

Register a Python callable as a MeTTa function, decorator-style.

- `effect`: `pureStructural`, `readOnlyLookup`, `nondeterministicReadOnly`, `writesState`, `oracleIO`.

`space:pure`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
pure(fn: Callable | None=None, /, **options: Any) -> Any
```

An operation whose answer depends only on its arguments.

`space:reads`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
reads(fn: Callable | None=None, /, **options: Any) -> Any
```

An operation that reads stable state without changing it.

`space:writes`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
writes(fn: Callable | None=None, /, **options: Any) -> Any
```

An operation that changes engine or host state.

`space:io`: `provider`, returns `value`, effect `writesState`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
io(fn: Callable | None=None, /, **options: Any) -> Any
```

An operation that observes an external oracle.

`space:unregister-op`: `provider`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
unregister_op(name: str) -> None
```

Remove a registered operation, every arity of it.

`space:register-prolog`: `provider`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
register_prolog(source: str | None=None, *, path: str | os.PathLike[str] | None=None, names: _abc.Sequence[str] | _abc.Mapping[str, str]=()) -> tuple[str, ...]
```

Register Prolog predicates as MeTTa functions, at native speed.

`space:register-foreign-library`: `provider`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
register_foreign_library(path: str | os.PathLike[str], *, entry: str | None=None, names: _abc.Sequence[str]=()) -> tuple[str, ...]
```

Load a compiled `.so` and register its predicates as MeTTa functions.

`space:register-library-path`: `provider`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
register_library_path(directory: Any, name: str) -> None
```

Point MeTTa at a directory of files your package ships.

`space:unregister-prolog`: `provider`, returns `tuple`, effect `writesState`, determinism `det`; tiers `sync`, `async`.

```python
unregister_prolog(extension: str) -> tuple[str, ...]
```

Release everything one extension registered, and its clauses.

`space:prolog`: `introspection`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
prolog() -> None
```

Drop into the engine's own interactive Prolog toplevel, the

`space:debug`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
debug(source: Atom | str, *, on: Any=None, inferences: int | None=None, at: int | None=None) -> Debugger
```

Run a TERM, or source, under breakpoints, stepped from Python.

`space:explain`: `introspection`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
explain(query: Any, /, *, analyze: bool=False, allow_writes: bool=False, **values: Any) -> Explanation
```

What the engine will do with this query, reflected rather than run.

`space:effect-plan`: `introspection`, returns `value`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
effect_plan(target: Any) -> _ops_module.EffectPlan
```

Return operations the target may execute and their joined effect.

`space:derivation`: `introspection`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
derivation(target: Any, depth: int | None=None, *, timeout: float | None=None, inferences: int | None=None) -> list[Any]
```

Every proof of an answer, as trees in MeTTa terms.

`space:why`: `introspection`, returns `str`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
why(pattern: Any, *, where: Any | None=None) -> str
```

Why a pattern matches nothing here, in words.

`space:record`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
record(source: Atom | str, *, seed: int | None=None, max_events: int | None=None, timeout: float | None=None, inferences: int | None=None) -> Recording
```

Run a TERM, or source, and keep the whole run as data.

`space:trace`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`, `module`, `context`.

```python
trace(source: Atom | str, max_events: int | None=None, *, filter: Symbol | str | Iterable[Symbol | str] | None=None, timeout: float | None=None, inferences: int | None=None) -> Trace
```

Run a TERM, or source, under the engine's reduction trace and

`space:lint`: `introspection`, returns `list`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `async`.

```python
lint() -> list[Finding]
```

Diagnose this space for the silently-wrong class: declared

`space:saga`: `scope`, returns `context`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
saga(receipts: _space_face.Space)
```

Open a committed-receipt saga over this execution space.

`space:reify`: `lifecycle`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
reify()
```

Capture this space as an immutable, independently evaluable world.

`space:commit`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
commit(world: Any) -> None
```

Apply one reified world's diff through this originating space.

`space:blame`: `introspection`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`, `async`.

```python
blame(atom: Any) -> list[Atom]
```

Return each matching occurrence's ``(t actor generation)`` identity.

### context declarations

`context:close`: `lifecycle`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
close() -> None
```

Release the context's own home space; closing twice is a no-op.

`context:closed`: `lifecycle`, returns `bool`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
closed -> bool
```

Whether :meth:`close` has released this context's own home.

`context:self`: `introspection`, returns `space`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
self -> _root.Space
```

The context's home space handle, its own ``&self``.

`context:runtime`: `introspection`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
runtime -> Runtime
```

The engine bridge itself, for callers going under the surface.

`context:info`: `introspection`, returns `mapping`, effect `readOnlyLookup`, determinism `det`; tiers `sync`.

```python
info() -> dict[str, str | int | None]
```

Return backend versions and the consulted MeTTa runtime tree.

`context:lock`: `introspection`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
lock() -> _root.Lock
```

Pin the knowledge this context has loaded, as a `Lock`.

`context:check`: `introspection`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
check(lock: _root.Lock) -> list[_root.Drift]
```

Every entry of a lock this tree no longer matches, as `Drift` rows.

`context:space`: `lifecycle`, returns `space`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
space(name: str | Symbol | Expression | _root.Space | None=None, backing: Any=None, *, inherits: _root.Space | None=None, restricted: bool=False, grants: _abc.Iterable[str]=(), journal: str | os.PathLike[str] | None=None, schema: _abc.Mapping[str, Any] | None=None, sync: JournalSync=JournalSync.none, rename: _abc.Mapping[str, str] | None=None, _created_at: tuple[str, int] | None=None) -> _root.Space
```

Create one native, provider-backed, remote, or journaled space.

- `sync`: `none`, `flush`, `close`.

`context:fn`: `introspection`, returns `value`, effect `readOnlyLookup`, determinism `det`; tiers `sync`.

```python
fn -> _declare.functions._FunctionNamespace
```

The bound function namespace of this context's self space.

`context:unregister-op`: `provider`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`.

```python
unregister_op(name: str) -> None
```

Release an operation installed through :meth:`op`.

`context:capture`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`.

```python
capture() -> _spaces_execution.CapturedOutput
```

Capture printed engine text across this context.

`context:atomic`: `scope`, returns `context`, effect `writesState`, determinism `det`; tiers `sync`.

```python
atomic() -> _spaces_execution.ScopedExecution
```

Scope source execution to committing transactions.

`context:scope`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
scope() -> _root.parallel.Scope
```

Own this block's children through the home space's library scope.

`context:transaction`: `scope`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
@overload
transaction(target: Callable[[], _R], /) -> _R
@overload
transaction(target: Atom | str, /) -> list[Atom | Undefined]
transaction(target: Any, /) -> Any
```

Run one callable or term in an engine transaction.

`context:register-prolog`: `provider`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
register_prolog(*args: Any, **kwargs: Any) -> tuple[str, ...]
```

Install a declared Prolog extension.

`context:register-foreign-library`: `provider`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
register_foreign_library(*args: Any, **kwargs: Any) -> tuple[str, ...]
```

Install a compiled SWI foreign library.

`context:register-library-path`: `provider`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
register_library_path(directory: Any, name: str) -> None
```

Register one named Prolog library directory.

`context:unregister-prolog`: `provider`, returns `tuple`, effect `writesState`, determinism `det`; tiers `sync`.

```python
unregister_prolog(extension: str) -> tuple[str, ...]
```

Release one declared Prolog extension.

`context:prolog`: `introspection`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
prolog() -> None
```

Enter SWI-Prolog's interactive toplevel.

### rows declarations

`rows:insert`: `write`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`.

```python
insert(i: int, item: Iterable[Any]) -> None
```

Read Rows.insert.

`rows:append`: `write`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`.

```python
append(item: Iterable[Any]) -> None
```

Read Rows.append.

`rows:extend`: `write`, returns `None`, effect `writesState`, determinism `det`; tiers `sync`.

```python
extend(other: Iterable[Iterable[Any]]) -> None
```

Read Rows.extend.

`rows:copy`: `query`, returns `Rows`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
copy() -> Rows
```

Read Rows.copy.

`rows:column`: `query`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
column(name: str) -> Column
```

Project one exact column name.

`rows:group-by`: `query`, returns `mapping`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
group_by(column: str) -> dict[Atom, Rows]
```

Group rows by the atom in one exact column.

`rows:first`: `query`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
first(*, default: Any=_MISSING) -> Row | Any
```

Return the first row, or the caller's explicit default.

`rows:one`: `query`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
one(*, default: Any=_MISSING) -> Row | Any
```

Return the sole row, using an explicit default only for absence.

`rows:raise-for-errors`: `query`, returns `value`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
raise_for_errors() -> Self
```

Raise when any cell carries an `(Error ...)` atom; answer self

`rows:why`: `query`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
why() -> str
```

Explain why this eager query returned no rows.

`rows:explain`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
explain(*, analyze: bool=False, allow_writes: bool=False) -> _spaces_profile.Explanation
```

What the engine did with the query that produced these rows.

`rows:build`: `query`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
@overload
build[BuildT](cls: type[BuildT], /) -> list[BuildT]
@overload
build[BuildT](column: str, cls: type[BuildT]) -> list[BuildT]
build(column: str | type, cls: type | None=None) -> list
```

Rebuild constructor atoms through the two-way translator.

`rows:into`: `query`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
into(cls: type) -> list
```

Each row as one ``cls``, matched to named constructor inputs.

`rows:to-dicts`: `query`, returns `list`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
to_dicts() -> list[dict[str, Any]]
```

Return one Python-native column-to-value mapping per row.

`rows:table`: `query`, returns `mapping`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
table() -> dict[str, list[Any]]
```

The columns as a dict of plain values, the one shape every

`rows:arrow`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
arrow() -> ArrowView
```

These rows wearing nothing but the Arrow protocol.

`rows:to`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
to(library: Any)
```

These rows as a frame of `library`: the general frame door.

`rows:pipe`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
pipe(fn: Callable[..., Any], *args: Any, **kwargs: Any) -> Any
```

fn(self, *args, **kwargs), pandas' chaining shape, so a

`rows:render`: `query`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
render(source: Any, /, **values: Any) -> str
```

These rows through a template, as text: `metta.render` with `rows` bound.

`rows:to-df`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
@staticmethod
to_df() -> Any
```

These rows as a pandas DataFrame; the declared point rows.to('pandas').

`rows:to-pl`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
@staticmethod
to_pl() -> Any
```

These rows as a polars DataFrame; the declared point rows.to('polars').

### answers declarations

`answers:columns`: `query`, returns `tuple`, effect `pureStructural`, determinism `det`; tiers `sync`.

```python
columns -> tuple[str, ...]
```

Caller-variable names available for projection.

`answers:index`: `query`, returns `int`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
index(value: T, start: int=0, stop: int | None=None) -> int
```

Return a row position, with a remedy for column-name collisions.

`answers:column`: `query`, returns `Answers`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
column(name: str) -> Answers[Any]
```

Project one exact caller-variable column.

`answers:group-by`: `query`, returns `mapping`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
group_by(column: str) -> dict[Atom, Rows]
```

Materialize binding rows grouped by one atom-valued column.

`answers:rows`: `query`, returns `Answers`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
rows -> Answers[Row]
```

The caller-binding row paired with each evaluation answer.

`answers:into`: `query`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
into(cls: type) -> list
```

Materialize, then convert through Rows.into.

`answers:build`: `query`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
build(*args: Any) -> list[Any]
```

Materialize, then rebuild one column through Rows.build.

`answers:to-dicts`: `query`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
to_dicts() -> list[dict[str, Any]]
```

Materialize as plain column-to-value records.

`answers:table`: `query`, returns `mapping`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
table() -> dict[str, list[Any]]
```

Materialize as a column mapping.

`answers:to`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
to(library: Any)
```

Materialize, then build a frame of `library`: Rows.to.

`answers:arrow`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
arrow() -> ArrowView
```

These answers wearing nothing but the Arrow protocol.

`answers:pipe`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
pipe(fn: Callable[..., Any], *args: Any, **kwargs: Any) -> Any
```

Materialize and pass the eager Rows face to ``fn``.

`answers:raise-for-errors`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
raise_for_errors() -> Self
```

Raise stored error cells after materializing the row view.

`answers:why`: `query`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
why() -> str
```

Explain an empty query after materializing it.

`answers:explain`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
explain(*, analyze: bool=False, allow_writes: bool=False) -> _spaces_profile.Explanation
```

What the engine did with the query behind this view, pulling nothing.

`answers:render`: `query`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
render(source: Any, /, **values: Any) -> str
```

These answers through a template, as text: `Rows.render`'s lazy twin.

`answers:one`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
one(*, default: Any=_MISSING) -> Any
```

Return at most one decoded value, defaulting only on absence.

`answers:first`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
first(*, default: Any=_MISSING) -> Any
```

Return the first decoded value, or the caller's explicit default.

`answers:close`: `lifecycle`, returns `None`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
close() -> None
```

Release the engine cursor this view holds, now rather than later.

`answers:to-df`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
@staticmethod
to_df() -> Any
```

These rows as a pandas DataFrame; the declared point rows.to('pandas').

`answers:to-pl`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`.

```python
@staticmethod
to_pl() -> Any
```

These rows as a polars DataFrame; the declared point rows.to('polars').

### remote-space declarations

`remote-space:delivers`: `query`, returns `None`, effect `pureStructural`, determinism `det`; tiers `remote`.

```python
delivers() -> tuple[str, str] | None
```

Nothing: the wire carries no event.

`remote-space:refusal`: `query`, returns `value`, effect `pureStructural`, determinism `det`; tiers `remote`.

```python
refusal(capability: str, /, **_request: Any) -> str | None
```

Read RemoteSpace.refusal.

`remote-space:match`: `query`, returns `stream`, effect `oracleIO`, determinism `nondet`; tiers `remote`.

```python
match(pattern: Atom, *, limit: int | None=None) -> Iterator[Atom]
```

Candidates for a pattern; `limit` crosses as the wire's optional

`remote-space:stream`: `query`, returns `stream`, effect `oracleIO`, determinism `nondet`; tiers `remote`.

```python
stream(pattern: Atom, *, batch: int=_DEFAULT_BATCH, limit: int | None=None, arrow: bool=False) -> RemoteCursor
```

The lazy method: answers pulled a chunk at a time, so taking two

`remote-space:server-capabilities`: `query`, returns `mapping`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
server_capabilities() -> dict[str, Any]
```

The server's own advertisement from GET /health: `capabilities`

`remote-space:atoms`: `query`, returns `stream`, effect `oracleIO`, determinism `nondet`; tiers `remote`.

```python
atoms() -> Iterator[Atom]
```

Read RemoteSpace.atoms.

`remote-space:add`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
add(atom: Atom) -> None
```

Store one atom on the serving side.

`remote-space:add-many`: `write`, returns `None`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
add_many(atoms: list[Atom]) -> None
```

One request carries the batch, the engine's own bulk-write law on

`remote-space:remove`: `write`, returns `bool`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
remove(atom: Atom) -> bool
```

Read RemoteSpace.remove.

### remote-cursor declarations

`remote-cursor:__next__`: `query`, returns `Atom`, effect `oracleIO`, determinism `nondet`; tiers `remote`.

```python
__next__() -> Atom
```

Read the next remote answer.

`remote-cursor:to-arrow`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
to_arrow() -> Any
```

The whole remaining stream as one pyarrow Table.

`remote-cursor:__arrow_c_stream__`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
__arrow_c_stream__(requested_schema: Any=None) -> Any
```

The drained stream as the Arrow PyCapsule Interface's own object.

`remote-cursor:__iter__`: `query`, returns `stream`, effect `pureStructural`, determinism `nondet`; tiers `remote`.

```python
__iter__() -> Iterator[Atom]
```

Iterate the receiver.

`remote-cursor:close`: `lifecycle`, returns `None`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
close() -> None
```

Release the server's cursor; idempotent, and distinct from

`remote-cursor:__enter__`: `query`, returns `value`, effect `pureStructural`, determinism `det`; tiers `remote`.

```python
__enter__() -> Self
```

Enter the receiver lifetime.

`remote-cursor:__exit__`: `lifecycle`, returns `None`, effect `oracleIO`, determinism `det`; tiers `remote`.

```python
__exit__(exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None) -> None
```

Stop the server's cursor without letting the stop displace the

### namespace declarations

`arrays:install`: `provider`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
install(default: Any=None) -> list[str]
```

Register the array operation set on the shared engine.

`arrays:uninstall`: `provider`, returns `list`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
uninstall() -> list[str]
```

Retire this space's array installation; answers what it unregistered.

`arrays:ops`: `introspection`, returns `list`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `context`.

```python
ops() -> list[str]
```

The array operation names installed in this space, in install order.

`arrays:backend`: `introspection`, returns `str`, effect `readOnlyLookup`, determinism `det`; tiers `sync`, `context`.

```python
backend() -> str
```

The array library this space's constructors build in.

`live:view`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`, `async`.

```python
view(*query: Any, on: SubscriptionEdge=SubscriptionEdge.both, strategy: str | None=None) -> Any
```

Maintain a query's multiset through this space's committed writes.

- `on`: `add`, `remove`, `both`.

`tables:to-df`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
to_df(rows: Any) -> Any
```

These rows as a pandas DataFrame; the declared point rows.to('pandas').

`tables:to-pl`: `query`, returns `value`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
to_pl(rows: Any) -> Any
```

These rows as a polars DataFrame; the declared point rows.to('polars').

`remote:connect`: `provider`, returns `callable`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
connect(url: str, timeout: float=30.0, *, token: str | None=None, headers: dict[str, str] | None=None, ssl_context: Any=None) -> Transport
```

The HTTP transport for a serve()d engine: one POST per operation,

`remote:serve`: `lifecycle`, returns `context`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
serve(host: str='127.0.0.1', port: int=0, spaces: list[str] | None=None, *, token: str | None=None, authorize: Callable[[Request], bool] | None=None, ssl_context: Any=None, cursor_idle: float=_CURSOR_IDLE, cursor_limit: int=_CURSOR_LIMIT, mutation_ttl: float=_MUTATION_TTL, mutation_limit: int=_MUTATION_LIMIT) -> Server
```

Expose this engine's spaces over HTTP; port 0 picks a free one.

`tables:add`: `write`, returns `int`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
add(head: Any, data: Any) -> int
```

Add a tabular source to a space as ``(head column...)`` facts.

`tables:declare`: `write`, returns `Atom`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
declare(name: str, declaration: Atom | str) -> Atom
```

Write one ctx-scoped bridge declaration into &metta, where explain

`tables:accessors`: `provider`, returns `tuple`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
accessors() -> tuple[str, ...]
```

Install the metta accessor for every registered frame library already imported.

`tables:sql-function`: `provider`, returns `str`, effect `oracleIO`, determinism `det`; tiers `sync`, `context`.

```python
sql_function(connection: Any, head: Any, name: str | None=None) -> str
```

Register a MeTTa head as a scalar SQL function, and answer its SQL name.

<!-- end generated door contracts -->

## Running and querying: exact return shapes

The generated declarations above own the parameter lists. `run` returns one
answer group per `!` directive. Ordinary `eval` returns a flat list for one
target and one group per target for a batch. Its `answer` option selects the
result shape; `under`, `delivery`, `limit`, `timeout`, `inferences`, `image`,
`on_error` and `determinism` compose with that selection. Lazy selections own
their cursor, and the asynchronous tier keeps every pull and close on its worker.

`prepare` retains a query for repeated `.solve(given=...)` calls and exposes
its `.columns`. `save` replaces the destination atomically and fsyncs it;
`source` returns the same loadable MeTTa text in memory. `digest` is the
store-independent, 64-hex content hash.

`target` may be a string or an already-built atom. `bind()` maps BARE SYMBOLS
(not `$vars`) to Python objects, which cross by identity, not by copy or repr:
`with m.bind(v=tensor): m.eval("(gated v)")` scopes that binding over every
call inside the block. A target with no applicable rule is returned as the
unreduced term; `eval_status()` names that path `not-reducible`.

### Program text with holes

Three faces, one door. `m.run(t"!(fib {n})")` is a Python 3.14 t-string
literal; `m.run("!(fib {n})", n=10)` is the same on every supported version;
in between, any object with `strings` and `interpolations` tuples works,
including `tstrings-backport`'s `t("...")`, because the check is structural and
never an isinstance against a class the 3.12 floor does not have. The type is
`metta._atoms.factories.TemplateLike`, whose holes are `metta._atoms.factories.InterpolationLike`
(published there, beside the reader door and the atom constructors that are a
hole's markers, rather than at the narrow package root). It is accepted
at `run`, `profile`, `profile_extension`, `eval`, `answers`, `eval_status`,
`match` (pattern text) and `parse`, on `Space`, on the `MeTTa` context, at
module level and on `AsyncMeTTa`.

A hole is a BINDING BY POSITION. Each one is spliced into the text as a
generated symbol and bound through the mechanism `bind()` already uses, after
the reader and before anything runs. Nothing is rendered to text, so a `str`
holding a space or a quote needs no escaping. Values enter through `encode`: an
int is a Number, a `str` a String atom, an `Atom` itself, a `Space` its handle,
anything else a grounded object.

The generated spelling is `__metta_hole_<k>`, and the `__metta_hole_` prefix is
RESERVED: template text spelling it is refused, and so is a `bind()` key in that
namespace, so a hole and a name the program uses can never be the same symbol.
Text passed with no values is not a template, so there it reads as an ordinary
symbol.

The markers at a hole are the atom constructors, not a new vocabulary:
`{Symbol(name)}` for a symbol, `{Grounded(obj)}` for an opaque object,
`{parse(text)}` for a spliced expression. The specs `{v:sym}`, `{v:py}` and
`{v:expr}` are sugar for exactly those three. `{v!r}`, `{v!s}` and `{v!a}` apply
Python's conversion first and enter the result as text. `{x=}` is PEP 750's
debug form: it folds `x=` into the text, so it enters as the String `"x="`
followed by the repr, two atoms rather than one. A nested template composes,
splicing its text and its holes into the outer call.

### The same template, rendered: `metta.render`

`metta.render(source, /, **values) -> str` takes those same three faces and
answers TEXT instead of running anything, so a card, a reference page or a
documentation section is a template over a query rather than a program that
prints. `rows.render(source, /, **values)` and `answers.render(...)` are the
method faces: both bind the receiver under the name `rows`, so one report
renders the eager result and the lazy view alike, and a `rows=` keyword beside
either is refused rather than silently winning. A method face always has that
one value, so it always reads its text as fields, where `metta.render("{x}")`
with no values leaves the braces alone the way `m.run("!(id {x})")` does.

One spec table, both directions, and a spec of the wrong direction refuses
naming the door that owns it (`{v:sym}` at a rendered hole names `m.run`,
`{v:table}` at a reading hole names `metta.render`):

| spec | reading a hole | rendering a hole |
|---|---|---|
| none | `encode(value)` | the value's text: a String's characters, any other atom's MeTTa text, a `str` itself, anything else through `encode` first |
| `sym` | `Symbol(text)` | refused, naming `m.run` |
| `expr` | `parse(text)` | refused, naming `m.run` |
| `py` | `Grounded(value)` | refused, naming `m.run` |
| `sexp` | refused, naming `metta.render` | canonical MeTTa text, what `repr` answers and `parse` reads back |
| `quoted` | refused, naming `metta.render` | a MeTTa string literal of that text |
| `json` | refused, naming `metta.render` | one line of JSON through `metta._binding.json.dumps`, a result as its records |
| `table` | refused, naming `metta.render` | the columns as a Markdown table, every row, `\|` and `\` escaped and a newline `<br>` |
| `lines` | refused, naming `metta.render` | one value per line, a nested template rendered |

A bare rendered hole is exactly what the ENGINE puts at a `format-args` `{}`
(`engine/metta/operators.pl`, `metta_console_text/2`), and `{v:sexp}` is what
`repr` answers, both compared against the engine by the suite rather than
pinned to a literal. The one measured difference is the boolean: this library
writes the source spelling `True` where the engine writes the atom `true`, and
both read back as the same atom.

Any other spec is Python's own, applied to the value, because a rendered hole
is text: `{n:.2f}` and `{name:<20}` mean here what they mean in an f-string,
and `f"{atom:sexp}"`, `format(rows, "table")` reach the same table with no
import, since `Atom`, `Rows` and `Answers` answer the specs through
`__format__`. `format(x, "")` stays `str(x)`, Python's law, which for a String
atom is the quoted literal where a bare hole is the characters.

Rendering costs one `encode` per hole and no engine call, except `{v:json}`,
which is one engine round trip through the codec. `{rows:table}` and
`{rows:lines}` read every row, where the display protocols stop at
`config.display_rows`: a document is not a terminal, so bound an unbounded
view before rendering it.

A template holds ONE level. `{for row in rows}` is not spellable: it is a
SyntaxError on the 3.14 face, PEP 750's grammar having no statement form, and
a literal's values are evaluated when the literal is, so no per-item binding
could arrive later. Iterate in Python and compose the pieces, which is what a
nested template and `{parts:lines}` are for:

```python
entries = [metta.render("- {p} -> {c}", p=row.parent, c=row.child) for row in rows]
page = metta.render("# {title}\n\n{entries:lines}\n\n{rows:table}",
                    title="Parents", entries=entries, rows=rows)
```

`extensions/python/tools/libdoc.py` is that shape at full size: its `catalog()`
answers three `Rows` and no text, and the page is the templates above it with
`{coverage:table}` in the middle.

Refused with the hole's line and column in the text you wrote: a hole inside a
`"..."` string literal, inside a `;` comment, or glued to a symbol. Refused by
name: a field with no keyword, a positional `{}` or `{0}`, a keyword no field
uses, a field spelled like one of the door's own keywords (`timeout`, `under`,
`where`), an unknown spec, a template at `load` (which takes a path, so use an
f-string) and at `run_status` (whose engine door carries no bindings).

The keyword face engages ONLY when values are passed, so `m.run("!(id {x})")`
still reads `{x}` as an ordinary symbol and `{{`/`}}` are `str.format` escapes
only when a value is there to resolve.

`bind()` stays, and is the right door for a value several calls share: it names
a value for a whole block rather than one position. The difference is what the
holes exist for. A binding names a SYMBOL and reaches every occurrence of it,
including one the author meant as a symbol; a hole reaches only its own place.

Variables shared across query patterns join: `m.match(S.p(V.x,V.y), S.p(V.y,V.z))`.
`where=` is a term the engine evaluates per match: `where=S[">="](V.n, 60) & S["<="](V.n, 70)`.
`into=` builds fields by matching column names, or rebuilds a complete
constructor expression captured in one column.

`under=` changes the annotation algebra for either a relational match or a
call. Thirteen carriers ship. The answers below are one program's: two facts tagged
`0.6` and `0.3` reaching one head through a rule tagged `1.0`, in a space named
`&s` whose head is `(h)`. Tags are floats, so `0.6 + 0.3` prints as the float it is.

| carrier | combine, extend | answers | |
|---|---|---|---|
| `bag` | `+` `*` | `0.8999999999999999` | the default when `under=` is omitted |
| `bool` | `max` `*` | `0.6` | |
| `visibility` | `max` `min` | refuses | requires `INTERNAL` or `PUBLIC`; reference faces read occurrence grades under this carrier |
| `set` | `max` `*` | `0.6` | combine is idempotent, so multiplicity collapses |
| `counting` | `+` `*` | `2` | an engine aggregate crossing no answer rows |
| `ranked` | `max` `*` | `0.6` | orders highest first |
| `prob` | `+` `*` | `0.8999999999999999` | orders highest first |
| `tropical` | `min` `+` | `1.3` | orders cheapest first |
| `budget` | `min` `+` | `1.3` | ascending like tropical, spent rather than distance |
| `prov` | `plus` `times` | `(plus (times 1.0 0.6) (times 1.0 0.3))` | a TERM, not a number |
| `formula` | `formula-or` `formula-and` | `(formula 7)` | a decision diagram over the facts, named by its root node's process-wide id (a fresh process answers `7` here); `.under(prob)` is its exact model count, `0.72` here, where `prob` sums proofs to `0.8999999999999999` |
| `polynomial` | `polynomial-plus` `polynomial-times` | `(poly (1 (var (rule &s 2 (h)) 1.0) (var (src &s 0) 0.6)) (1 (var (rule &s 2 (h)) 1.0) (var (src &s 1) 0.3)))` | the free semiring: one monomial per derivation, its sources as variables, its coefficient how many derivations use exactly them |
| `amplitude` | `amplitude-add` `amplitude-multiply` | refuses | outside its declared fragment |

Thirteen are objects: `metta.bool`, `.visibility`, `.bag`, `.counting`, `.set`, `.ranked`,
`.tropical`, `.prob`, `.prov`, `.budget`, `.formula`, `.polynomial` and `.amplitude`. The bare name works
wherever an object does, `under="budget"`.

`metta.vocabularies.Semiring` names the closed set: `bool`, `visibility`, `bag`, `counting`,
`set`, `ranked`, `tropical`, `prob`, `prov`, `budget`, `formula`, `polynomial`, `amplitude`.

A tagged program is evaluated on one of two routes, and `derivations=` on
`match` and `metta.algebra.evaluate` chooses. Left alone, a program whose
rules form a cycle, under a carrier whose `combine` is idempotent (`bool`,
`set`, `tropical`, `budget`, `ranked`, `visibility`, `formula`) or that
declares a saturation, takes the engine's tabled fixpoint: each relation
becomes a tabled predicate whose tag is a lattice-moded argument joined by
the carrier's `combine`, so the program converges and keeps no proof tree;
`why()` on its answers asks the engine again for the witnesses, the sources
each derivation uses (a cyclic program's minimal derivations, the formula's
prime implicants; an acyclic program's every derivation with its
multiplicity, the `polynomial` carrier's value), and `.under(other)`
is the other carrier's own fixpoint for the proposition, both bounded by
their `timeout=` and `inferences=`. Every other program takes the
derived route with retained derivations, as before, which refuses a cycle
after its round bound. `derivations=False` forces the fixpoint, the route
that scales and is exact for every carrier on acyclic data; a carrier whose
`combine` is not idempotent has no fixpoint over cyclic data, the sum over
infinitely many derivations, and runs there until the call's `timeout=` or
`inferences=` stops it, as any unbounded program does, unless it was declared
with `saturated=`, whose test stops the join when an answer changed too
little. `derivations=True` forces the derived route.

`under=formula` is how a probability is exact. Its tag is a reduced ordered
binary decision diagram over the program's facts, one variable per fact and
per ground rule instance, so two proofs that share a fact share a variable
and a cycle adds nothing, and `.under(prob)` on it is the weighted model
count: `P = p_f (p_g + p_h - p_g p_h)` for `(f and g) or (f and h)`, where
`under=prob` on the same program answers `p_f p_g + p_f p_h`, the
sum-product semiring over proofs. `under=prob` is exact only when no two
proofs share a fact. `metta.algebra.formula_variables(space, tag)` lists the
variables a formula mentions with their weights.

A declared carrier states the three operations the engine reads as claims
beside its row: `negate=` (unary, what `.under(...)` weighs a variable's
false branch with; `bool` and `prob` ship `complement` and `formula` ships
`formula-not`), `saturated=` (the binary test that stops a fixpoint join, which
no shipped carrier declares), and `variable=` (the binary
operation that mints the carrier's value for a source key `(src space n)`
or `(rule space n head)` and its written tag, which is how a carrier becomes
free over the program's facts; `formula` ships `formula-var`, `counting`
ships `counting-one` and `polynomial` ships `polynomial-var`). Each is a callable, a Symbol, or an operation name,
exactly as `plus=` and `times=` are.

In MeTTa the same fixpoint is `(match-under &space carrier pattern)`: one
answer `(proposition tag)` per derived proposition matching the pattern, the
pattern's variables bound, and a carrier written `(formula prob)` answers the
exact model count, so `!(match-under &self (formula prob) (path a c))` is
`((path a c) 0.344)` over the two-cycle graph of
`examples/ch22-a-reasoner-you-can-serve/22-01-logic-programs/07-tagged_fixpoint.metta`.

A rule may label its instances by a function of its premise tags instead of
the carrier's extend fold: `add_tagged_rule(weaker, S.h(V.x), S.p(V.x),
S.q(V.x))` with a callable registers it and stores `(rule (function
rule-weaker) (h $x) (premises (p $x) (q $x)))`, and a MeTTa equation named
the same way is written as `S.function(S.stronger)` directly. Each instance's
tag is the function applied to the premise tags in order, evaluated under
the carrier, which is Kifer and Subrahmanian's generalized annotated
program: NARS-style deduction, induction and abduction each carry their own
truth function. Such a label computes in the carrier it was evaluated under
and is not reinterpreted by `.under(other)`; the function's monotonicity is
what makes the fixpoint converge, and is the author's.

A rule may also carry a side condition: `add_tagged_rule(1, S.trusted(V.x),
S.score(V.x), where=S["above-half"])` stores `(rule 1 (trusted $x) (premises
(score $x)) (where above-half))`, and an instance exists only where the
guard, applied to the premise tags in order under the carrier, answers
True; a callable `where=` registers like a callable tag. That is the rule
form of Gabbay's labelled deductive systems, labelled premises, a label
function and a condition on the labels. On the derived route the guard
reads each derivation's own premise tags; on the fixpoint route a premise's
tag is its table's value, the join of every derivation so far, so the guard
reads an aggregate, and a non-monotone guard on a premise inside the rule's
own cycle is the author's loop, bounded by the call as any other. `why()`
shows the guard that held and `.under(other)` refuses a guarded instance by
name. A guard answering anything but True or False is refused by name. A
guard reads the labels of the carrier the program is asked in: under
`counting` every fact is one, so a probability threshold admits every
instance, and under a carrier whose labels are formulas or polynomials a
numeric guard is refused; `why()` on a tabled answer therefore runs the
program under the product of the answer's own carrier, which reads the
guards and label functions, and the witness carrier, which follows the
derivations it admits. A carrier may be written `(product Left Right)`
anywhere a carrier goes on the fixpoint route, its tags `(pair L R)`, so
`(match-under &self (product prob polynomial) (trusted a))` answers
`((trusted a) (pair 0.6 (poly ...)))`.

`metta.vocabularies.AlgebraLaw` names the accepted set: `combine-associative`,
`combine-commutative`, `extend-associative`, `extend-commutative`,
`left-distributive`, `right-distributive`, `combine-idempotent`,
`combine-zero-identity`, `extend-one-identity`, `extend-zero-annihilates`,
`contraction`, `roundtrip`, `equivalent`, `associative`, `commutative`,
`distributive`, `idempotent`, `identity`, `distributes-over`.

| algebra-law alias | expands to |
|---|---|
| `associative` | `combine-associative`, `extend-associative` |
| `commutative` | `combine-commutative` |
| `distributive` | `left-distributive`, `right-distributive` |
| `idempotent` | `combine-idempotent` |
| `contraction` | `contraction` |
| `identity` | `combine-zero-identity`, `extend-one-identity` |
| `distributes-over` | `left-distributive`, `right-distributive` |

The seven names Hypothesis's ghostwriter spells, `associative`, `commutative`,
`identity`, `distributes_over`, `idempotent`, `roundtrip` and `equivalent`,
are `AlgebraLaw` members (the enum is the underscore-to-hyphen map), so
`metta.testing.laws(algebra, space)` generates one property test per law row
a declaration names. `roundtrip` and `equivalent` are the seam's laws, checked
by the host and never by the engine's finite-carrier checker: every carrier
value survives projection through the engine and back, and each operation
agrees with its host twin (the Python callable it was registered from, or the
standard callable that mentions a builtin, `*` and `operator.mul`).

`under=counting` answers one `TaggedAnswer` whose `.annotation` is the count
and whose `.value` is `()`, the empty value saying no proposition row was
manufactured; every carrier yields `TaggedAnswer` with `.annotation`, `.plan`,
`.why()` and `.under(other)`. A `prov` tag is a symbolic term over the source
tags, so an interpreter outside the engine can walk it, which is how one
query's fused derivation carries derivatives; `.why()` renders the retained derivation and `.under(other)` reinterprets that
same derivation without querying again, including under an algebra whose
operations are plain Python callables. Passing an algebra object uses that
object directly, without a declaration in the answer's space; a same-name local
declaration does not replace it. `amplitude` refuses until
`m.annotations` declares its fragment with the capabilities `finite`,
`contractive` and `staged`.
`with metta.under(carrier):` supplies the task-local default and an explicit
keyword wins. `metta.current_algebra()` reads back which of the three is in
force, following the same precedence a query does, per-call carrier over task
scope over the current context's `annotations` row, and answering `None` when
none of the three is present rather than reporting execution's implicit
Boolean default as a declaration. It answers from inside an operation the
engine has already entered, which is what `metta.current_space()` does for the
other half of the ambient state.
Algebra combine and extend operations and tagged `where=` guards observe the
selected carrier through `current_algebra()`, including an explicit carrier
that overrides an annotations row. The evaluation context carries that carrier,
answer limit and ordering across their internal evaluation calls.
`m.match(q, under=ranked, limit=3)` and `m.match(q, under=ranked)[:3]`
return the three best. They offer `limit=3` to a foreign provider when its
source is repeatable, it promises `emits("best-first")`, its annotations and
ordering match the selected carrier, and it handles the single unguarded
pattern with `Exact` routing. Otherwise the provider is drained and the
answers are ordered here. `(top 3 ...)` uses the same engine license. A
provider that implements `match` and no `atoms()`, the ranker or vector index
the pushdown exists for, takes the bound through all three: a space that
cannot enumerate holds no tagged program the Python doors could read, so they
take the ordinary route `(top 3 ...)` takes.
`m.sample(q, k=10, seed=7)`
samples with replacement from implicit `(rate n)` tags using a local seeded
generator.

THREE DIFFERENT QUESTIONS WEAR THE WORD "PROBABILITY" AND EACH HAS ITS OWN
MECHANISM. Picking the wrong one answers a number that means something else,
so choose by the question you are asking:

- is this PROPOSITION true, and how confident am I: `lib_pln`, `lib_pln2`, and `lib_nars`
  truth functions. The value belongs to the fact.
- what VALUE does this quantity take, over a distribution: `lib_measure`
  holds transparent weighted superpositions, where `ws-normalize` makes a
  distribution and `ws-sample!` draws from it, its bang naming the choice it
  makes. `lib_statistics` maps one distribution, combines independent ones,
  conditions an explicit joint law, and asks named probability questions. The
  value belongs to the quantity.
- how did this DERIVATION combine the tags it passed through: `under=`, above.
  The value belongs to the proof.

For the value question, import `lib_statistics` and write a finite law as
`((weight value) ...)`. Choose the head by the question:

- `(ws-map fun dist)` pushes one distribution through a pure unary function.
- `(ws-map-independent fun dist ...)` pushes the product of zero or more
  independent distributions through a function with matching arity. Alternative
  function rewrites give alternative complete laws. If the values are correlated, put
  `(Pair left right)` values in one joint distribution and use `ws-map`.
- `(ws-mass-at-least dist threshold)` answers the inclusive probability
  `P(X >= threshold)`.
- `(ws-prob-gt-independent left right)` answers the strict independent win
  probability `P(X > Y)`; it is not stochastic dominance, total variation, or
  comparison of expectations.
- `(ws-condition-joint joint observed)` conditions `(weight (Pair input
  output))` rows on an exact input and returns the output distribution.
- `(ws-average-independent (dist ...))` gives the arithmetic-mean distribution
  for mutually independent numeric inputs.
- `(ws-add-bernoulli-independent dist p)` adds an independent zero-or-one trial
  with `p` in `[0, 1]`.

Each head normalizes relative weights and merges equal outcomes at their first
position. Empty input, negative or nonfinite weights, and all-zero mass answer
an `Error` whose message states the repair.

`under=prob` is the THIRD of those. It weights a derivation and is not a random
variable's distribution, so a query asking what a height is will not get one
from it; that is `lib_measure`'s question. Keeping the three apart is what lets
a fact carry a truth value AND range over a distributed quantity AND be reached
by a weighted proof, without any one of them overwriting another.

`with m.capture() as output:` collects printed text in `output.text` without
changing either return shape. `with m.atomic():` makes each whole call one
transaction; `with m.speculative():` runs each call against a snapshot and
discards its writes, so `m.run("!(add-atom &self (f 1))")` inside one leaves
nothing behind. Both scope every CALL in the block, the Python write doors
included: `m.add`, `m.remove`, `del m[pattern]`, `m.transfer` and `m.clear`
inside a speculative block leave nothing behind, and inside an atomic one
each is its own committing transaction. Per CALL is the whole contract: a
later call does not see what an earlier one wrote in a speculative block, and
a raise does not undo a call an atomic block already committed.
`m.transaction(callable)` is the boundary that spans SEVERAL calls, and there
is no with-block form of it, because SWI's transaction/1 and snapshot/1 take
a closed goal and an engine refuses to yield out of either.
`with metta.speculate():` is the same discarded execution scope for the lazy
module-tier default context.

`Rows` is a list of `Row` with `.columns`, and `Answers`, which is what `match`
and `answers` hand back, is the lazy replayable cursor carrying every door
below. `row.x` and `row["x"]` both work.
A view opens its engine cursor on first demand. If that happens inside a
transaction, the engine evaluates it eagerly on the transaction's thread and
holds the answer bag. Its reads see that transaction's writes, and its writes
belong to the transaction. Holding costs memory proportional to the answers;
inference and time budgets are spent during opening, and captured output is
returned once with the first pull. Unread rows survive commit and disappear
on rollback. Stepping from another thread refuses with "step it from the
transaction's thread, or open it outside the transaction". Outside a
transaction cursors remain lazy and keep their logical update view.
`rows.one()` (exactly one), `.first()`, `.column(name)` -> that column's atoms,
`.group_by(name)` -> a dict from each column atom to its `Rows` slice,
`.table()` -> dict of columns decoded to Python values, `.to_dicts()` -> plain
mappings, `.to(library)` -> a frame of any REGISTERED frame library, with
`.to_df()` and `.to_pl()` the sugar `metta-pandas` and `metta-polars` declare
(the `dataframes` extra installs both), `.build(column, cls)`
rebuilds one named column, and `.build(cls)` rebuilds the sole constructor
column. Both keep `cls` for type checkers.
`.pipe(fn, *args)` chains, `_repr_html_` renders in notebooks, and
`_repr_pretty_` on an expression gives IPython the same grouped tree
`__rich_repr__` gives rich.

Rows and Answers ARE Arrow data. `__arrow_c_schema__()` and
`__arrow_c_stream__(requested_schema=None)` are the Arrow PyCapsule Interface,
so `pa.table(rows)`, `pl.scan_arrow_c_stream(rows)`,
`pd.DataFrame.from_arrow(rows)` and `duckdb.sql("select * from rows")` all read
the answers with no conversion call, and `to(library)` is sugar over the same
stream: which libraries it reaches is the `frame` point's rows in
`metta.seam`, so a third frame library gets `rows.to(solars)` by registering
and `to_df` / `to_pl` are the two shipped rows' declared method names rather
than a privilege. One typed projection decides the columns for all of them: a
column of one wire kind is int64, float64, bool or utf8 and carries its decoded
values, and a column mixing kinds, or holding a symbol, a variable, a nested
expression or an integer wider than int64, is utf8 canonical MeTTa text.
`Grounded(None)` is Arrow null. Batches double from one up to 64, the engine
cursor's own chunk policy. `rows.arrow()` is the same stream wearing nothing
but the Arrow protocol, for `pl.DataFrame(rows.arrow())`: polars' constructor
tests for a sequence before it looks for the capsule and Rows is a sequence.
`np.asarray(rows["age"])` answers a typed array through `__array__` on the
column rather than an object array of atoms.
`answers.__length_hint__()` answers a size already known and never pulls;
`len(answers)` is the door that counts.

`m.assuming(*facts)` is a with-block where those facts exist and then do not.
`m.batch()` collects `add()` calls and crosses once at exit.
`m.limits(timeout=, inferences=, stack=)` sets scoped defaults for every call
inside; `stack` is SWI's combined-stack ceiling in bytes.

A bound that was EXCEEDED is a refusal and never an answer. `timeout=` raises
`TimeLimitError` and `inferences=` raises `InferenceLimitError`, and both are
decided where the answer is produced as well as armed as an interrupt, so a
call whose interrupt never reached the frame that armed it still refuses rather
than handing back a result for work that ran past its bound. Each loses its
interrupt its own way: a wall alarm can arrive after the goal has finished
(`call_with_time_limit(0.05, sig_atomic(sleep(0.3)))` succeeds in SWI with no
signal at all, and a 0.3-second load once answered after 66.170 seconds on a
starved box), and an inference limit is raised as a bare ball INSIDE the goal
after SWI has disarmed the limit, so any recovery catch under the goal eats
both (`call_with_inference_limit(catch(loop, _, true), 5000, R)` answers `R = !`
over an endless loop). The counter read at the answer is what refuses in both
cases. The cost of the rule is two `get_time/1` reads and one counter read per
bounded call, and none at all when no bound is set. A host resource abort inside a bound is raised too, as
`EngineError` naming SWI's stack ceiling. The program's OWN
`(pragma! max-stack-depth N)` is the exception and is unchanged: running out of
that fuel is `(Error <culprit> StackOverflow)` beside the answers that
finished, because it is reduction fuel the program asked for rather than a
caller's deadline.

## The three seams anything plugs into

It is a KERNEL because the point is what plugs into it. **Lower it**: host
code becomes equations (`@m.define`, translator rules). **Extend it**: the
engine calls your code (Python operations, Prolog predicates, C foreign
predicates, reader tokens). **Back it**: the atoms live elsewhere, because a
space is an interface, so SQLite, DuckDB, NetworkX, a live object, another
process or MORK can BE a space and still join with a native one. Each SEAT has
the same shape one level out: `metta.seam` for Python, `metta-node/seam` for
Node and `mt_point`/`mt_register` for C are one declared table of extension
points per seat, so a library extends a seat the way an extension extends the
engine. A
table-backed space is one declaration,
`(bridge (edge $a $b) (row edges (a $a) (b $b)))`, from which every provider
operation derives in both directions: a match becomes a WHERE, a repeated
variable `WHERE a = b`, `take` a LIMIT, an add an INSERT. EXTENDING.md is the
long form and names all nine seams; forking should never be the answer.

## Spaces

`ctx.space(name)` selects on the `MeTTa` context and `ctx.space()` or
`metta.space()` creates a fresh one, a context manager whose exit drops it;
a STRING names the space exactly, so `space("&kb")` is `&kb` and
`space("my_space_name")` is the bare name a program registers by writing
through it and `space_names()` lists, while the Symbol door supplies the
prefix, so `space(S.kb)` is `&kb`. A `$` name is refused (it would read back
as a variable) and so is the empty name; every other symbol is a space name.
The wire's `p` tag takes the payload as written for the same reason, while the
ENCODER still asks `metta_space_operand/1`, so a bare registered name crosses
out as `s` and only a host minting the tag itself puts one in;
`m.copy()` restores a space's own rows into a fresh anonymous space the way a
load restores a program: the equations arrive waiting, the functions the source
had compiled compile, and the clone holds exactly its source's rows,
specializations included, and keeps running.
`m.drop()` clears a space and releases its name: a drop clears the whole life,
atoms, equations, subscriptions, import markers, tabling state and space-owned
catalog declarations, including algebras and their certificates. A reused name
starts clean. Named spaces
compile into their own module, so two spaces can define the same function.
`(context-space)` names the space the running code is in, and
`metta.current_space()` reports it from inside an operation.

`m.add(*atoms)`, `m.remove(atom)`, `m.atoms()`, `len(m)`, `m.clear()`,
`m.space_names()`, `m.name`, and `metta.tables.add(m, head, source)` reads
polars / pandas / mappings / iterables / any `__arrow_c_stream__` producer into
`(head v1 .. vn)` facts and answers how many.

`<`, `<=`, `>` and `>=` between two space handles REFUSE. `|`, `&`, `-` and
`^` on a space already build the terms `(or a b)`, `(and a b)`, `(- a b)` and
`(xor a b)`, because a Space is an Atom, so the ordering spellings cannot also
mean subset, and term order between two live engine objects is a third meaning
no program wants. Set algebra is `metta.spaces.diff`, `union`, `overlay`,
`readonly` and `mapped`; `a == b` compares identity; `metta._atoms.factories.order_key`
sorts a mixed atom list. A handle against any other atom still orders.

The write family is VARIADIC where n-ary is the meaning, each shape one
engine crossing inside one transaction: `a.transfer(x, y, to=b)` moves one
occurrence per atom between spaces, `m.remove(x, y, z)` counts the found
while the one-atom call keeps its truth value, `m.eval(t1, t2)` answers one
group per term under one bind scope, and `x.unify(y, z)` is SIMULTANEOUS,
every operand agreeing under one substitution or the answer is None.
`+=` and `-=` classify their operand the same way, so the fact stream one
door stores the other subtracts (`m -= [(S.Edge, a, b), (S.Edge, b, c)]`).
`-=` takes ONE occurrence per element, Counter's grain, which is what makes
it `+=`'s inverse; `remove()` is that same grain reporting absence; and
`del m[pattern]` is the drain, every unifying occurrence in one crossing.
MeTTa spells the pair `subtract-atom` and `remove-atom`. `add-atom` and
`remove-atom` are upstream PeTTa's own spellings and take upstream's domain, an
atom with a HEAD: `!(add-atom &self b)`, `!(add-atom &self ())` and
`!(remove-atom &self 1)` answer nothing and write nothing here exactly as they
do there, because upstream stores an atom as a fact keyed on its head and a
headless atom cannot become one. This engine's space is WIDER, and the wider
doors are the spellings upstream does not define: `add-atoms` writes any atom,
`subtract-atom` takes one occurrence back, `Space.add`, `space.remove` and
`del space[atom]` are the Python faces, and a bare atom at the top of a source
file is the source spelling, which upstream's parser refuses. The `MeTTa` context speaks the same protocols as its own space,
so `m += lib.dict`, `len(m)`, `atom in m`, `m[pattern]` and `del m[...]`
work on the process home directly; `bool(m)` is always True, since a space
is a handle rather than a value that dwindles.

On a native space, `subtract-atom` is the non-blocking single-occurrence
remover: it returns `False` for a current miss without waiting for a later
writer, including inside `transaction`. A rollback restores the occurrence.
A structured pattern may contain variables; a bare variable is refused with
the remedy to name a pattern or use `remove-atom` to drain. Python's
`space.remove(atom)` and `space -= atom` expose this grain for a named atom
or structured pattern. Subtraction uses the existing storage lookup and
removal paths; it does not install a subscription. A foreign provider's
removal runs synchronously and determines its own waiting behavior.

`metta.spaces` composes spaces without copying: `union(*spaces)` reads a set as
one, `overlay(front, back)` reads both and writes to the front, `readonly(s)`
refuses writes by capability, `mapped(s, shape)` is a shape view from one
declaration, and `diff(a, b)` says HOW two spaces differ where `digest()` only
says THAT they do. Each ANSWERS a provider, not a space, so attach it to query
it: `metta.attach("&all", metta.spaces.overlay(front, back))` then
`all.match(...)` joins across both layers with `where=`, `under=` and Answers,
where the composed object's own `match(pattern)` is the provider protocol's
narrow one. Each composes STORAGE and is a provider, not an evaluation
context: equations reachable through one are data, and read back by `atoms()`
without firing, unless that provider declares `rules`.

`m.live(*query, on="both", strategy=None)`, the door `metta-live` contributes
(the `live` extra; without it `m.live` is `no door namespace 'live' is
registered`), materialises a query and keeps it current from this space's own
committed writes: `live.rows` is what
`m.match(...)` would answer without asking, `len(live)`, `atom in live` and
`live.count(atom_or_row)` are local reads, and `live.atoms()` is the answer as
atoms for a one-atom query. The query is one pattern, a conjunction spelled the
way `match` spells one, or a call to a TABLED head. `strategy=` is the
`live-strategy` vocabulary (`metta.vocabularies.LiveStrategy`) and defaults to
the query's shape: `pattern` maintains one pattern's multiset from the write
events at O(1) per event, `heads` watches the heads the query mentions and
re-answers it once per COMMIT that touched one, `tabled` serves a call by
watching its own table's invalidation counter. `live.strategy` reports which is
in force. Refusals: a provider that declares no event delivery; a query whose
own head is an operation that writes, because a view MATCHES its query and
never calls it; a `tabled` strategy over a head with no table, or one whose
cache policy does not invalidate, naming the policy. `live.close()` ends the
maintenance and the view keeps its last answer; it is a context manager, and
`aclose()`/`async with` are its `aio` face.

`metta.structures` holds the stores worth having: `AlphaSet` (atoms modulo
variable renaming), `PatternMap` (a MutableMapping keyed by atoms),
`MatchIndex` (many patterns, one atom, which match), `LiveView` (one pattern
materialised and kept current from the space's own writes, which is
`metta.live`'s `Live` with the `pattern` strategy read through its atoms),
`ClosureView` (reachability over a
stored relation, tabled from birth, which is what makes a closure over CYCLIC
or symmetric data terminate at all: the same reachability written as recursive
equations does not terminate over a cycle, so reach for this rather than
writing the rules), `TabledMap` (a computed cache that stays correct).

`&metta` is the space in which the library describes itself, and it is where
every declaration below is stored. The catalog describes its own kinds there:
`(kind head argspec...)` rows declare each declaration's shape,
`(vocabulary name value...)` rows declare the value sets, and
`(claim vocab value property...)` rows attach per-value facts. A
`(policy axis knob default)` row names each engine decision point and its
shipped choice. There is exactly one row for each of agenda, algebra,
atomicity, caching, delivery, determinism, dispatch, equality, errors,
fidelity, merge, order, reaction-order, save-format, source-kind, storage,
transaction-mode, typing, volatility and world, twenty of
them. `tests/checks/check_policy_inventory.py` asks the running catalog for
those rows and the semiring ordering claims, joins them to their implementation
seams, and rejects multiline `member/2` or `memberchk/2` lists, Python
`Literal[...]`, and Python list/set membership that bypass the catalog. The
immediately preceding annotation may exempt only mechanism-internal,
arbiter-owned-language-law, codec-version-identity, or
documented-collision-decision, with a reason and an existing local source line
or symbol. Only catalog preset terms in `engine/spaces.pl` and the generated
`metta.vocabularies` output are authority rather than independent lists. One
generic checker validates every `&metta` write against them, a violation is a hard
error naming the atom, the position and the argspec, and a head with no kind
row passes untouched, so third-party declaration kinds are ordinary data
until their author declares a kind row for them. Two marker rows put a
third-party kind on the engine's own paths: `(routed-by-shape head)` gives it
the shape router the shipped kinds use, keyed by context or by global, and
`(owned-by-space head)` says its rows name their owning space in the first
position, which puts the head in the walk that retires a space's declarations
when the space is dropped. `owned-by-space` refuses a head whose kind row does
not start at `symbol`, because that walk reads position 1 as the space.

Every vocabulary has a MeTTa TYPE NAME, and the engine writes the type atoms
itself: one `(: <TypeName> Type)` beside each `(vocabulary ...)` row and one
`(: <member> <TypeName>)` per member, all in `&metta`, so
`!(get-type-space &metta pureStructural)` answers `EffectClass` and a program
can match the closed sets by type there. Plain `get-type` asks the current
space, which holds none of them: `!(get-type pureStructural)` answers
`%Undefined%`. The name is the
mechanical CamelCase of the kebab row name (`effect-class` is `EffectClass`,
`answer-policy` is `AnswerPolicy`), and an exception is a row:
`(vocabulary-type on-error-mode OnError)` is the only one that ships, and it is
what both seats' generated enums are named after as well. Two more sibling rows
carry what a vocabulary needs beyond its members, never a column, because
programs match `(vocabulary ...)` by arity: `(vocabulary-order <vocab> <m1>
<m2> ...)` is a chain the engine writes as `(:< m1 m2)` edges, shipped once as
`(vocabulary-order fidelity Exact Partial Sound)` so a stronger fidelity claim
stands where a weaker one is required, with `Refuse` deliberately outside it;
and `(vocabulary-open <vocab> "<why>")` says a library may extend the set.

A vocabulary with no `vocabulary-open` row is CLOSED, which is every one of
them except `semiring` and `provider-capability`. The one door is
`(add-atom &metta (vocabulary-member <vocab> <word>))`: on an open row the word
joins the vocabulary's values everywhere the engine reads them (`(one-of ...)`,
`(some-of ...)`, a `(claim ...)` about it, `metta_vocabulary_value/2`) and gains
its `(: <word> <TypeName>)` atom, and withdrawing the row takes both back. On a
closed row it is refused naming the row and the property, with
`(vocabulary-open <vocab> "<why it opens>")` as the remedy. `semiring` is open
because an `(algebra ...)` row is the door a program already has, and the
engine registers the carrier's name through this one when that row lands, which
is what lets a declared algebra carry `(claim semiring <name> ordered
ascending)`; before that the vocabulary was a boot-time snapshot of the shipped
presets and the claim was refused. `provider-capability` is open because
`seam:foreign_capability/2` and `kind/2` are multifile, so a seat declaring a
seam hook of its own declares the word gating it: `extensions/node/bridge.pl`
registers `bounded`, `pushdown` and `transactional` that way, and a capability
word outside the row is refused at the registration door rather than gating
nothing.

The wire's own grammar is rows too, `(wire-tag <tag> <class> <payload>
<means>)`, thirteen of them: nine `term` tags that nest inside an atom, three
`frame` tags that wrap a whole answer, and `r`, whose class is `reply` because
it is `metta_py_cast`'s answer shape rather than part of the atom grammar.
`metta.vocabularies.WIRE_TAGS` is generated from them, `metta.remote._schemas`'
OpenAPI `Atom` schema builds one arm per term tag from them, and
`CODEC.md`'s table and `tests/codec/corpus.json` are held to them, so the four
copies of the grammar that used to disagree now cannot.

Function dispatch has six axes. Match `(dispatch-default $axis $value)` in
`&metta` to read their shipped defaults, and add
`(dispatch-policy f NoMatchEnum NoMatchFail)` to override one axis for one
function. The axes are `MismatchEnum`, `NoMatchEnum`, `EvaluationOrderEnum`,
`FunctionResultEnum`, `ClauseFailedEnum`, and `OutOfClausesEnum`; each axis's
accepted values are published by its same-named vocabulary row. Remove the
override atom to restore the default immediately. Five names ship an override
of their own: `and`, `or`, `not`, `xor` and `implies` carry
`(dispatch-policy <name> MismatchEnum MismatchFail)`, because they are
RELATIONS over the two booleans and a relation out of its domain has no row
rather than a badly typed argument. `!(and a a)`, `!(and True 5)` and
`!(not 5)` answer nothing, which is upstream PeTTa's answer, while
`!(collapse (and $a $b))` is still `(True False False False)`.

## References and definition properties

```metta
(from lib_string (prefix text.))
!(text.string-length "abc") ; 3
```

`(from source map)` stores a reference row. A library name resolves through
`library` to one canonical defining home per process; a source can also be a
space. Definitions execute in that home, so private helper calls keep their
meaning. A reference brings callable heads and their type and documentation
rows. Ordinary data remains in the source. `import!` keeps its existing merge
semantics; `include` pastes forms in order and answers the last result.

References follow later definitions and disappear when their rows or homes
are withdrawn. Colliding heads form a union with one informational note naming
the origins. Multiple reference paths to one defining occurrence contribute it
once; two actual equal equations still contribute two answers. Cycles stop at
visited spaces. Prolog definitions participate at every registered arity.

A map is an ordinary function taking a head symbol. It may return one symbol,
no answers or several symbols. The engine applies it once per visible head per
reference row, including later additions, and refuses a non-symbol result.
The prelude provides `only`, `except`, `prefix`, `rename` and `qualified`:
`(only (a b))`, `(except (a b))`, `(prefix api.)`,
`(rename ((a x) (b y)))` and `(qualified api)`. `qualified` inserts `.`;
`rename` leaves an unlisted name unchanged. Partial applications and lambdas
use the same evaluator. `(pragma! from-map map)` sets the current space's
default for a two-element `(from source)` row; the initial map is identity.

`(internal helper another-helper)` grades every matching occurrence
`INTERNAL`, including later additions. Ungraded occurrences are `PUBLIC`.
The `visibility` algebra orders `INTERNAL < PUBLIC`, with `min` for extension
and `max` for combination. References read public faces under that algebra.
Selecting an internal head explicitly refuses with `evalc` in its defining
space as the remedy; a selected missing head produces an informational note.

`(get-property head)` enumerates `(visibility public|internal)`,
`(origin space file line)`, `(effect class)`, `(cost class measure)`, declared
`(deprecated since remedy)` and `(doc ...)` claims. Origins retain defining
occurrences through aliases and do not compile lazy equations. An unavailable
or changed source retains its path and answers line `-1`. `explain`, Python
`space.get_property(head)`, `head.origin`, `lib_reflect`'s `origin-of` and
library cards consume the same engine claims. Python `space.from_(source,
map)` adds the corresponding stored row through the ordinary write door.

`(pragma! load eager|background|lazy)` belongs to the current receiver. Eager
is the default. Background uses a future, and a call waits for its home to
finish. Lazy reads the source summary and compiles an equation at first use.
Both deferred policies require pure structural load-time forms and name the
offending form with eager loading as the remedy. Map evaluation may enumerate
read-only answers. A wait inside a transaction refuses; load eagerly before
opening that transaction. Source owners wake waiters on failure and allow a
later retry.

Same-name references use native module imports. Measured 2026-09-09
(`docs/journal/2026-09-09-import-and-module-semantics.md`): in the 3,000-call extension
driver, a local call and its reference each cost 3 inferences beyond the loop;
prefix and rename each cost 4. A 2,000-call `eval-arith` loop costs 278,007 for
local and referenced heads and 280,007 for renamed heads. Ordinary 1,000-row
imports keep their per-row slopes and cost nine fewer inferences when warm:
one rollback-state collection replaces three collections and an append. The
first cold equation import grows by 507 for six new engine heads, the cost of
the loader's initial predicate census. The design journal records paired
control counts and the reference-publication batch that avoids rebuilding a
shared caller once per changed dependency.

## Python functions as MeTTa functions

```python
@m.op(effect=EffectClass.pureStructural)
def hypot(a: float, b: float) -> float: ...
```

Effect metadata is required, with `effect=` the canonical spelling for new
code and an existing `(effect name class)` declaration atom retained as a
compatibility input. The remaining options are `name=`,
`transport="encoded"|"raw"`, `declarations=` (ordinary Atom claims),
`arities=`, and `inverse=` (the callable that runs it backwards).
`m.unregister_op(name)` removes every arity and declaration, for the whole
process. Its per-space half is `metta.withdraw(runtime, name, space)`: an
implementation is process-global while declarations are space-local, so a
library uninstalling from ONE space an operation another space still uses
releases that space's rows and leaves the operation registered, answering
whether the space held any. It raises `KeyError` for an unregistered name, as
`m.unregister_op` does, and withdrawing the last space leaves the operation
registered and declared nowhere, `m.unregister_op` being the door for that. A
coroutine
operation answers a FutureSpace immediately rather than suspending the call:
the future IS a space, so awaiting it is matching it, and `(async-op <name>
<future-space> launch|landing)` makes both ends observable. Landing is
published after the future settles, so an await that has returned says the
operation is terminal and says nothing about whether a landing subscriber has
run yet; wait on that subscriber's own signal when the observation is what you
need.

The ordered `EffectClass` members are `pureStructural`, `readOnlyLookup`,
`nondeterministicReadOnly`, `writesState`, and `oracleIO`. A plan's class is
the strongest member: `EffectClass.compose(effects)` folds that join and an
empty plan is `pureStructural`. Registering a generator or a generator inverse
LIFTS the class to at least `nondeterministicReadOnly` rather than refusing, so
`effect="pureStructural"` on a generator is accepted and reflects
`nondeterministicReadOnly`. Every registration publishes its canonical
`(effect name class)` row in `&metta`; missing metadata refuses before engine
state changes and names all five remedies. The retired input spellings map as
`immutable -> pureStructural`, `stable -> readOnlyLookup`, and
`volatile -> oracleIO`. Only the canonical names appear in `EffectClass` and
reflection.

The Python name is the MeTTa name, VERBATIM, and nothing is rewritten. Hyphens
are MeTTa's convention and Python cannot spell one, so ask: `name="p-digit"` on
`op`, `@m.define(name="p-sum")`, `rename=` on `integrate.module_ops`.
An operation name must also read as one symbol: a delimiter, variable spelling,
literal, or registered reader token is refused before either registry changes.
The same holds inside a compiled body, where a called name is resolved exactly
as written, so a hyphenated engine function is reached through an alias
equation the body can spell, `(= (sqrt_math $x) (sqrt-math $x))`.

Reader classes are full-token regular expressions. `m.register_token(pattern,
constructor)` gives the constructor the complete matched lexeme and accepts an
Atom or any value `encode` accepts; registering the same pattern replaces its
constructor, and `m.unregister_token(pattern)` removes it. Source has the same
door as `!(register-token! "[A-Z][0-9]+" tagged)`, which parses a later `A7` as
`(tagged "A7")`; `unregister-token!` removes that class. The shipped number and
string literals are rows in the same declared mapping, visible through
`metta_reader_token_class/3`. Registration changes later parses only.

Annotations become declarations in the engine's idiom: a `TypeVar` is
parametric, a `Union` declares one arrow per member, `Callable[[int],int]` ->
`(-> Number Number)`, `tuple[int,str]` -> elementwise, and
`Annotated[int,"metres"]` retains `Number` in the arrow while publishing its
metadata as a matchable `(Annotated Number "metres")` claim, where
`Annotated[int, Gt(0)]` refines the arrow itself to `(Annotated Number (Gt
0))` (Types and cast, the refinement vocabulary). An ATOM in
annotation position IS the type, which is the escape hatch for a MeTTa type no
Python class spells: `def speak(a: S.Animal) -> S.Sound` declares
`(-> Animal Sound)`, and the doc's `(@type ...)` field carries the same atom.
A generator is
nondeterministic, one answer per yield; returning `None` answers nothing, which
is why an `Optional` return declares the value type. An annotation the runtime
cannot resolve, a `TYPE_CHECKING`-only import for instance, drops only its own
parameter: the ones that resolve still declare, and a call form that does reach
the unresolved one is refused naming that parameter. An unannotated callable
makes no type claim. `(arguments name atoms)` asks for Atom wrappers after
ordinary evaluation, while an `Atom` annotation receives the written term
before evaluation. Only `(effect name pureStructural)` licenses the AUTOMATIC
cache, the one nobody asked for. A written declaration is carried out as
written whatever the class says: `!(memoize f)`, `!(memoize-exact f)`,
`!(tabled (f $x))` and `(cache f force)` cache a body that prints, writes a
space or is declared `oracleIO`. Two refusals remain and neither judges a
body: a name no function answers to, and a predicate SWI already tables, which
`force` does not open. These
policy atoms live in `&metta`; `(op name arity raw_det|raw_many)` records raw
transport.

`@m.define` compiles the Python BODY into MeTTa equations. Calling the resulting
`Defined` evaluates in its owning space and returns every engine answer;
`S.name(...)` stages the term explicitly, while `.py` keeps the plain function.
There is no unsupported-construct list. A body may say `try`/`except`/`else`/
`finally` and `raise`, which ride the engine's own error algebra (a raise
PRODUCES through `throw`, the body runs under `catch`, `py-except` matches by
live exception-class identity and inheritance, so a custom hierarchy matches
as `isinstance` would, and `as e`
reconstructs the live instance); dict and set literals, which lower to
`lib_dict`'s `dict-space` and reach it through `get-value`, `dict-has`,
`dict-put`, `dict-remove`, `dict-size` and the view methods, comprehensions
included; `type X = T`, which IS the rewrite rule it reads as; and `global`,
which is a pragma over the definition module. `&`, `|`, `^`, `~`, `<<`, `>>`
and `//` are engine builtins, so they pay no host crossing. Anything else
odd becomes a visible host island inside the equation, run per application
and never at decoration time, which is what `py(...)` spells explicitly. The
refusals that remain cite their ground in one of the two languages: an
unresolvable name is Python's own NameError, a `nonlocal` targets a frame no
stored equation outlives, and a `finally` reading a name its `try` rebinds
is a stale read the compiler names.
Inside a compiled body `match(pattern, template)` is LOWERED rather than run,
against `(context-space)`; a leading handle, space parameter or `"&kb"` names
another space, and two or more patterns before the template are the engine's
own conjunction `(, p q)`, the same join the read door spells as `m[p1, p2]`.
A Python `match` STATEMENT is a `case`: its arms lower to flat case rows over
the subject, so an `Empty` arm answers for a subject with no answers, and an
arm carrying a guard or an as-name nests the arms from there under a variable
row.
Stacked clauses become a first-match dispatcher. It takes `name=`, and
`prolog=` to make a Prolog file the function with the Python kept as the
reference twin. A local assignment such as `result: int = value`
becomes the enforceable in-place claim `(: $result Number)` inside its `let*`.
The parsed AST also supplies each definition's absolute source span, source
docstring, lexical free variables, and a conservative effect class through
`Defined.source_span`, `.doc`, `.free_variables`, and `.effect`; each clause joins the classes of the
operations it calls, stacked clauses join again, and `source-span`,
`free-variable`, and the resulting `effect ... <class>` atom reflect in
`&metta`. Replacement and `clear()` retire stale facts. `Defined.pure` remains
the compatibility projection of
`Defined.effect is EffectClass.pureStructural`.
`@rules` executes a generator with one rule-local `Var` per parameter and
returns its yielded equations as ordinary atoms. Defined calls stage only in
that scope. `equation(lhs).to(rhs)` statically keeps both halves on one Python
type and derives from the first-class longhand `S["="](lhs, rhs)`. Inside a
compiled generator, `yield from call(...)` delegates only when the callee's
nondeterminism is known; an ambiguous engine call refuses with the two explicit
spellings instead of splicing the call's children.
`m.define(cls)` declares a class into a space: `(: ...)` atoms, one accessor
equation per field for an expression-image class, and its methods registered as
functions, so the class crosses with its behavior. Python's class hierarchy IS
a subtype relation, so declaring `Animal` and then `Dog(Animal)` stores
`(:< Dog Animal)` and `get-type` on a `(: Rex Dog)` widens to `[Dog, Animal]`.
Only DECLARED classes and REAL bases become edges, which keeps `object`, a
NamedTuple's `tuple`, an enum's `Enum` and a virtual `abc` registration out.
`m.type(atom)` is the other verb and is unrelated: it answers that atom's first
`get-type`.
The grain is read off the class: a frozen dataclass, a NamedTuple or an Enum
is a VALUE, the constructor term itself (`(Point 1 2)`); any other class is an
ENTITY, a handle around one of the engine's tokens whose fields are facts in
the class's own space (`(_field-balance (Account (t ...)) 100)` in
`&Account`), read by an indexed match and written inside the caller's
transaction; a class inheriting `metta.Space` is a PROTOTYPE, a handle around
a space of its own that holds its facts and private rules. Every class
declares into a space of its own, `&Point`, which the declaring space
references with `(from &Point)`. Methods compile through the same compiler
with `self` as the first parameter: `self.x` is the accessor, `self.x = v` the
writer on an entity (and a refusal naming `dataclasses.replace` on a value),
`other.m()` the method's dispatch entry, `super().m()` the base's qualified
spelling, `type(x)` and `isinstance` are `get-type` with the `:<` edges. A
special method compiles under its word (`__add__` is `Vector-add`, `__len__`
is `Stack-len`) and the compiler lowers the syntax Python routes to it when
the operand's static type is declared: `a + b`, `a < b`, `-a`, `len(a)`,
`abs(a)`, `str(a)`, `a[i]`, `a[i] = v`, `del a[i]`, `x in a`, `if a:`,
`a(x)`, `for x in a` (a generator `__iter__`), `with a as v:` (enter, then
exit in a finally arm) and `case C(x=0, y=y)` (through `__match_args__`); an
operand of unknown type keeps the builtin. Python's own operators on the
instance reach the same equation. Decorators are rows: `@property` publishes
its getter, setter (`C-name!`) and deleter (`retire-C-name`);
`@cached_property`, `@functools.cache` and `@lru_cache` memoize the method
through lib_memo; `@staticmethod` is an equation with no receiver;
`@classmethod` takes the class symbol as its first argument
(`(Circle-unit Circle)`); `@abstractmethod` and a `Protocol` member publish
the arrow alone and a concrete subclass that leaves it unwritten refuses;
`@typing.final` seals a method and a class; `@dataclass(order=True)` and
`@functools.total_ordering` derive the missing comparisons from CPython's own
formulas; `@singledispatchmethod` chooses by `get-type` of its first
argument; `partialmethod` curries; `__del__` refuses with the scope remedy.
The five examples of `examples/ch17-concurrency-and-the-loop/09-class_values.metta`
through `13-class_decorators.metta` write each mapping's rows by hand beside
the Python twin that derives them.
The class door carries PEP 681's `typing.dataclass_transform`, so a checker
synthesises the constructor `install_type` builds and `Point(1.0, 2.0)` checks
and completes. Mypy reads that declaration on the module-level `metta._declare.define`
and not on `m.define`, because it resolves a decorator expression to a
definition node and an instance member access has none; pyright, the
specification's reference implementation, reads both.
`@typing.override` under `@m.define` is read as a declaration rather than a
hint: the definition must shadow a head a space this one inherits from
defines, and the door refuses with both remedies when it shadows nothing. The
decorator sits BELOW `@m.define`, on the function, because `typing.override`
writes `__override__` on what it is handed and the installer reads it there.
Shadowing WITHOUT the decorator is unchanged and silent, which is the
inherited-declarations ruling: a definition that hides an inherited one is
deliberate. PEP 698 scopes `override` to methods, so mypy reports
`"override" used with a non-method` on a module-level definition and a mypy
user silences that line with `# type: ignore[misc]`; pyright accepts it.
`metta.stubs(space)` returns that space's declared heads as the text of a
`.pyi`: one `def` per declared head with the arrow projected to Python
annotations, one `class` per `(: X Type)` with its constructor arrow as
`__init__`, each `(@doc ...)` as the docstring the same formatter gives
`help()`, an `__all__`, and a trailing note naming every head whose MeTTa
name Python cannot spell with the `m.fn["<name>"]` door that reaches it. The
projection is the annotation reader's table backwards: `%Undefined%` to `Any`,
`Number` to `int | float`, `String` to `str`, `Bool` to `bool`, the metatypes
to the atom classes, a nested `(-> ...)` to `Callable`, `(->)` as the return
to `None`, a type variable to a PEP 695 type parameter, and any other symbol
to `Atom`. `python -m metta stubs file.metta [-o out.pyi]` is the same
generator from a shell.
`m.fn.superpose(...)` calls an engine function from Python and answers every
answer; `m.fn["car-atom"]` is the exact door for a head outside Python's
identifier grammar, and `.compiled`, `.equations` and `.type` on the handle read
its clauses, its stored equations and its declared type. The namespace is not
callable, so `m.fn("superpose")` is a TypeError. Module-level `metta.fn` is a
different thing, the symbol namespace a compiled body writes `fn.add` against.
`m.register_prolog(source=..., path=..., names=...)` registers Prolog
predicates directly, which is the fast path: 2 inferences a call against 20 for
the same operation through an encoded `m.op`, measured 2026-09-06 by
`python -m benchmarks.extension_cost` from `extensions/python`, which subtracts
its driver so each figure is one call's marginal cost. The sequence is one
engine service, `metta_register_prolog(Origin, Names, Registered)`, which
tsmetta's `registerProlog` crosses too.
`extensions/python/llms.txt` carries the whole tier table.
`m.register_foreign_library(path, entry=, names=)` loads a compiled `.so`.
`m.unregister_prolog(extension)` releases everything one extension registered.

## Types and cast

Types are optional atoms: `(: Ann Person)`, `(: age (-> Person Number))`.
An arrow may carry ANNOTATIONS in its own brackets,
`(: twice (-[det]-> Number Number))`, and it then governs execution and
compilation exactly as the plain `->` does: `!(twice "s")` is a `BadArgType`
either way. The stored atom, `get-type`, the docs and source export all retain
the written spelling. The brackets hold one slot or two, and the ORDER is
fixed: a determinism word from `metta.vocabularies.Determinism`, one of `det`,
`semidet` and `nondet`, then optionally an `EffectClass` member. One slot
leaves the class at `oracleIO`, the top, and a class ALONE is not an arrow:
`(: f (-[oracleIO]-> Number Number))` is refused as a declaration that types
the symbol rather than calls to it. `(-[nondet,readOnlyLookup]-> Number
Number)` publishes `(effect f nondeterministicReadOnly)`, because a `nondet`
product joins its class with that one. Both slots must be CONCRETE: a `$name`
in either is refused at the declaration, because a product variable has no
runtime consumer, and so are a nested product and an annotation on a
translated form. A plain `->` is `(-[nondet,oracleIO]->)`, which is why it
promises nothing. `(pragma! verify-cardinality true)` is what turns a
determinism claim into a runtime check; without it the claim is trusted.
`(: Count (Alias Number))` defines a transparent structural alias. Aliases
expand inside tuples and full arrows in their declaration owner's scope;
reflection retains the written declaration. An alias of `Atom` preserves
the same argument mask and result finality as `Atom` itself.
`(| Number String)` is a union type, usable wherever a type goes: an argument,
a result, a tuple field, an alias right side. A value is admitted when SOME
member admits it; a value whose own type is a union is admitted only when EVERY
alternative is, under one assignment of the type variables they share, so
`(| Number String)` fits `(| Number String Bool)` and not `(| Number Bool)`.
Nested unions flatten, a repeated member is one member, a one-member union is
that member, and `(|)` or an improper union raises a type-syntax error rather
than standing as a type nothing satisfies. `|` heads a union only where a type
is read: `(|-> ($x) ...)` is still a lambda and `(| a b)` is still data.
`Atom` and `%Undefined%` keep each family's own meaning inside a union, and a
union naming `Atom` is an ordinary evaluated, checked parameter rather than an
evaluation mask. Testing a union-typed value does NOT narrow it: there is no
occurrence typing, so a later use still faces the whole union. `match-types`
and the `type-cast` built on it compare written types by identity and do not
decompose a union; union membership is the argument and
result relation.
A typed mismatch answers an `Error` value whose reason is `BadArgType` or
`IncorrectNumberOfArguments`, so a MeTTa program can handle it with `if-error`.
A REFINEMENT is a constraint on the value inside a type: `(Annotated Number
(Gt 0))` is a Number that is greater than zero, and `Annotated[int, Gt(0)]`
with the `annotated_types` vocabulary declares exactly that arrow from a
signature, because each constraint class encodes to the atom of its own name.
`metta.vocabularies.Refinement` names the heads the engine decides: `Gt`,
`Ge`, `Lt`, `Le`, `Interval` (as `(Interval (ge 0) (le 1))`, the bounds that
were written), `MultipleOf`, `MinLen`, `MaxLen`, `Len` (as `(Len 2)` or
`(Len 2 5)`), `Predicate`, `Unit` and `Literal` (as `(Literal 1 2)`, from
`typing.Literal[1, 2]`, whose members split by base type, so
`Literal[1, "one"]` is `(Annotated Number (Literal 1))` or
`(Annotated String (Literal "one"))`); `doc(...)` and `Timezone(...)` travel in
the annotation claim and never reach the type. A refined parameter accepts a
value whose declared type unifies with the whole refined type, or whose type
admits the base while every constraint holds on the value; a value the base
admits and a constraint refuses answers ONE `(Error <call> (BadArgValue
<position> <constraint> <value>))`, the first violated constraint of the first
violating position, and a base mismatch keeps `BadArgType`. A refined RESULT
type, `-> Annotated[int, Ge(0)]`, is checked at the return crossing and
answers `(Error <call> (BadReturnValue <constraint> <value>))`; a bare result
type mismatch stays the silent branch failure it always was. `MinLen`,
`MaxLen` and `Len` read a string's length, an expression's child count and a
host sequence's length; `Gt`, `Ge`, `Lt`, `Le`, `Interval` and `MultipleOf`
decide native numbers and host numerics through the seam; `Predicate` applies
its function to the value, a defined head through its equations and a Python
callable through the seam, and holds when the answer is True; `Unit` is a
declaration, decided by unification between declared types and never against
a bare number; `Literal` holds when the value is identical to one listed member,
binding nothing, so `1.0` is not a member of `(Literal 1)`. An `%Undefined%`-typed value is not waved through a refinement
the way the gradual rule waves it through a plain type: the constraint reads
the value, so `(a)` fails `(MinLen 2)` on its length. A constraint head
outside the vocabulary, `(Shape ...)` included, is admitted only by declared
type unification, exactly as before the vocabulary existed. The rules are one
clause per head in `engine/metta/refinements.pl`, and the catalog's
`(vocabulary refinement ...)` row names the same twelve heads.
`(add-typing-rule! name family actual expected outcome)` adds a module-scoped
checker rule; `outcome` is `Accept`, `(Refuse reason)`, or `Defer`, and
`remove-typing-rule!` withdraws it. Families are `ordinary`, `derived`,
`reporting`, `witness`, `arrow-arity`, `widening`, `declared-widening`, and `metatype`.
User rules run
before the shipped declarations. A named refusal appears in the resulting
`BadArgType`; the confluence report lists its user/user and user/shipped
overlaps as conditional proof obligations.
`m.infer_types()` proposes a `(: head (-> T1 .. Tn R))` for every head the
space mentions and never declares, and adds nothing; `m.infer_types(declare=
True)` adds exactly those atoms, after which `get-type` answers them and there
is nothing left to propose. It reads `pandas.api.types.infer_dtype`'s question
of an argument position instead of a column: the NARROWEST kind covering every
child observed there. All numbers `Number`, all strings `String`, all booleans
`Bool`, all symbols `Symbol`, all expressions sharing one head that head's
declared result when it has one and `Expression` otherwise, several kinds
`Atom`. A variable stands for anything and so constrains nothing, `infer_dtype`
's own `skipna`, and a position with nothing left to go on is `%Undefined%`.
An equation head's RESULT is what its body answers: a literal's own type, or
the declared result of the head the body calls, so `(= (double $x) (* $x 2))`
proposes `(-> %Undefined% Number)`; anything else, a bare symbol included, is
`%Undefined%`, since a symbol's own type is. A head mentioned at two arities is
two proposals. Read the `Atom` case before accepting one: `Atom` in an argument
position is a metatype and masks evaluation there, so accepting a mixed
position's proposal turns `(f (+ 1 2))` from `3` into the term `(+ 1 2)`. That
is why proposing and adding are two calls. Cost is O(atoms x arity), one pass
plus one type lookup per distinct head. A foreign space that declines
`enumerate` refuses, and `declare=True` on a space that refuses writes refuses
through the write path. `inspect.signature()` and `metta.stubs()` show the same
arrow for an undeclared head, marked `(inferred from stored atoms, not
declared)` in the docstring, without adding it; `python -m metta doc --infer
prog.metta` prints the proposals for a program.

`m.cast(value, type)` returns the value or raises `CastError` naming the types
the value does admit. Its bound type observation uses `witness`: the wildcard
applies to the target only, so an unknown actual cannot establish a concrete
target. This is stricter than ordinary typed-call acceptance. Aliases inherit
that rule and ordinary user refusals. An `Annotated` target casts against its
refined type, `m.cast(1, Annotated[int, Gt(0)])` answers `1`, and a value the
base admits and a constraint refuses raises `CastError` naming that constraint
and the value. `Atom`, `%Undefined%` and `_` are unchecked. The
metatypes `Atom`, `Variable` and `Expression` mask evaluation: a parameter
declared with one receives its argument as written at every door, and a call
whose declared result is the metatype `Atom` answers as produced where any
other declared result re-enters evaluation, so `!(car-atom ((+ 1 2) b))` is
`3` and a caller that wants a call's value in a masked position names it
first with `let`. Minimal MeTTa's `eval` is one equality step over retained
source equations; NotReducible is a control result only `function` and
`metta-thread` observe raw (`chain` is `let` and sees what `let` sees), an application boundary retains an
irreducible call as written, and a function frame distinguishes a produced
marker from an irreducible body. A user type
declared with `(: Payload DontEvalType)` is also an evaluation mask: a function
parameter of type `Payload` receives its written argument unevaluated. The
declaration is required; no type-name convention enables the behavior. A float
or signed-i64 integer has type `Number`; a wider integer has type `BigInt`. A
`BigInt` satisfies a declared `Number` parameter, while a `Number` does not
satisfy `BigInt`. Arithmetic stays exact and result typing follows the result
width. `bool` spells `Bool` before `int` is classified by that boundary. The
target is positional-only, and a concrete Python class target is also the
static return type of `cast`, `convert.build` and `Rows.build`.
An expression with no arrow-typed head is typed element by element. Once its
head has an arrow, the arrow controls the application: an under-applied call
has no type answer and does not fall back to a tuple type.
The empty expression is the unit value: `get-type` and `get-type-space` report
its type as `(->)`. That is an observer rule; argument checking continues to
treat `()` as gradual rather than forcing a unit-type constraint.
A state cell has type `(StateMonad $t)`: `(new-state 0.4)` is
`(StateMonad Number)` and arithmetic on it is a `BadArgType`, so a cell is
dereferenced with `get-state` before use. `get-metatype` classifies a NAME by
whether this engine holds a function for it, so it answers `Grounded` for
`car-atom`, for a literal, and for a name the running program has just given
an equation, and `Symbol` for `nop`, `hyperpose`, `sealed`, a name nothing
defines, and every space handle and state cell, `&self` included. What a
handle or a cell IS is read with `get-type`, which answers `SpaceType` and
`(StateMonad $t)`.
`metta.State[T](value, space=None)` is the Python handle: `.value` reads and
writes the same engine cell, `__metta__` carries it across any atom boundary,
and the write answers `true` rather than the cell. Because a cell is an
ordinary atom it also serves as a mutable TAG, so an algebra that dereferences
it reads the current weight on every match.
`m.arities(name)`, `m.is_function(name)` (registered as a function anywhere in
this engine, the translator's call-or-data question), `m.is_function_here(name)`
(has clauses HERE), `m.builtins()` (every function callable from this space,
its own, inherited, `&self`'s shared ones and the engine's builtins, plus every
translator special form, sorted without duplicates; a head another space
defines is not listed); each is a `Space` method, so any space handle answers
for its own view, and `dir(m.fn)` is the same list spelled as attributes.

## Declarations: how a space behaves, written as atoms

Each head-named method below writes one atom into `&metta` and returns it;
removing that atom withdraws the declaration. Coherence is checked eagerly in
the same transaction as the write, so a new entry that could disagree with an
existing one fails there, naming both, rather than on the first query in their overlap.
A variant-identical `(: name type)` row is likewise refused and names the first
row; distinct arrows for one function remain valid overloads. A public batch
is checked before its first write, so `m.add(declaration, declaration)` leaves
neither copy behind.

The generated declarations above own the signatures; these notes explain the
declarations' behavior.

```text
m.handles:
        how faithfully a space answers one query shape. Exact licenses pushing
        the caller's bound down to the provider; Partial and Sound stay
        candidates the engine re-unifies; Refuse makes the query a loud error
        instead of a silent partial answer. (in $x) at a position matches only
        queries arriving with it bound, so a scan-only source is three words.
m.emits:        answer order
m.merge:        how answers merge
m.consumption:  consumption discipline; writes (source <space> <kind>)
m.atomicity:    the strength of a write's atomicity promise
m.context:      what absence means
m.on_error:     how a provider failure is delivered
m.image:        how values cross
m.algebra:
        add one catalog algebra. type= accepts a Python type, a MeTTa type atom,
        or a predicate returning one bool, and checks every input and result.
        A type alone grants no law certificate or answer fusion. Only an explicit
        finite carrier= permits exhaustive equational-law checking; it is the
        complete domain, never samples. Tensor membership and law equality use
        exact shape and element values. Claiming any law, including contraction,
        without a finite carrier
        is refused: declare one for a certificate, or use prov and .under() to
        reinterpret the retained derivation.
        A declared algebra is OWNED BY THE SPACE THAT DECLARES IT: the row's
        last field is that context, and lookup reads it before falling back to
        the shipped presets, whose owner is `global`. The same key annotations
        use, so a sibling space does not inherit it. Equational checking runs
        in the declaring space's equation module, so a MeTTa equation defined
        there certifies the algebra that names it. drop() retires the row and
        its law certificate together with all space-owned catalog declarations;
        a reused named or pooled space starts clean. An operation returning an
        Error is refused as algebra_operation_error, never used as a tag.
metta.algebra(name, *, plus, times, zero, one, laws=(), carrier=(), type=None,
              requires=(), order=None, negate=None, saturated=None,
              variable=None) -> DeclaredAlgebra
        construct an arbitrary algebra through the callable `metta.algebra`
        module, whose plus and times (`combine=` and `extend=` name the same
        pair) may be plain Python callables; called with no name it decorates
        a class whose attributes carry those fields and whose name it takes,
        and a shipped carrier's name answers that carrier. It targets
        the space `metta.current_space()` names, so inside `with scratch:` the
        row is owned by `scratch`. Thirteen carriers ship, tabled under `under=`
        above, and each is also an object
m.annotations:
        choose any declared algebra for this space or an operation; required
        capabilities are checked before the catalog row lands. This row is
        keyed by the same context the algebra row above is owned by
m.add_tagged_fact: store ordinary (fact tag proposition)
m.add_tagged_rule: store the generic threaded rule form
m.match / m.answers / m.eval:
        under= selects the algebra of their annotated answers
m.sample:
        stable weighted selection from nonnegative `(rate n)` tags
m.admits:       only TYPE-carrying atoms enter
m.capacity:     an add beyond LIMIT is refused loudly
m.reacts:       stored as an (on ...) atom
m.agenda:
        which reaction fires first when several match one write. declaration
        is the default and the order they were declared; user names a MeTTa
        function that SCORES a reaction. Every policy ties on declaration
        order and an undeclared priority reads as 0.
m.events:
        what a foreign context's change events promise. Subscribability is a
        promise about the context, not an inference from its write methods: a
        context that declares nothing refuses subscribe, bridge and reaction
        naming the missing capability. A Python provider says the same thing
        by overriding delivers(); a native space needs no declaration.
```

`(cache name policy)` has no Python verb, by the memoisation ruling: it is
written as the atom, `m.run("!(add-atom &metta (cache f monotonic))")`, and
read back by `match`. The policy is the `cache-policy` vocabulary
(`metta.vocabularies.CachePolicy`), one word or a list of them, and
`lib_tabling` compiles it to SWI's own table option list; `TabledMap.stats()`
and `(table-stats (f $x))` answer the words in force as `policy`. Each word
and what it costs, with `add-atom` to a space the body reads as the write and
N the table's answers:

- `plain`: table, watch nothing; a write leaves the table stale until
  `table-clear`. Read O(1) per answer.
- `incremental` (the default a bare `tabled` builds over a body the engine can
  watch): a write invalidates, the next call re-evaluates the body, O(N) per
  write [measured 2026-09-07: 1,969 to 9,345 inferences per write-then-read
  over chains of 50 to 400 links].
- `monotonic`: a write propagates its consequences, the next call is a read,
  O(1) per write for a chain [measured 2026-09-07: 863 to 871 inferences
  over the same chains]. The body must be monotonic: no absence made an
  answer. A `remove-atom` falls back to re-evaluation.
- `lazy` (with `monotonic`): compiled and reported as written; on SWI
  10.1.13 the propagation still lands at the write and the table only reads
  invalid until its next use, so it buys nothing measurable here.
- `shared` (default) / `private`: one trie between engines, or one per engine.
  A shared table refuses calls inside a transaction or snapshot, including
  calls compiled before it was tabled. Its trie can expose uncommitted rows
  to another thread on SWI 10.1.13. Write `(cache f (incremental private))`
  for a watched table inside a transaction; keep other explicit policy words.
- `subsumptive`: a specific call answers from a completed more general table;
  cannot watch a read on this SWI, so over a body that reads a space `plain`
  must be written.
- `(lattice join)`: one aggregated answer per input, joined by the
  two-argument function named, which is how shortest paths over a cycle
  terminate; `private` and `plain` by default, for the same SWI reasons,
  and refused with `shared` or a watch.
- `(max-answers N)`, `(subgoal-abstract N)`, `(answer-abstract N)`: bounds
  the table declares for itself; tripping one raises `RestraintError` on
  this side and is uncatchable from MeTTa.
- `force` / `refuse`: `lib_memo`'s word about the automatic memo, alone in
  its row.

A policy the engine cannot honour is refused at the write with the remedy
named and the row never lands: a watch over a body the effect walk cannot
classify (write `plain`), a foreign read under a watch, a second watch on a
space predicate another table already watches (one predicate carries one
watch; both at once re-evaluates the monotonic reader on every write), `lazy`
without `monotonic`, two words of one class, a shared or watched `lattice`,
a watched `subsumptive`, a bound that is not a non-negative integer, a join
that is not a visible function of two inputs. `untabled` under a standing row
refuses too; the row is the declaration, remove it.

`(cost witness class)` and `(cost witness class measure)` have no Python verb
either, by the same ruling: `m.run("!(add-atom &metta (cost (nrev $n) quadratic))")`.
The witness is a CALL with exactly one size hole `$n`, and the class is the
`cost-class` vocabulary (`metta.vocabularies.CostClass`): `constant`, `log`,
`linear`, `linearithmic`, `quadratic`, `exponential`. The row is Ciao's
`:- check comp nrev(A,B) + steps_o(length(A))` with the same size measures,
except that CiaoPP proves it from inferred bounds while here the `cost-rows`
gate MEASURES a ladder of sizes and fits it. A repeated hole is one hole:
`(cost (intersection-atom $n $n) linearithmic)` sizes both operands together.

The measure is optional and the engine derives it from the head's arrow at the
hole's position: `Number` gives `int`, the VALUE of `$n`, and everything else
gives `length`, an expression of `$n` children. Name it in the fourth field
when the arrow does not decide it. `(explain (<head> ...))` answers
`(cost <class> <measure>)` for a head with a row, and `help()` on the bound
function shows `cost: <class> in $n (<measure>)` with the ledger's measurement
date, or `declared` where no ledger is on disk.

Refusals, all at the write: a witness with zero or two holes, a witness that is
not a call, a second row for one head (`remove-atom` the standing row first),
and a class outside the vocabulary. The lane refuses more, by name rather than
by fitting nothing: a head it cannot call, a measure it builds no ladder for,
and `constant` or `log` over a `length` measure, since a call that receives an
expression of n children cannot cost less than reading it.

Ten rows ship. `(+ $n 1)` is constant; `car-atom`, `cdr-atom`, `size-atom`,
`union-atom` and `union` are linear; `intersection-atom`, `intersection`,
`subtraction` and `alpha-unique` are linearithmic, each building an association
tree of one operand and looking the other up in it where `union-atom` is an
append. `unique` and `unique-atom` deliberately carry NO row: `list_to_set/2`
sorts in C, so the engine's inference counter reads them linear while retired
instructions read them linearithmic, and a row would state the cheaper of the
two.

### Bounds, and the shape of a head's result

Every bound this seat decides is a `(limit <name> <value>)` row in `&metta`,
published once per engine from `metta.config`'s own table and read back from
the row afterwards: `chunk-cap` (the largest chunk one crossing carries),
`subscription-queue` (undelivered events one subscription holds),
`repr-items` (items a container's repr shows), `display-rows` and
`declaration-limit`. So `!(match &metta (limit $name $value) ($name $value))`
is what the bounds ARE, `!(add-atom &metta (limit display-rows 5))` changes
one, and `metta.config.display_rows` answers the row. `configure()` writes the
row as well, leaving exactly one behind, so the two cannot disagree.
`stack_limit` and `heartbeat_interval` are NOT rows: they are arguments to the
boot that creates the space the rows would live in, and they freeze once it
has run. Cost: none. A cursor reads its chunk cap when it OPENS, so the rows
are MIRRORED in the seat rather than consulted per read, and the engine keeps
the mirror in step: `seam:catalog_row_changed/2` announces every `(limit ...)`
write, so a MeTTa program's own `add-atom` reaches every cursor opened after
it. Consulting the catalog per read instead cost 21 inferences and 3.2 of the
35 microseconds a one-answer `match` takes; watching the head costs 1
inference on a `&metta` write and nothing anywhere else (measured 2026-09-08
by `extensions/python/benchmarks/probes/bound_row_cost.py`). That point is
general, not the bounds table's own: `spaces:watch_catalog_rows(<head>)` turns
it on for any catalog head, and EXTENDING.md's "Mirroring a catalog row you
read on a hot path" is the worked example.

What SHAPE a head's result has is the `typing` seam point.
`seam.typing.register(<kind>, equations=(<template>,), doc=...)` adds a rule
KIND, whose equations are TEMPLATE atoms carrying `$head` where the head goes
and `$arg1`, `$arg2`, ... where the row's own arguments go;
`metta.typing.declare(space, head, kind, *arguments)` writes the
`(typing <space> <head> <kind> <arg>...)` row, adds the instantiated
equations, and answers the inverse, and `metta.typing.withdraw(space, head)`
is the same inverse from the row alone. The rules are a shape ALGEBRA over any
indexed carrier rather than anything about arrays: `metta_arrays` registers
twenty-one kinds (`preserve`, `broadcast`, `reduce-all`, `concatenate-axis`
and the rest) and declares a row per head, and a library whose carrier is a
dataframe registers `column-select` the same way. The row dies with its space,
which `(owned-by-space typing)` in the catalog is what arranges.

## Observability

The generated declarations above own the door signatures. The notes below
describe their result objects and execution behavior.

```
m.trace: Trace of TraceEvent
        (seq, time, depth, kind, term, answer). seq numbers the recorded events
        from 0 and time is the WALL nanoseconds since the run began; time is
        outside equality, so two traces of one program compare equal
        kinds "call", "exit" and "fail": a reduction reaches exactly one of
        exit (once per answer), fail (it answered nothing), or neither (a bound
        cut the run). answer is None on every port but exit
        a memoised head records the calls its CACHE answers too: the memo
        declares its dispatcher through seam:interposed_dispatch/4 and each
        reduction is recorded once, by whichever layer the call entered first
        Trace is a list; .stopped names the bound that cut it, one of
        Limit.events, .memory, .inferences, .timeout and .stack, or None when
        the run finished; .truncated is the yes-or-no reading of the same fact
        max_events bounds the RECORDING, timeout and inferences bound the RUN;
        either way the events recorded so far are answered, never discarded
        filter= names the functions to record, before those bounds apply, and
        takes a symbol, a string, a bound handle like m.fn.double, or several
        `(with-seed S expr)` scopes a draw's seed in MeTTa; `m.record` captures
        a seed for its complete run
m.debug: Debugger of Stop
        breakpoints, suspension, stepping, resume. Iterating runs the program
        to each breakpoint; the loop body is where it is SUSPENDED and leaving
        the body resumes that same execution. on= names the functions that stop
        it, `d.step()` stops at the very next reduction and lasts one advance,
        `d.breakpoints` is a live set, `d.stop` is where it is halted now, and
        `d.answers` is what the program produced.
        at= is a COUNT breakpoint: it stops at the event with that sequence
        number, the numbering a Recording indexes by; a negative one refuses
        Close it or leave its with-block: a session holds a wrapper on every
        compiled function until it does. No timeout, by design; inferences
        bound the whole session so a resume cannot run forever
        a Stop carries the same six fields a TraceEvent does, plus .function
m.record: Recording
        the run kept as DATA: the events plus the state that produced them, so
        they are re-runnable and not only readable. rr's shape, where the
        nondeterministic input is recorded once and the replay is deterministic
        Recording(program, space, digest, seed, bound, engine, events,
        replayable, reason, live), `live` being the Space it was recorded in
        and None once loaded; len(rec) is the event count and rec.events the
        Trace. A recorded run ALWAYS has a seed, minted when you name none
        navigation, all over recorded data and none of it re-running the
        program: rec.at(k) -> Frame (negative k counts from the end, one
        outside the range raises IndexError), rec.seek(k), rec.back(),
        rec.forward(), rec.position, rec.stack(k), rec.find(head) -> Frames
        Frame(index, seq, time, depth, kind, term, answer, stack); stack is the
        chain of open calls, outermost first, ending with this event's own term
        rec.save(path) -> event count, Recording.load(path); the file is wire
        JSON, named `<something>.metta-rec.json` by convention, gzipped when
        the name ends `.gz`, measured 2026-09-07 at 55 bytes an event and 9
        gzipped over a 2,438-event recording. A file another engine version wrote
        loads and warns (RecordingVersionWarning); one that is not a recording,
        or holds a layout this reader does not know, refuses by name
        rec.replay(space=None) -> Trace re-runs under the recorded seed and
        compares event by event, answering the replayed Trace or raising with
        the FIRST event that differed. It asks every library to forget what it
        derived first, so the replay starts where the recording did; that
        forget is the ENGINE's, not one space's, and it drops cached ANSWERS
        while keeping every cache decision
        rec.debug(space=None, *, at=k) -> Debugger already stopped where event
        k is, `d.stop` being that event; it verifies it landed there
        replayable is False, with reason, when the program reaches an oracleIO
        operation no seed pins (`py-atom`, `current-time`, `readln!`); a draw
        is replayable, because the seed captured it and the engine declares
        which oracleIO operations that is true of through seam:seeded_operation/1
        replay() and debug() then refuse; the events stay readable either way
        replay refuses a space whose digest() differs from the recording's, and
        a LOADED recording has no live space, so it wants one as the argument
metta_otel.spans(trace, *, tracer, space=None, start_time=None, parent=None)
        one BACK-DATED OpenTelemetry span per recorded reduction, nested by the
        events' own depth and carrying the times the engine recorded rather than
        the times the spans were built. `trace` is a Trace or a Recording, which
        knows its own space. A call opens a span named by the HEAD (a span name
        is low-cardinality) with the attributes `term` (the canonical text),
        `depth`, `seq` and `space`, each under the `metta.` namespace; its exit
        ends it with `answer`; a `fail` ends it ERROR with `exit=fail`; and a
        reduction a bound cut ends where the trace does with `exit=absent`
metta_otel.observe(m, *, tracer=None, meter=None, name="metta",
        max_events=None, filter=None) -> Trace
        a with-block. With a tracer it holds the engine's ONE trace session for
        the block, so every compiled reduction in it becomes a span under one
        span named `name`; with a meter the block's `m.stats()` deltas become the
        four histograms `inferences` (1), `cputime` (s), `gc.freed` (By) and
        `table_bytes` (By), under that same `metta.` namespace and attributed
        with the space and `name`.
        Neither given refuses; either alone works, and a meter alone arms nothing
        The yielded Trace fills in as the block ENDS, `.stopped` naming the
        recording bound if one cut it. That bound stops the RECORDING and never
        the observed work, which is the caller's; a trace's bound stops its run
        Spans are emitted at the block's end because the engine's tracer does not
        stream; they carry the true times, which is what back-dating is for
        A trace or debug session inside an observed block refuses, and observing
        inside one of those refuses naming the same rule: one session holds the
        wrappers. Needs pymetta[otel], which installs metta-otel, whose one
        dependency is the OpenTelemetry API package
        The `metta.*` loggers need no code here: attaching
        opentelemetry.sdk._logs.LoggingHandler to logging.getLogger("metta")
        puts every engine, transport and provider message in the same pipeline
m.derivation: list[Derivation]
        proof trees in MeTTa terms: .rules, .facts, .complete, .truncations
m.why:         one empty match explained in words
rows.why:      pattern miss, failed join, or rejecting guard
m.lint:        the silently-wrong class, from stored structure
        `# metta: ok(<kind>)` on a statement, or on the line above the lint
        CALL to cover a space built entirely from Python, suppresses that one
        kind there; it is kept as a (lint-intent ...) atom, not dropped as a
        comment
        a Finding carries `.remedy`, the same Remedy the errors carry, beside
        `.autofix`; `duplicate-equation` removes, the six simplifications
        rewrite, and `possibly-undefined-reference` renames to its near miss
metta.lint.lint_file(path, *, m=None)   the same findings anchored to file:line
        with the sha256 of the bytes read, which is the document version
metta.lint.apply(space, findings=None) -> Repair   writes every `machine`
        remedy into the space, remove-then-add; `.applied`, `.skipped` (each
        with its reason) and `.remaining`
metta.lint.fix_file(path, findings=None, *, m=None) -> Repair   the same repair
        over the file, rewriting only a line that still holds exactly the
        form; refuses the whole file when its digest moved
metta.lint.diagnostics(findings) -> list[dict]   LSP 3.17 Diagnostics,
        zero-based, the remedy under `data`
m.effect_plan: EffectPlan(operations, effect), translates and follows
        nested compiled calls without executing the target
m.explain: Explanation
        SQL's EXPLAIN over this engine's decisions for one query, as the atoms
        the MeTTa form `!(explain <query>)` answers. A match form answers
        handles, pushes, source, context, annotations, emits, events, writes,
        on-error, merge, materialized and PLAN; an operation call answers
        effect, inverse, annotations, on-error, origin and visibility, plus
        the memo's cache decision for a compiled function and the op row for
        a registered operation.
        Explanation is a Mapping from each item's head to the whole item atom,
        with .plan, .route (the handles item), .atoms (every item in order,
        which is what a space stores) and .analyzed
        The plan item names the join the matcher RUNS, not the one the query
        shape allows: `(plan generic-join (order $x $y $z) (relations (edge 1 2)
        (edge 2 3) (edge 1 3)))` when the Generic Join answers it, `(plan
        nested-loop (order <conjunct> ...))` naming the conjunct the retained
        loop leads with, `(plan empty-factor <conjunct>)` when one conjunct has
        no candidate. Deciding costs the query's shape plus one scan of each
        conjunct's relation, because a conjunction whose stored rows are not all
        ground declines the plan; nothing is sorted and no trie is built, so
        explaining a triangle over 2,048 stored edges cost 7,362 inferences
        against the query's own 237,341 [measured 2026-09-25T22:18:09+10:00:
        extensions/python/benchmarks/probes/explain_plan_cost.py]
        analyze=True adds (inferences N), (answers N) and (cputime S), measured
        by running the query inside stats(). It REFUSES a query whose named
        operations write, because an analysis that mutates is not an analysis;
        allow_writes=True measures it anyway. A match TEMPLATE is evaluated, so
        `(match &s (edge $x $y) (add-atom &s (seen $x)))` is a writing query
rows.explain: Explanation
        the same, over the match form a query result came from. The lazy view
        pulls nothing to answer it. A `where=` guard is not part of it: a guard
        filters answers after the match and does not change which join runs
m.eval_status / m.run_status: each answer paired with the path that
        produced it: "value" (equation, builtin or special form applied),
        "not-reducible" (no rule applied, the answer is the term itself),
        "empty" (branch pruned, answer None). A pruned branch and an unevaluated
        term are different things the answers alone cannot tell apart.
m.stats:       with-block yielding .inferences (deterministic, gate on this),
               .cputime, .walltime, .gc_count, .gc_freed, .gc_time, .table_bytes,
               .heartbeats
        .inferences is the BLOCK's work: the engine's interrupt poll, which
        crosses into Python every config.heartbeat_interval inferences so a
        Ctrl-C can land, costs inferences of its own and they are taken out,
        with .heartbeats saying how many times it ran inside the block. A
        thread the block JOINS is counted, because SWI adds an exited thread's
        inferences to the thread that waited for it; a detached one finishing
        beside the block is not; and a joined worker whose answer the block
        did not use, a race's losers, a cancelled thread-backed future or
        timer, the branches par-any or par-forall stopped, is taken out again,
        so the count is the work that produced the block's answers, one
        integer rather than however far the schedule let a stopped branch run
        A spawned future runs as a scheduler engine that is never joined, so
        its spin never reaches the block, but cancelling it costs the caller
        27 inferences more when the task is still queued than when a carrier
        is running it, and the schedule decides which
        Known issue: a race pulled through a streaming door, such as race() or
        a fn call, is counted partly inside that door's held engine, and that
        part varies with the schedule, so the count is not one integer; the
        same race through run reads one
        The door itself costs 7 inferences of the block it measures, which is
        constant and therefore cancels out of any comparison
m.profile:     (groups, EngineProfile), per predicate
        EngineProfile: .samples, .ticks, .seconds, .nodes (Rows over predicate,
        calls, redos, ticks_self, ticks_siblings, file, line, seconds_self,
        seconds_total, name, arity, recursive_calls), .top(n), .as_stats()
prof.as_stats() -> pstats.Stats   the same profile in the currency every Python
        profile viewer reads: .sort_stats("cumulative").print_stats(), and
        .dump_stats(path) writes what snakeviz and tuna open. The key is
        (file, line, predicate), so a row is navigable; a redo has no pstats
        column, so .nodes stays the door for choice-point cost
m.profile_extension: only the selected extension's functions
m.fn[name].origin -> tuple      where each clause of a head was written, in
        clause order: Origin(file, line) per compiled clause, or None in that
        position for a clause with no source. A `.metta` head answers the file
        and the line its equation sits on, a Prolog-registered head answers
        what clause_property/2 recorded, and a head defined from Python text
        has None. A special form has no clauses and answers (). Reading a
        `.metta` line reads and parses that file, so this is a diagnostic
        rather than a lookup. S["car-atom"].origin and metta.fn.car_atom.origin
        ask the same question of the ambient space
m.prolog:                     the engine's own interactive toplevel
metta.engine().info() -> {metta, janus, swi_prolog, python, metta_path, actor,
        next_generation}: the four versions, the engine tree it consulted, the
        engine's actor id and its next occurrence generation
```

The engine's messages are `metta.engine` log records, so the tool a Python
program already configures filters and formats them. SWI's kinds map to
levels: `error` to ERROR, `warning` to WARNING, `informational` to INFO,
`debug(Topic)` to DEBUG, and `silent` is dropped. Each record carries
`metta_kind`, and `metta_file` and `metta_line` when the message has a source
location. The bridge ADDS a reader: SWI still writes its own line to stderr,
because a message hook that claimed the message would silence the engine. It
covers the thread the library drives the engine on; a message emitted on a
Prolog worker thread prints without a record. `metta` carries the library
author's `NullHandler`, so a program that configures nothing stays quiet.

The three doors that run host code raise `sys.audit("metta.host", door,
payload)` before the effect, so an `addaudithook` hook can watch or refuse:
`("py-atom", source)` for the expression form of `py-atom`, `("load", path)`
for `Space.load`, and `("compile", qualname)` for a Python function compiled
into equations. The name form of `py-atom` needs none of its own, because
importing raises `import` already.

A refusal from a namespace, a projection or a module carries
`AttributeError.name` and `.obj`, so the interpreter's own "Did you mean"
appears beside the library's sentence. CPython fills both itself for anything
raised out of `__getattr__`; the bracket and method doors (`fn["car-atmo"]`,
`answers.column("wha")`) are not attribute access and would otherwise carry
nothing.

Errors: `MettaError` is the base. Under it sit `MettaSyntaxError`,
`CastError` (also a `TypeError`), `CompileError`, `SourceNotFound` (also a
`FileNotFoundError`), `RegistrationError` (also a `ValueError`),
`MettaResultError`, `AssertionFailure`, `TransportFailure`, `SubscriberError`,
`LockDrift`, `Timeout` (also a `TimeoutError`) and `EngineError`, and under
`EngineError` sit `Interrupted`, `MettaOperationError`, `SpaceCapabilityError`,
`PlatformCapabilityError` and `ResourceLimitError` with `TimeLimitError`,
`InferenceLimitError`, `RestraintError` and `StackLimitError` under it.
`NotReducible` is outside the family, since it is a signal rather than a
refusal. Every refusal this library makes on purpose carries
`.remedy` and `.ground` beside its message, and the message never changes
for their presence. `metta._errors.errors.Remedy(title, kind, applicability, edit=,
replace=, python=)` is the repair as data: `kind` is LSP's CodeActionKind
(`quickfix`, `refactor`, `source`), `applicability` is rustc's
(`machine` is definitely right and is applied without asking, `maybe` is
valid but may not be what was meant, `prose` carries `<placeholders>` for a
human), and the repair itself is `edit` (an atom to write), `replace` (a
stored atom and what it becomes, `None` in the second position for a
removal) or `python` (the host text to write instead). A Remedy naming none
of the three refuses at construction. `metta._errors.errors.Ground(kind, citation)`
is the authority: `host-reference` the host language's own specification,
which here is a Python Language Reference section, `metta-law` a named law,
`arbiter` a measured answer of upstream PeTTa under
`tests/conformance/petta/`. Both are frozen, slotted, pattern-matchable, and
project to `(remedy ...)` and `(ground ...)` atoms through `as_atom()` and
back through `from_atom()`. A refusal Python's own word covers is still a
`TypeError`, `AttributeError` or `ValueError`, and carries the two fields on
the instance, so `getattr(error, "remedy", None)` is the one reader. Whichever
class it wears, the message is the sentence the engine composed and never the
reserved envelope around it, so a repeated JSON key reads `JSON object repeats
the key a` rather than naming a term.
A deprecation's catalog remedy term decodes the same way: the
DeprecationWarning instance carries `.remedy` with the term as its `edit`. `RestraintError` is a bound the program declared for one of its
own tables, `(cache f (max-answers N))` or a size restraint, tripping; it
carries `restraint`, `bound` and `call`. `RegistrationError` is a
registration of Prolog as MeTTa functions its contract refuses, a `ValueError`
too, carrying `requires`, what the registration lacks: the names to register,
a declaration in the source, or a file origin for a rename.
Remote-backend authors use `metta._errors.errors.is_transport_failure(error)` to
classify an absent connection, timeout, or closed stream before choosing retry
or abandonment; ordinary application errors answer false.
`AssertionFailure` means a `(test ...)` or `(assert ...)` claim was false, not
that the engine broke; `.operation`, `.actual`, and `.expected` are structured
fields for a harness. A failing comparison over ANSWERS adds `.missing` and
`.excess`, the answers expected and never produced and the answers produced
and never expected, each a tuple of atoms carrying bag multiplicity; the
message carries the same two lines. Both are `None` where the failing form
computed no such difference, which is a different answer from `()`: two empty
bags say the answers agree and differ only in ORDER, which is what
`assertEqual` fails on while `assertEqualToResult` accepts it.
`Rows.raise_for_errors()` and `Answers.raise_for_errors()` are the explicit
bridge from `(Error culprit reason)` values to `MettaResultError`: one raises
plainly, several as an `ExceptionGroup`, and a clean collection returns itself
for chaining.
`MettaOperationError(EngineError)` is a builtin refusing a value, with the parts
as data: `.operation` is what the source wrote (`+`, `min-atom`), `.kind` the
formal's functor, `.expected` and `.culprit` the type and offending value.
WHICH class a Prolog-side refusal becomes is decided engine-side rather than by
reading its message: `engine/metta/registration.pl` declares one kind word per
refusal a host can act on differently (`syntax`, `time_limit`,
`inference_limit`, `restraint`, `interrupted`, `value`, `type`, `assertion`,
`capability`, `platform`, `operation`, `stack`, `source`, `registration`, and
`engine` for a ball it did not shape) with the fields each carries, and reads
one off a raised ball. Every kind renders as its own sentence wherever a seat
shows the engine's message text, a signal without the envelope's framing.
`tests/data/error-kinds.json` lists them with the class each seat raises, and
each seat's suite reads that file against its own map. This seat's
`_EXCEPTION_TYPES` is derived from the rows below through the generated table
and names a class for all fifteen kinds; `assertion`, `capability` and
`operation` are taken apart by classifiers of their own, and every other kind
arrives as the class its row names, read off the ball, with that kind's fields
as the class's keywords. The Node seat maps all fifteen.
Each kind is also a ROW in the `&metta` catalog, `(refusal <kind> <class>
(ground <authority> "<citation>") (remedy "<title>" <kind> <applicability>
<act>...))`, and the rows are what a seat READS rather than what it keeps a
copy of: the class name is the seat-independent one, the ground is the
authority the refusal stands on (`metta-law` for a law this engine states,
`arbiter` for a measured answer of upstream PeTTa), and the remedy's title
carries a `<field>` hole for each field the kind declares. Ask for them like
any other data, `!(match &metta (refusal $k $class $g $r) ($k $class))`, or
read `website/reference/refusals.md`, which is those rows rendered. The engine
fills the holes from the refusal that was actually raised, so a tripped bound
carries `raise the bound past 0.05 seconds, or narrow the query`; a hole left
over is the reader's own choice, which is what keeps that remedy `prose`, and
a remedy whose every hole was filled keeps its row's applicability, which is
how `capability` arrives `maybe` carrying `(edit (grants &restricted
process))`. Eleven of the fifteen carry a title and no act, because their
repair is a decision. Every engine refusal reaching this seat therefore has
`.ground` and `.remedy` without any raise site here naming them; the Node seat
carries the same two on `MettaError`, and the C seat as `mt_ground()` and
`mt_remedy()` beside `mt_errmsg()`. A seat spells a class its own way where
its own language already owns the word, and `tests/data/error-kinds.json`
records what it spells and why: `value` and `type` are `ValueError` and
`TypeError` here against the rows' `WireError` and `CastError`. The three
closed sets `Ground` and `Remedy` validate against are catalog vocabularies
too, `ground-kind`, `remedy-kind` and `applicability`, which is where
`metta.vocabularies.GroundKind`, `RemedyKind`, `Applicability` and
`RefusalKind` come from.
`metta._errors.errors.refuse(kind, message, **fields)` is the SEAT's own door onto
those rows: the class, the ground and the remedy all come from the kind's row,
and the fields fill both the remedy's holes and the class's own attributes, so
`raise refuse(RefusalKind.source, msg, source=path)` is a `SourceNotFound`
carrying the path and `create <path>, or correct the path that names it`. The
table it reads is `metta/_errors/refusals.py`, GENERATED from those rows joined with
`tests/data/error-kinds.json` by `tools/refusalgen.py` with the `refusal-sync`
gate lane, and it is what the crossing classifies a ball with too: every one of
the fifteen kinds arrives as the class its row names, `stack` as
`StackLimitError`, `source` as `SourceNotFound` and `registration` as
`RegistrationError`, each carrying the fields its kind declares. The `refusal-grounds` lane counts a class the rows name for
a SPECIFIC kind, raised without its row, as a finding; an inline `raise` is for
a Python-level refusal of an argument's shape, a class the taxonomy does not
name, and the catch-all `EngineError`, which is what a refusal with no specific
kind already is.

`metta._errors.errors.NotReducible` is how a deterministic operation says "no answer"
rather than failing: raising it makes the call fail rather than error, which is
a semi-deterministic MeTTa function's way of declining. A generator needs no
signal, since yielding nothing already is one. A SPACE PROVIDER declines
differently, through `should_run` and `refusal` under Foreign spaces below.
`CastError` lives in `metta.convert`, beside the `cast` it names, and the rest
of the family in `metta._errors.errors`.
Type checkers get the closed `SaveFormat` set from `metta.vocabularies`.
Atom kinds are the type: a space name is a `Handle` and a call head is a
`Symbol`.

## Concurrency, transactions, bounds

`with metta.scope() as scope:` and `with m.scope():` join children before
releasing spaces, channels, pools and subscriptions created in the block.
Existing spaces and pools are borrowed; a submission to a borrowed pool is
still a child. A body or child exception cancels siblings before joining.
`scope.keep(value)` transfers its spaces to the enclosing scope, or to the
caller at the root, only after successful cleanup. Released scoped names are
revoked, so an escaped alias refuses instead of recreating the space. The
entering thread alone may keep or close. Repeating timers stop on exit.
AsyncMeTTa workers created in a scope close on exit; requests and async
subscriptions on borrowed workers are scoped while those workers survive.
Debugger sessions and partially consumed host cursors also close on exit.
`scope.cancel()` requests cancellation consumed by that scope. It attempts
every child before reporting signal refusals; a refused close retains its
resources for `scope.close()` to retry.
`with metta.move_on_after(seconds):` uses that scope's deadline and suppresses
only its own deadline cancellation. Scope creation and asynchronous child
publication inside a transaction refuse; allocations rolled back inside an
existing scope still receive cleanup.

In `lib_thread`, `(scope body)` joins its children and transfers spaces in its
returned values. `(capture expr)` holds `expr` and returns
`(evalc expr <current-space>)`; evaluating that value uses the captured space.
`cancel` on a running future signals its engine and waits for acknowledgement:
True means the body stopped, False means it already finished; unknown futures
refuse. A Prolog loop
stops at a predicate safe point. A foreign call, including a Python callback
in `time.sleep`, must return first; cancellation cannot undo its side effects.
Every Python engine call boundary checks the library scope. Python owns no
separate cancellation scheduler. The `choose`/`par` handler reading awaits
the effect-handlers package.

Engine calls belong to the thread that made the engine. `m.pool(workers)` gives
each worker its OWN attached engine, which is what makes the calls genuinely
concurrent (measured 2026-08-15: 1.94x, 3.90x and 7.26x at 2, 4 and 8 workers).

Both pools ARE `concurrent.futures.Executor`, so `submit`, `map`, `shutdown`,
`with`, `as_completed` and `wait` are Python's own words on them. `map(fn,
*iterables)` handles unary and zipped work and `starmap(fn, argument_rows)`
spreads each row into a multi-argument call; both preserve input order and
both take Executor's `timeout=`, `chunksize=` and `buffersize=`. Every
fan-out door SUBMITS the whole input and then answers an ITERATOR over
results that already exist, so wrap it in `list()` to compare, and a map
written for its side effects still runs; `imap_unordered(fn, items)` yields
in completion order instead. One failure raises plainly, several raise as
one `ExceptionGroup` in input order, and `timeout=` raises `Timeout` after
cancelling what has not started. `close(wait=)` is the pools' own name for
`shutdown(wait=)`, which adds `cancel_futures=`.

`metta.parallel.process_pool(workers, boot=)` is the other boundary: worker
PROCESSES that each boot an engine of their own and share nothing. A worker
costs a whole boot where a thread costs an attachment (measured 2026-09-07:
2,248M instructions:u, 0.37s wall with the `.qlf` set present), so reach for
`m.pool` unless isolation is the point. An engine cannot cross a process
boundary, so a worker is sent WORK rather than a callable over a handle:
`metta.parallel.program(source)` runs program text on the worker's engine
and `metta.parallel.call(head, *arguments)` applies a head the pool's `boot=`
defined. Both are ordinary functions in this process too, so `map(program,
texts)` is the pool's own oracle for `pool.map(program, texts)`. Atoms cross
by value; a `Space`, a `MeTTa` or any other live handle refuses, at submit
when a call reaches one and inside the work unit when an answer is one,
because a handle pickles by NAME and would silently open the worker's own
space of that name. The pool uses `forkserver` on Linux and `spawn`
elsewhere and REFUSES `fork` at construction, because SWI-Prolog does not
survive one. The trap to know: `forkserver` runs your `__main__` once in its
server and forks workers from it, so an engine booted at IMPORT time is
inherited and every work unit refuses naming that; keep the boot under `if
__name__ == "__main__":` or pass
`mp_context=multiprocessing.get_context("spawn")`.
`m.parallel(*targets)` evaluates targets at once; `hyperpose` is the same thing
under its MeTTa name, written `!(hyperpose (t1 t2))` in source and reached from
Python as `m.fn.hyperpose`. `metta.aio.AsyncMeTTa` runs engine calls on one worker
thread behind `async`; `metta.parallel.engine_thread()` and `metta.current_space()`
report the crossing.
`metta.channel(max=)` creates a FIFO space. Its mailbox and ordinary space
operations use the same bounded buffer. `send` and `add` may block on capacity,
`recv(deadline=)` waits, and `try_recv()` takes a waiting term or returns
`None` immediately; close it with a context manager.
It is one of the root doors over `lib_thread`, each of which runs in the
current space and imports that library there first: `metta.spawn(expr)` starts
an expression and
returns the future space its answers fill, `metta.every(seconds, expr)` repeats
one until its future is cancelled, `metta.race(*exprs)` answers the first
success and cancels the other branches, and `metta.par_map(function, items)`
evaluates a unary function over the items concurrently through `par-map`
(natively `par_map`), answering in input order: `metta.par_map(S.inc, [1, 2, 3])` is `(2 3 4)` where
`(= (inc $x) (+ $x 1))` is defined.

In MeTTa, `(transaction EXPR)` and `(atomically EXPR)` run one atomic block.
Both answer EVERY answer their body has and commit or roll back the whole
answer set; `transaction` compiles its body into the call site, `atomically`
takes the body as an unreduced atom and evaluates it, so only `atomically`
can run a body the program computed.

`m.transaction(callable)` and the `@m.transactional` decorator run a callable in
one engine transaction. Control signals cannot be eaten by the evaluation they
stop, not even by a program's own `(catch ...)`: a bound, a Ctrl-C and an
`interrupt()` all reach a running goal, the same reasoning that puts
`KeyboardInterrupt` outside `Exception`.

Function calls and MeTTa library imports made by an integration installer
follow the same transaction ownership. The shared host services are
`metta_host_hold/3` (template, goal, opaque handle), `metta_host_hold_next/2`,
`metta_host_hold_chunk/3`, `metta_host_hold_post/3` and `metta_host_hold_close/1`.
They retain an SWI engine outside a transaction or transaction-owned dynamic
rows inside one. Closing is idempotent; a close from another thread queues
cleanup on the owner, and owner exit releases abandoned rows. A held cursor cannot accept host
replies because its evaluation is complete; open outside the transaction for
that protocol. Consulting Prolog source still has no general rollback:
dynamic clauses roll back, static clauses remain.

An ordinary transaction cannot undo an external effect after it commits. For
that boundary, declare `space.compensates(operation, recovery)`, then run each
forward term through `with space.saga(receipts) as saga: saga.run(term)`.
Committed `writesState` and `oracleIO` steps leave queryable
`(did operation args result)` receipts. Exceptional exit compensates them in
reverse commit order; a failed compensation keeps its receipt for an explicit
`saga.rollback()` retry.

## Integrating any library

`metta.convert`: `project(obj) -> Projected` whose `.atom` is the constructor
expression, `build(atom)` -> object (returning the atom unchanged when it
cannot), `register_type`, `unregister_type`, `declarations`, `auto_image`.
Dataclasses, enums, pydantic models and annotated classes all cross; enums
project to symbols. A class that states its positional fields through PEP
634's `__match_args__`, an attrs class or a plain class, crosses the same way
with no registration: the fields become children and the positional
constructor is the reverse; attrs state outside the tuple and a required
constructor parameter it does not name are refused rather than lost, and
`__metta__` on the class outranks the default. A class owner can instead implement `obj.__metta__()` and
`Class.__from_metta__(*fields)` for a two-way conversion without process-wide
registration; pass the class as `build(atom, Class)`. `@space.define` on a
class declares it INTO the space
for the round trip; the separate record decorator is gone. Use the direct
`space.define(Class, accessors=False, methods=False)` form when the type may
cross but its fields or public methods must not become MeTTa callables. The
keyword-only decorator form is not supported.

`metta.integrate`: `module_ops(m, module, names=, effect=, prefix=, rename=,
transport="raw")` registers a whole module's callables,
`face(module, names=, purpose=, prefix=, rename=, effects=, signatures=) -> str`
writes those same names out as MeTTa SOURCE instead of registering them,
`facts(m, atoms)` bulk-writes,
`wrap_callable(m, name, target, effect=, arities=)`,
`wrap_object(m, name, obj, methods, effects=)`, `reflect(m, name, obj)`,
`install_reflection_ops(m)`, `integrate(m, target)`, `Integration`,
`SpaceProvider`, `entry_points(group=)` for unloaded discovery,
`load_entry_point(name, group=)` for explicit provider/library loading, and
`discover(m)` for integrations. An integration may declare `METTA_REQUIRES` as
entry-point names; discovery checks missing names and cycles, then installs in
dependency order. Installation is idempotent for a live space, and dropping a
space releases its installation record. Pair `register_object_type`,
`register_repr`, and `register_reflector` with their exact `unregister_` twins
when an integration or test stops owning those process-wide hooks.
Entry-point groups: `metta.integrations`, `metta.spaces`, `metta.libraries`,
and `metta.extensions` for the seam below.

`metta.seam` is this seat's ONE extension seam, the seat-level twin of
`engine/ext_points.pl`: every point a library can plug into is declared with a
KIND and its fields, a registrant is a ROW against a declared point, and both
read back as data. Four kinds, the engine's own less the `host_service` split
it has no audience for: `declaration` (rows read as data, all of them),
`ownership` (the FIRST row whose `claims(...)` answers non-None wins, pluggy's
`firstresult`), `event` (every row's `on(...)` runs), `service` (the SEAT
writes it and a registrant CALLS it). The shipped points are `frame` (a
dataframe library: `module`, `accessor`, `build`, optional `rows`), `sql` (a
SQL engine: `claims`, `define`, optional `undeclared`), `array` (an Array API
library: `module`, `default`, optional `missing`, `scalars`), `index` (a
nearest-neighbour backend: `available`, `build`, `search`), `arrow` (who
builds the Arrow C structs: `claims`, `schema`, `stream`, `batches`), `ipc`
(who writes and reads the Arrow IPC stream: `claims`, `schema`, `stream`,
`read`, `concat`), `transport-error` (`module`, `classes`), `image` (a
default projection for
a class of host types: `claims`), `graphql` (who EXECUTES a document:
`claims`, `schema`, `execute`), `typing` (a type-equation TEMPLATE named by its
rule kind: `equations`, `doc`), `law` (an algebra law a declared carrier can
be held to: `arity`, `sides`, optional `same`) and `door` (the typed host doors
a package contributes as namespace members or receiver sugar: `doors`, which is
where a frame library's short methods such as `to_df` are declared), plus `type`, `repr`,
`reflector`,
`provider`, `library` and `integration`, whose rows live where they always
lived. The twelve above are declared by `metta.seam` itself and are module attributes of it; `type`, `repr`, `reflector`, `provider`, `library` and `integration` are declared by `metta.integrate`, where their readers and adders live, and are reached with `seam.at(<name>)`, which loads that module only when the name is not already declared so a dispatch on the base layer never pays for it. Services published for a
registrant to call: `projection`, `arrow-view`, `space-of`, `module`,
`optional-module` (its declining twin, for an ownership row's `claims()`),
`field-types`, `sql-arity`, `sql-types`, `image-of`, `match` (the directional
primitive, where public `unify` is symmetric), `alpha-eq`, `batch-bounds`,
`arrow-schema`, `arrow-stream`, `arrow-batches`, `observe` (hold the engine's
ONE trace session over a block and answer the Trace, which is what
`metta_otel` calls), and `catalog`, which `metta._spaces.handle` publishes because a
space is that module's. A service is the SEAT's one row and no package can add
another, so reading one never triggers discovery: `seam.at("module").call()`
is the first line of most packages and would otherwise have loaded every other
one [measured 2026-09-08: 124 ms and 196 modules for `import metta_pandas`
before, 5 ms and 33 after].

A row may declare itself a FALLBACK, `register(..., fallback=True)`, which is
the trylast rank: it is consulted after every row that is not one, whatever
order the two loaded in, and registration order decides only between rows of
the same rank. This is what lets rows live in separate distributions, since
`importlib.metadata` promises no order over a group's entry points. The four
structural images this package ships are fallbacks so a model framework's row
is asked first, and the Array API index backend is one so a library's own
backend wins `backend="auto"`.
`seam.at(name)` reads a point (`seam.frame` and friends are the sugar),
`point(name, kind, fields=, doc=)` declares one, `<point>.register(name,
**fields)` adds a row and refuses an undeclared point, a missing field or an
extra one by name, `<point>.table()` / `.claim(...)` / `.each(...)` dispatch by
kind and refuse the other kinds' spelling, `rows()` and `points()` are the
whole seam as data, `withdraw(name)` is remove-then-redeclare, and
`publish(m)` writes it into `&metta` under `(kind extension-point ...)` and
`(kind extension ...)` so `!(match &metta (extension python frame $who $f)
$who)` answers the frame libraries. Discovery is lazy and free: `advertised()`
answers the `metta.extensions` names without importing anything, and the group
is loaded on the first dispatch that has no answer without it, which is how
Pygments finds a plugin lexer. Cost: a registration imports nothing (a row
holds the module NAME), and the shipped rows arrive by the same lazy path a
stranger's do. Refusals: an undeclared point names every declared one; a row
against a `service` point is refused because the seat writes those; and a
dispatch nobody claims names the door, the registrants there are, and the
registration the caller lacks.

**pymetta names no third-party library.** Not in a branch, not in a row, not
in an allowlist: every library the Python seat can be extended by is its own
distribution under `ext/`, one directory per library, found
through the `metta.extensions` entry point exactly as a stranger's package is.
There is no built-in tier. This is the shape Apache Airflow's providers have
(the core knows no cloud; `apache-airflow[amazon]` is the extra that installs
`apache-airflow-providers-amazon`), and an extra here is the same convenience:

| extra | packages | what it fills |
|---|---|---|
| `engine` | janus-swi, only where the wheel carries no patched host | the bridge to a patched SWI-Prolog you built |
| `dataframes` | `metta-tables`, `metta-pandas`, `metta-polars` | the `tables` namespace, frame conversions, and each library's own `.metta` accessor |
| `live` | `metta-live` | the callable `m.live` namespace and `m.live.view` |
| `remote` | `metta-remote` | `m.remote.connect` and `m.remote.serve` |
| `sql` | `metta-tables`, `metta-duckdb`, `metta-sqlite` | the `sql` point: a MeTTa head as a scalar SQL function |
| `arrays` | `metta-arrays`, `metta-numpy`, `metta-faiss` | the array layer, its default library, its vector index |
| `arrow` | `metta-nanoarrow`, `metta-pyarrow` | the `arrow` capsules and the `ipc` stream |
| `graphql` | `metta-graphql` | the `graphql` point: executing a query, where the SDL needs nothing |
| `models` | `metta-pydantic` | the `image` point: a validated model as a constructor expression |
| `das` | `metta-websocket` | the `transport-error` point |
| `otel` | `metta-otel` | a reduction trace as OpenTelemetry spans |

`metta-otel` and `metta-benchmarking` are libraries reached by import and
advertise no entry point. `metta-arrays` advertises its lightweight
`metta_arrays_doors` module, which registers deferred implementation references
for `m.arrays` without importing the array implementation, and its
`lib_arrays` library under `metta.libraries`. Every other workspace member
advertises its declaration module.

Every generic door works with NONE of them installed and refuses by name,
saying which point it was, which registrants there are, and the command that
fills it: `rows.to("pandas")` raises `no frame registration handles the frame
library 'pandas'; registered: nothing. ... The packages this repository ships
for it install with pip install 'pymetta[dataframes]'`. A member's declared
sugar stays absent until its package is installed, and `hasattr` answers
False, but the `AttributeError` carries the same refusal: with no frame member,
`.to_df` on what `match` answers raises `no frame registration handles
answers.to_df(); registered: nothing. ...`, while an answer variable spelled
`to_df` still reads as the variable. `tests/shell/test_the_core_names_no_library.sh` runs
the core with zero packages and then with one, and
`tests/checks/check_layering.py` holds the two rules that keep the boundary
real: the core imports no member, and no member reaches the core's private
names.

Cost, measured 2026-09-08 with `perf stat -e instructions:u`, min of five, on
a box at loadavg 26: `import metta` is 179.84M instructions with all fourteen
packages installed and 179.85M with none (the difference is one sys.path entry,
2.09M, which an empty directory costs identically), so what a program that
never dispatches pays does not change. The first dispatch of a point a
registrant writes loads the group: 278.0M with nothing installed, 393.0M with
the eleven advertising packages, one module each.

`metta_arrays`: one operation vocabulary over any DLPack library.
`install(m, default=xp)` makes numpy, torch or JAX first-class with the same
words; `namespace_of`, `is_array`, `data_of`, and `EmbeddingStore`
and `EmbeddingStore(m, backend="auto"|<a registered name>)`, whose backends
are the `index` point's rows: an exact faiss index and this seat's own Array
API path ship, `auto` takes the first that can run here, and a vector library
installs itself into every store by registering. What a space installed is a property OF that
space, one row `(array-backend <space> <library> (ops ...))` in `&metta`:
`ops(m)` answers that space's roster and `backend(m)` its library, so two
spaces on two libraries answer their own whichever order they were installed
in. `uninstall(m)` is install's inverse, retiring the row, the constructor
aliases, the shape equations and the typing rule, and unregistering every
operation of the roster that no OTHER space's row still names, since the
operation registry is process-wide by name; it answers what actually left it.
Two registrations deliberately survive an uninstall, both keyed on the DLPack
predicate rather than on a space: the DLTensor type and printing hooks, whose
doors are `integrate.unregister_object_type` and `integrate.unregister_repr`,
and the `broadcast-shape` relation, which `register_prolog` cannot withdraw.
Dropping the space retires the row, the catalog retiring a space's
declarations with it, but the process-wide operations stay until `uninstall`
hands them back. `metta.registered()` remains the PROCESS-wide registry view,
which is a different question from what one space installed. Installing again
replaces the row, the aliases and the operations the outgoing roster alone
named. A space with no install refuses by name, and two rows for one space
refuse naming both libraries with install as the remedy.
`EmbeddingStore.keys()` lists stored atom keys and
`EmbeddingStore.vector_for(key)` retrieves a key's original vector.
`EmbeddingStore` registers `(name-knn $q $k)` and
`(name-embed $key)` as OPERATIONS rather than backing a space, so it is called
beside a match rather than being one. Those two public names route through
equations in the store's own space to internal operations named per store, and
the routing is one catalog row,
`(embedding-store <space> <name> (routes <knn> <embed>))` in `&metta`, carrying
`(owned-by-space embedding-store)` so a dropped space takes it along exactly as
it takes the install roster. A second store of the same name in the same space
replaces the row and retires the old routes; anonymous space names are pooled,
so a record that outlived its space would be read by whichever space was handed
the name next. `install` returns the names it
registered, 44 of them with numpy as the default, and every one carries a
`(-> ...)` declaration. `broadcast-shape` is a CLP(FD) relation over shape
expressions, so it computes compatible shapes, runs backwards to infer
dimensions, and rejects incompatible shapes before a tensor is materialised.
`Shape(...)` builds the dimension metadata an
`Annotated[DLTensor, Shape(...)]` annotation carries. A user operation's arrow
retains `(Annotated DLTensor (Shape (...)))`: input dimensions unify with the
argument shape and shared MeTTa variables determine its result shape.
An incompatible known shape returns the ordinary `BadArgType` refusal naming
both shapes. Live array types include that same expression beside their class
and `DLTensor` types. `SHAPE_RULES` declares every registered head's behavior:
elementwise unary heads preserve shape, binary heads infer broadcast shapes,
and rank-two `matmul` unifies its inner dimension before materialization.
Array results from constructors, axis transformations, and reductions report
their actual shape when the value exists. Scalar observations retain their host
type. An unbound dimension remains a variable until
argument typing or the live value binds it; a shape claim does not evaluate
a symbolic size or prove the host function's implementation.
One host value produces one refusal; a matching refinement witness supplies
its observed dimensions.

`metta.tables`: `declare(...)` writes one ctx-scoped bridge declaration into
`&metta` and `TableBridge` derives every provider operation from it, so a
DB-API connection (the `Executes` slice) answers MeTTa matches. The bridge is
an Arrow producer too, so `pl.DataFrame(bridge)` and
`duckdb.sql("select * from bridge")` stream the declared columns out of its own
cursor; two shapes over different relations refuse, because one stream carries
one schema. The rows are read inside the `__arrow_c_stream__` call and DuckDB
makes that call on a worker thread, so a thread-affine driver needs a
connection that permits it, `sqlite3.connect(path, check_same_thread=False)`. `add(space, head, data)` reads an Arrow stream one record batch at
a time, which is how a DuckDB relation, a pyarrow Table or a Parquet reader
loads; a source with its own row door keeps it, since the two build the same
atoms and the row door measured faster. `accessors()` installs the `metta`
accessor on every REGISTERED frame library already imported and answers which
ones carry it, so `df.metta.into(m, "row")` is `tables.add` in each library's
own spelling; it never imports a frame library to do it, and which libraries
those are is the `frame` point's rows. `sql_function(connection, head)`
registers a MeTTa head as a scalar SQL function and answers its SQL name: the
first row of the `sql` point that CLAIMS the connection declares the function
its own way, sqlite3 taking the arity alone and DuckDB the types from the
head's declared arrow. No answer is SQL NULL and several answers refuse. A
connection no row claims is refused naming the door and every engine
registered, never pushed down whichever branch is last.
`metta.space(backing={"edge": 2}, journal=path, sync="flush")` is journalled
and crash-recovering. Reopen an old schema once with
`metta.space(backing={"new": 2}, journal=path, rename={"old": "new"})`; every
old head must occur, the journal is atomically rewritten, and the next open
omits `rename`. `metta.space(journal=path)` without a schema refuses.
Likewise,
`metta.space(backing=url)` mounts a remote store; both ride the one
space-factory door rather than their own modules.

## Foreign spaces and the backend seam

A space can be backed by anything, and the seam is universal rather than
per-backend. From Python, implement `Matcher` / `Enumerable` / `Adder` /
`BulkAdder` / `Remover` / `Clearer` / `Planner` / `Transactional` / `CustomMatch` / `TokenProvider`
and call `metta.foreign.register_provider(runtime, name, provider)` with a name
starting with `&`; or subclass `SpaceProvider`. `can_run(capability, **request)`
declares that the operation exists. Override
`should_run(capability, **request)` to accept or decline each concrete request,
and `refusal(capability, **request)` to give a declined request its own reason.
For example, an add policy reads `request["atom"]`; it runs before the write,
including before any bulk write.
Capabilities are declared, not guessed: `tokens`, `match`, `enumerate`, `add`, `add-many`,
`remove`, `clear`, `subscribe`, `plan`, `rules`, `add-token`, `remove-token`, `savepoint`, and an
unsupported operation refuses loudly rather than degrading. They are the engine's own
`(vocabulary provider-capability ...)` row, which `metta.foreign.CAPABILITIES`
reads rather than restates, and the row is OPEN: a seat or library that
declares a seam hook of its own registers the word gating it with
`(add-atom &metta (vocabulary-member provider-capability <word>))`, and a word
neither shipped nor registered is refused when the provider registers. A provider's `match` may yield
`Answer(theta, *, value=, residue=, k=)` instead of a plain atom: `theta` binds
the query's variables, `value` is the answer atom unified with the pattern, and
`k` is the provider's own annotation, which orders answers under `under=ranked`
and becomes the tag under `under=prov`; `Bindings(theta)` is the theta-only
shorthand. That is how a store's own score, a
cosine or a confidence, weights a derivation. Tagged-rule premises use that same
match door and evaluation context, retain k in their proof traces, and read
fresh complete source bags on each query. Linear provider derivations refuse with
`linear_provider_occurrence_identity_missing` because `Answer` supplies no
stable occurrence identity. `rules` is a promise about what a space HOLDS,
not about which methods a provider has, so nothing derives it: without
it a space holds DATA, and an equation written there is refused rather than
stored where it could never fire. Conjunctive queries route per conjunct, so
a foreign space joins with a native one; on such a conjunction `rows.why()`
prints which conjunct went where and whether its class was exact.
`BoundedMatcher.match(pattern, *, limit=)` may stop at the caller's count only
when `MatchClassifier.pushdown(pattern)` says `"exact"`; ignoring the limit is
always sound. `Snapshotter.snapshot() -> tuple[Atom, ...]` makes a provider
reifiable, and `WorldCommitter.commit_world(base, removed, added)` is the
provider-owned atomic boundary for landing that world's checked multiset diff.
`TokenProvider.tokens(pattern)` yields `(token, atom)` pairs. Each token is an
expression such as `S.t(S.provider, 42)`, with a stable nonnegative integer row
identity; equal atom occurrences need distinct tokens. The engine unifies the
candidates and orders their tokens by generation then actor. `blame` and fast
save refuse a provider without `tokens`, including MORK, with a
`SpaceCapabilityError` naming a native overlay or stable provider identities as
the remedy. Invalid or duplicate identities refuse rather than shortening a
bag, and all token streams close on success or error.

A provider's `match` or `atoms` may re-enter the engine and may raise at any
point, mid-stream included: its own `MettaError` reaches the caller with its
own sentence, anything else arrives as an `EngineError` naming the space and
the provider class and carrying the original as `__cause__`, a resource bound
spent inside the callback arrives as `InferenceLimitError` or `TimeLimitError`,
and `KeyboardInterrupt` crosses unchanged. Answers already streamed before the
failure are never delivered as a complete set.

From Prolog, every seam is declared WITH ITS KIND in `seam:kind/2`, mostly in
`engine/ext_points.pl`: an EVENT runs
for effect and every handler runs; an OWNERSHIP seam is claimed by the first
handler that succeeds and declined by failing; a DECLARATION is a fact table read
as data; a SERVICE runs the other way, a predicate the ENGINE defines that an
extension may CALL. Declaring a seam of any kind EXPORTS it from the engine's
module, so published is a fact the module system holds rather than a comment,
and the two surface walks ask the module system for it. The `service` rows are
the whole permitted inward surface; `seam:kind/2` lists every one, and
these are the families they fall into, each with some of its rows
(text: `swrite/2`, `sdisplay/2`, `sdisplay_with_names/3`, `sread/2`,
`metta_symbol_writable/1`, `metta_unwritable_symbol/2`,
`metta_reader_token_class/3`, `metta_reader_token_source/2`;
source: `metta_source/2` for a context's declared source discipline,
`parse_metta_source/2` with `parsed_form_parts/4` to take one form
apart, `active_source_program/1` to detect a definition batch,
`current_working_dir/1` for what a relative path resolves against,
`observe/3` with `observation_begin/0`, `observation_commit/0`,
`observation_discard/0` and `observation_defer/2` for the post-commit event
stream a scope buffers and then publishes or drops, the last of them pairing a
commit goal with its rollback so a launch happens only after the transaction
commits, with `seam:segment_committed/1` announcing the END of each committed
segment and the spaces it touched, which is where a handler that maintains a
derived answer recomputes once instead of once per atom, `metta_ensure_source_observation/0` to bring the source observer into
a process that did not boot with it, and `metta_vocabulary_value/2` so a
library validates an option against the same declared vocabulary the engine
reads;
compiler: `metta_special_form_head/1`, every head the translator gives special
meaning, so a linter, a completion list or the Python MeTTa.builtins() call asks
a question instead of reading the compiler's clause table. That read was what the
Python shim and lib/lib_reflect/pkg.metta both did, and both answered short and
silently the moment the translator became a module of its own, and
`recompile_function_impl/1` rebuilds one function after a dispatch decision,
with `recompile_function_impl_in/2` naming the module to rebuild it in;
static analysis: `metta_form_unevaluated_variable_paths/3`, the path of every
variable a written form leaves unevaluated (its patterns, binders, quoted atoms
and write payloads), read off the effect planner's evaluated-argument table and
the declaration masks, and `metta_argument_admitted/3`, whether a value would be
admitted for a declared parameter type under a space's typing policy, the
compiled call check's own relation, so the Python lint asks both instead of
keeping a binder list and a metatype list;
errors: `throw_metta_type_error/3`, `rethrow_metta_operation_error/2`,
`refuse_unbound_input/2`;
context: `current_metta_module/1`, `current_metta_space/1`, `space_module/2`,
`metta_module_space/2`, `metta_space_name/1`, and `eval_metta_in_module/3` to
run an expression in the module a space compiles into, plus `metta_source/2`
to read the declared consumption discipline of a context;
platform: `metta_requires/1` for a Prolog source to declare the platform
capability it needs, so a build without it refuses the file at load instead of
half-loading it, and `metta_require_platform/2` for a form to refuse by name,
with what the absence costs, rather than raising an existence error from the
engine's interior;
native storage: `native_storage_module/2`, `native_storage_functor/2`,
`ensure_native_storage_module/2` and `native_atom_clause/4`, which construct
and decode tokenized native storage, beside `stored_atom_of_ref/4` and
`add_sexp/4`, which `metta_engine_reexport/2` publishes rather than a service
row: `add_sexp/4` owns occurrence publication, and static caches restore
through it;
effects and caching: `metta_effect_class_canonical/2`, `metta_effect_rank/2`,
`metta_effect_join/3`, `metta_effect_compose/2`, `metta_operation_effect/2`,
`metta_annotated_operation_effect/2` for the class an annotated arrow
published, `metta_operation_plan_effect/2`, `metta_effect_walk/3`,
and `metta_function_cacheable/1`, with
`support_record/2`, `support_invalidate/1` and `support_forget/1` for taking
part in the support graph whose handler seams the engine already declares,
plus `support_memo_sccs/2` and `support_memo_take_change/2` for its call-graph
SCC view and changed-edge signal;
foreign spaces: `metta_shape_route/5` for the routed view of any shape-routed
declaration kind, `foreign_pushdown_class/3` and `foreign_provides/2`, the
routing classifier and capability probe, `metta_require_events/2`, which
refuses a wait on a context that promises no change events, `match_foreign/4`
for the library that checks a provider's contract, and
`run_with_loading_marker/2` for a library that performs an import of its
own), and it
exists so a backend never reaches into
`engine/parser.pl`, the same reason SQLite hands extensions an
`sqlite3_api_routines` table instead of letting them link against internals.

`engine/support_graph.pl` owns derived-state dependencies. `support_replace/2`
publishes a complete support set, `support_record/2` adds an observation,
`support_invalidate/1` and `support_invalidate_many/1` dirty the reachable
forward subgraph once, and `support_stabilize/3` recomputes only on demand and
cuts propagation off when the value is unchanged. Nodes carry their execution
module: `function`, `function_view`, `specialization`, `memo`,
`compiled_function`, `translated_form`, `type_marker`, `dispatch_policy`, and
`derived`, which is the open kind an extension's own artifact takes.
The specializer, memo library, compiler, and language-policy registries use
these same `supports(Support, Derived)` edges.

`extensions/*/extension.pl` is read when argv carries `extensions` -- a control
file of facts declaring what each seat needs, never a script -- and a seat's
`entry(engine, _)` loads only when every need holds, so there is no backend
"mode" to select and the engine names no seat. A boot without the token reads
none of them, which is the pure kernel. `extensions/` holds every seat in one
folder, told apart by the `entry/2` roles they declare rather than by where
they sit: `entry(engine, File)` is a file the engine consults, `entry(host,
File)` one the seat's own runtime consults, and a seat may declare both. A
MORK-backed store is one such seat, supplying `&mork` and `&mork:name`; it is
present only when both shared libraries were built. The pins in `build.sh` are
MORK ed57c6716d8c510296fb5fbb8be6fbfe2df241d7 and PathMap
0010dbbd52d13fad67e9a7dabfdadb1cfea71fe1. Whole representable conjunctions use
the product join; the optional upstream leapfrog feature is not enabled.
`extensions/mork/benchmarks/baseline.json` pins native and MORK skewed triangle joins
at 100, 400, 1600 and 3200 atoms. Retired instructions measure the Rust work
that Prolog inference counts cannot see. The text boundary refuses expressions
with more than 63 children and symbols that cannot round-trip through text;
plans wider than 62 conjuncts or 62 variables decline to the engine's split.

## Apps, from source

`metta.manifest.boot(manifest, m=None, connections=, host=, token=, authorize=,
ssl_context=)` assembles an app from `(boot ...)` forms, each sugar for exactly
one existing call, performed in source order:

```
(boot (load "rules.metta"))                m.load, manifest-relative
(boot (attach &crm "http://crm:8700"))     metta.attach
(boot (bridge &db (edge $a $b) (row ...))) metta.tables declare + bridge
(boot (serve (&self &crm) 8700))           metta.remote.serve
```

The vocabulary is closed and validated whole before anything runs; bridged names
must appear in `connections` and every connection must be claimed. Each
performed form is stored as its own atom, so the running app answers
`(match &self (boot $what) $what)` with its own topology. A manifest that fails
mid-way keeps its performed prefix's writes, closes any servers it started, and
names the failing form.

`python -m metta` has twelve subcommands: `extension` (`extension new` NAME
writes a new extension distribution in `./NAME`, removing it again if a write
fails), `run` (files, printing each `!` answer
group), `repl` (paren-balance aware; on a terminal, TAB completes a head or a
`&space` against the live engine and history persists in `~/.metta_history`, or
wherever `METTA_HISTORY` points), `serve`, `boot`, `lint` (nonzero
exit on findings; `--json` prints one LSP Diagnostic per line and `--fix`
applies every `machine` remedy in place and lists the rest with their
reasons, exiting nonzero on what remains), `doc` (a name's `(@doc ...)`), `llms` (this file),
`stubs` (`file.metta... [-o out.pyi]`, the loaded program's declarations as a
Python stub, with the program's own printing kept on stderr),
`convert` (`program.py [-o out.metta]`, emitting the module's fresh-space
declarations as loadable MeTTa source), `card` (`lib_x`, one shipped library's
own account of itself) and `lock` (`[file.metta...] [-o metta.lock]`, pinning
what those programs load).

`metta.library`: `card(name) -> Card` is what a shipped library says about
itself, and `rows(name)` is the query under it, which
`extensions/python/tools/libdoc.py` renders as the reference page so a card and
that page cannot disagree. A `Card` carries `name`, `files`, `digest` (each
file's sha256, sorted, listed under its path and hashed as one document),
`since` (the version the library declares, else the engine's), `doc` (its own
opening prose), `heads` (one `HeadCard(name, types, doc, effect, cost, origin,
registered, visibility, origins)`, `types` every type the library declares for
the head, overloads included, and `origins` every live defining space with its
source location, per head it declares, defines, documents or REGISTERS through a
runnable `!(import_prolog_function ...)` form), `effects`, `costs`, `examples`
(the corpus programs that import it), `deprecations` and `needs` (the platform
capabilities its `:- metta_requires(...)` declarations name). Reading a library
neither loads nor runs it, so one whose backend this build has not got still
describes itself; the effect and cost on a head are what THIS engine currently
answers, so a card taken after `m += lib.memo` can say more than one taken
before it. `roster()` is the library-to-files map and `digest(name)` the digest
alone. Cost: the library's source bytes, plus one crossing for every head's
live claims, plus one pass over the example corpus the first time any card is
asked for. `metta.library.card("lib_not_here")` refuses with the roster.

`face(name)` is the third renderer over the same rows: one shipped library's
heads as Python names, so `strategy = metta.library.face("lib_strategy")` puts
`strategy.try_` (the head `try`, PEP 8's escape), `strategy.stratego_all`
(`stratego-all`), `strategy.TP` and `strategy["◁"]` (the bracket door for a
head outside identifier grammar) in hand, each a plain `Symbol` carrying the
library's own `(@doc ...)` prose. A name the library does not declare refuses
with its roster, which is the whole reason to hold a face rather than write
`S["try"]`: `id` is the ENGINE's identity operation and lib_strategy's own
source says it defines none, so `face.id` refuses and `fn.id` is where it
lives. Python's `operator` words are deliberately absent, since they name
engine heads. It is the same machinery `metta.fn` is, over one library's
catalog instead of the engine's; `metta.strategies`, which was that list
written out by hand, is gone.

`context.lock() -> Lock`, a door of the `MeTTa` context rather than of a space,
pins what this PROCESS loaded, not what this context
loaded: the engine's load table, registrations and git pins are process-wide,
so two contexts in one process take the same lock, which is the unit that has
to be reproduced. The doors are `Lock.write(path)`,
`metta.Lock.read(path)`, `context.check(lock) -> list[Drift]`, and
`python -m metta run --locked metta.lock file.metta`, which checks BEFORE the program
runs and refuses with `LockDrift` naming every entry that differs. The file is
TOML in uv's and PEP 751's shape: `lock-version`, `created-by`, an `[engine]`
table (`metta`, `swi-prolog`, and `sources`, one digest over `engine/**/*.pl`,
computed once per process), one `[[library]]` row
per shipped library imported, one `[[source]]` row per other file loaded with
the space it landed in, and one `[[pin]]` row per repository revision
`git-import!` or `(git-dependency ...)` acquired. Digests are the engine's own
`metta_source_digest`, the identity `import!` already compares to decide a
reload, so a lock check and a reload cannot disagree about whether a file
changed. A source path is written relative to the lock's own directory when it
sits under it, so a checked-in lock travels with its program. Refusals: a lock
taken while a load is in flight (it would record a half-loaded program), a
`lock-version` this build does not know (refused by number, never read in
part), and a file that is not TOML. `Drift(kind, name, expected, actual)` with
`actual` None for an entry that is not here at all. What a lock does NOT pin: a
program built from text rather than files has no source to digest and gets no
row, and a bare `!(git-import! url)` with no revision is not a pin.

`metta.importing.install(space=None, *, path=None)` makes a `.metta` file a
Python module: it appends a `sys.meta_path` finder, so `import lib_dict` finds
a file of that name, its `.metta.gz` form, or a directory of that name holding
a `pkg.metta`, and loads it into `space` with the engine's own `import!`. `path` names directories
searched before `sys.path`, one bare directory allowed; `space` defaults to the
ambient one and is resolved AT INSTALL, so one finder names one space for its
whole life. The module carries the heads the FILE declares as attributes, each
the `_EngineFunction` that space's `fn` answers under the underscore-to-hyphen
map, plus `__all__`, `__doc__` (the file's own `(@doc <module name> ...)` or
its first comment block), `__file__`, `__spec__.origin` and `__metta_space__`;
a name the file does not declare falls through to the space's own namespace,
and a head Python cannot spell keeps its exact name under `getattr`. A head the
file DECLARES and never defines is not an attribute, because the space cannot
call it. `importlib.reload(module)` is `import!`'s digest reload under Python's
word: the same module object, the edited file's new bodies, a head the edit
removed gone from `__all__` and from the space. The longhand is
`m += lib(S["path/to/file.metta"])`, which performs the same import and answers
no module. Costs and refusals: importing a file RUNS its `!` directives, the
way `import!` does; the finder is appended and never prepended, so a name with
both a `.py` and a `.metta` on one path is Python's and says so; a load that
fails raises `ImportError` chaining the engine's error and leaves no module;
`importlib.reload` on a module the hook did not load is Python's own refusal,
since there is no `reload` verb here. `import metta` does NOT install it, a
process-wide hook being the program's decision; `python -m metta run` and
`repl` install one for the program's directory and uninstall it when the run
ends. `install()` answers the `Finder`, which is a context manager, has
`uninstall()` (taking its `sys.modules` entries with it) and `modules`, and
`metta.importing.installed()` reads `sys.meta_path` for the ones in place. On
the producer side, a pip-installed package advertises a directory under the
`metta.libraries` entry-point group and its declared NAME becomes importable,
consulted only after the search path misses and only for that exact name.

`metta.remote`: `serve(m, host="127.0.0.1", port=0, spaces=, token=,
authorize=, ssl_context=, cursor_idle=300, cursor_limit=256, mutation_ttl=300,
mutation_limit=4096)`, `connect(url, timeout=30, token=,
headers=, ssl_context=)`, `RemoteSpace(transport, space="&self", batch=)` with
its `server_capabilities()`, and the root `metta.attach` to mount one.
`authorize(Request(operation, space, headers)) -> bool` can express read-only,
per-space, and tenant policy. The cursor settings bound how long an abandoned
answer cursor survives and how many the server owns at once; the mutation
settings do the same for the idempotency keys a retryable write negotiates, so
a lost reply raises `OutcomeUnknown` and its `retry()` replays the request
without repeating its effects. Credentials
require https, tokens compare in constant time, and only http/https schemes
are accepted.

`metta.events`: `m.events()` is the engine's stream of `(action, space, atom)`
changes as a first-class object, and `EventStream.fold(step=None, space=,
pattern=, on=, state=, into=, under=)` is the one way to consume it. A step is
`(state, event) -> state`, run inside the write that caused the event;
`Fold.take()` reads the accumulated state and resets it, `Fold.wait(timeout)`
is the same read blocked on a condition variable, and `Fold.cancel()` ends
it. Leave `state` alone and the fold accumulates nothing, which costs it no
serialisation. `EventStream.publish(action, space, atom)` announces a change
this process did not write, which is how a provider with its own channel
delivers. The three shipped models are that fold with three steps: subscribe
delivers, bridge writes, a declared `(on ...)` reaction evaluates.
`into=State(...)` passes the same process-shared gauge cell to every step.
Each individual store read and write is thread-safe, but compound
read-modify-write needs coordination. State has no events, history, or
transactions. With `under=algebra`, omit the step: zero initializes the fold,
merge is its step, ordinary events contribute one, and `(fact tag value)`
events contribute `tag`.
`EventStream.folds(space_name)` lists that space's live folds in registration
order, so an observability owner can inspect what is still subscribed.
`EventStream.generation()` is the stream's clock, one tick per delivered
change while a segment watch is live and standing still while none is, because
there is then no consumer to be current to. `EventStream.segments(callback)`
runs `callback(generation)` after
every committed SEGMENT: one commit's whole ordered diff, so an unscoped write
is a segment of one and a transaction is a segment of everything it wrote,
while a rollback, a speculation and a world evaluation have none. The space
already held the whole diff when the segment's first event was delivered, so a
consumer that recomputes recomputes there, once, rather than once per atom. The
engine announces boundaries only while a watch is live, and only for a segment
touching a subscribed space.

`m.live(query).changes(timeout=None)` reads a live view as a stream of
`metta.live.Delta(kind, diff, row, atom, generation)`, frozen and slotted
so a consumer reads it with `match`: `kind` is the `delta-kind` vocabulary
(`metta.vocabularies.DeltaKind`), `add`, `remove` or `progress`,
`diff` is the signed change in that row's multiplicity, `row` is the answer
keyed by column name, `atom` is the query instantiated under it when the query
is one atom, and a `progress` delta carries neither and means every change
committed up to its generation has been delivered. Deltas buffer only while a
`changes()` stream is open, bounded by the `(limit subscription-queue ...)` row
and REFUSING rather than dropping the oldest; the stream is a context manager
and iterates with `for` or, under `aio`, with `async for`. Measured 2026-09-07
over relations of 10, 100 and 1,000 rows, inferences per touching write: the
`pattern` strategy 88, 90, 90 against a recompute-per-event consumer's 149,
425, 3,153; `heads` 167, 445, 3,173 for a single write but 4,035 against 31,564
for a transaction of ten, because it re-answers once per commit; `tabled` 563
flat for a write that leaves its table valid at every size.

`metta.subscribe`: `m.subscribe(pattern, callback=None, *, on="add", where=None,
queue_max=None)`, `where=` a term evaluated per event and `queue_max=None` the
standing `(limit subscription-queue ...)` row, 10000 by default,
is the delivering fold, run INSIDE the write that matched it; without a
callback, events queue until `drain()`, and a full queue raises rather than
discarding the oldest. A callback that raises reaches the writer as
`SubscriberError`, which carries `.subscription` and says the write was
applied, so it is not a failed write and retrying it duplicates.
`bridge(...)` connects two spaces. `Subscription` is a context manager and
also a blocking event stream. A foreign space is watchable only when it
declares what its change events promise; a `RemoteSpace` declares nothing and
refuses `subscribe`, because there is no event channel on the wire.

The wire has both doors the in-process seam has. `RemoteSpace.match` is
eager, one request carrying the whole answer set, and `RemoteSpace.stream`
is the protocol's ask/next/stop lifecycle, a chunk per request, so taking
two answers of a large enumeration costs the serving engine two answers.
`metta.attach(name, metta.remote.RemoteSpace(transport, batch=1))` puts an
attached space's matching on the lazy door; `metta.remote.connect(url)`
builds the transport when it needs a token, headers or a timeout. `metta.remote.Gateway` is the same protocol with
no transport under it, for mounting on another HTTP framework.
`website/live/remote-protocol.md` is the contract every binding inherits and
`metta.testing.GatewayComplianceSuite` certifies it.

A served engine also DESCRIBES itself. `Gateway.openapi(secured=False) -> dict`
is an OpenAPI 3.1.1 document for the spaces that gateway serves, answered at
`GET /openapi.json`: one path per door with the door's own name as its
`operationId`, `components.schemas.Atom` as the wire's tagged grammar written as
JSON Schema 2020-12, and `x-metta-heads` naming what each space DECLARES with
each argument's and the result's schema. `serve(token=)` puts the bearer scheme
in it; a Gateway is transport-free and never learns the token. A space that
declares nothing publishes an empty head list, which is the reason to declare.
`Gateway.served() -> dict` is the space map the document is built from, and a
Gateway is a context manager because it owns one engine per open cursor.

Cost: the declarations are read through the engine's own first-argument index,
not by walking the store, so the document is derived per request and does not
grow with the space (230 inferences over 20,000 atoms against 340,525 for the
walk, measured 2026-09-07). Nothing is cached, so nothing goes stale.

`Gateway.graphql_schema() -> str` is the same catalog as GraphQL SDL, answered
at `GET /graphql` as `text/plain`. `scalar Atom` carries any atom as canonical
MeTTa text and `scalar Number` a MeTTa number, which no built-in GraphQL scalar
holds exactly (`Int` is 32-bit, `Float` a double). `Query.match(pattern:
String!, limit: Int, space: String)` reaches every atom whatever a space
declares; each DECLARED head gains `<head>(x1: Atom, ..., space: String):
[<Head>Row!]!` whose row fields are `x1..xn` at their declared types, because a
`(@param ...)` row carries a type and a description and never a name. Mutations
are `add(atom: String!)` and `remove(atom: String!)`, both taking MeTTa source.
A head outside GraphQL's `[_A-Za-z][_0-9A-Za-z]*`, one colliding with another
space's, and one that would shadow `match` are listed in the OpenAPI document's
`x-metta-unnameable` with the `match(pattern:)` door that still reaches them.

`Gateway.graphql(request) -> dict` executes one request, GraphQL over HTTP's own
`query`, `variables` and `operationName` shape, and answers `data` and `errors`;
`POST /graphql` is the same. It needs `pymetta[graphql]` (graphql-core) and
refuses by name without it, while the SDL is built as text here and is published
either way. `Query.match` resolves through the same door `POST /match` uses, so
the two answer one set.

`POST /ask` and `/next` with `Accept: application/vnd.apache.arrow.stream`
answer an Arrow IPC stream instead of tagged JSON atoms;
`RemoteSpace.stream(pattern, batch=, limit=, arrow=True)` is the client half,
`RemoteCursor.to_arrow()` drains it into one pyarrow Table and
`__arrow_c_stream__` hands the batches to anything reading the PyCapsule
protocol. A `Gateway` called directly asks with `format="arrow"` in the payload,
which is what the Accept header sets. Columns are the pattern's variables at the
types the space DECLARES, plus `atom`, the canonical text of each instantiated
answer; an undeclared column is `utf8` text with `metta.kind=mixed` in the field
metadata. The schema is fixed when the cursor OPENS, because an IPC stream has
one schema for all its batches, and each chunk crosses as a complete stream with
the cursor token in `x-metta-cursor`. Needs `pymetta[arrow]` (pyarrow) on both
sides and refuses by name without it; an Arrow cursor answers batches and not
atoms, and each mode's door refuses the other's by name.

Cost: 360M retired instructions for a 2,000-row drained cursor against JSON's
685M at one chunk, 383M against 622M at ten. The crossings are the same
(`ceil(rows / batch)`); what Arrow removes is the per-atom encode and decode.

`metta.testing` ships what the suite fuzzes itself with: hypothesis strategies
(`atoms`, `expressions`, `patterns`, `names`, `numbers`, `texts`, `symbols`,
`variables`, `grounded`, `ground_atoms`, `programs`, and
`library_scalars(module)`, the scalar values of an array library whose `array`
row declares `scalars`, as `metta-numpy`'s does, refused naming the field where
the row declares none),
`from_pattern(pattern, max_leaves=8)` for ground instances that share every
repeated named variable and draw anonymous occurrences independently,
`programs(census=None, depth=3, facts=(1, 4), queries=(1, 3))` for whole MeTTa
programs written only out of heads an arbiter is known to REDUCE, which is what
makes a differential against another engine compare answers instead of error
paths. Its census is `tests/conformance/petta/HEADS.json`, read from upstream
PeTTa's own example corpus by
`tests/conformance/petta_capture.py --census` and decided by running each head
on that engine; `tests/checks/check_upstream_fuzz.py` is the `parity-fuzz` lane
that draws from it, runs both engines, and shrinks a disagreement to the
smallest program that still shows it. Also here: the contract tests a
declaration already writes, `cases(head, examples=100, strategies=None,
seed=None)` and `laws(algebra, space, laws=None, values=None, examples=100,
seed=None)`, the compliance suites
(`SpaceComplianceSuite`, `GatewayComplianceSuite`, `check_space_provider`,
`check_twin`, `check_replay`, `check_minted_handles`), and the deterministic
benchmark gates (`benchmark_case`, `benchmark_counter_slope`,
`measure_counters(command, events=("instructions:u",), rounds=3,
controlled=False, timeout=60) -> CounterRuns`, `measure_instructions`,
`BenchmarkBaseline`, `count_atoms`), which live in the `metta_benchmarking` distribution
(`pip install metta-benchmarking`, which `pymetta[test]` includes; a checkout reaches
it through `extensions/python/_workspace.py`'s `on_path()`).
`CounterRuns.events` maps each requested perf event to its samples and
`.outputs` retains each measured command's stdout. A box that will not count
is told apart from a tree that moved: `measure_counters` raises
`MeasurementRefusedError` where perf answered `<not counted>` for a requested
event or where a controlled workload exited `PERF_CONTROL_REFUSED` (125,
timeout(1)'s and `git bisect run`'s status for "this run says nothing"),
and raises an ordinary `RuntimeError` for every other nonzero exit, which is
the workload's own failure. `measured_main(main)` is what a benchmark's
`__main__` guard calls: it turns that refusal into a named skip and exit 0 on
a developer's box, where a PMU another session holds is not a code change, and
into an error and exit 1 where `CI=true`, because a runner that cannot count
is a broken runner. The refusal names `/proc/sys/kernel/perf_event_paranoid`
and the container knob rather than sending a reader into the harness.
One ROW can be refused while its neighbours decide, which is a different thing
from a lane that measured nothing. A case whose measured region contains the
engine load reads the LENGTH of the checkout's path, about 0.045% per
character (measured 2026-09-07), so its instruction pin is true of one location: `engine/bench.pl`
declares `bench_whole_process(boot)`, `engine/bench-baseline.json` records
`measurement.checkout_path_length`, and `engine/bench.py` reports such a row
instead of comparing it, and declines to re-pin it, from a checkout of another
length. `extensions/cmetta/benchmarks/bench.py` holds the same fact for its own
boot row. Every other row's window opens inside an already-booted process and
decides from anywhere.
`metta.testing.SpaceMachine` is the multiset laws of a space as a hypothesis
state machine, pointed at your own store: `SpaceMachine.for_(factory)` answers
the machine bound to a factory that returns a FRESH space it may write into,
clear and drop, as a class, so the same object is both
`run_state_machine_as_test(SpaceMachine.for_(factory))` and the pytest shape
`TestMine = SpaceMachine.for_(factory).TestCase`; `SpaceMachine(factory)` is the
constructor underneath both. Each generated step adds, adds a second copy,
removes one copy, clears, queries, or writes inside a speculative scope or a
transaction that commits or rolls back, and after every step the space is
compared against a `Counter`. It requires `add` and `enumerate` and REFUSES
without them, naming `check_space_provider` and `SpaceComplianceSuite`; every
other rule is skipped where the space cannot support it, and
`SpaceMachine.skips(space)` answers which rules those are and why before any run,
each reason the engine's own refusal. The transaction and speculation rules run
for a native space and for a foreign one declaring `(writes <space>
transactional)`, and skip for `best-effort`, `atomic-single` or silence, because
a write a rollback does not undo is not a bag law. Subclass it to add a law of
your own; the library's own suite adds the native save-and-load round trip that
way.
`metta.testing.assert_answers(actual, expected, *, msg=None)` compares two
answer bags with multiplicity and blind to order, and
`assert_includes(actual, expected, *, msg=None)` asks the one-sided containment.
Each side is `Rows`, `Answers`, or any sequence of atoms or of values `encode`
accepts; a `Rows` compares row by row, each row the expression of its values, so
project one column with `rows.x` to compare values, and one answer handed over
as itself is REFUSED, a `str` included, rather than compared character by
character. Neither is a second implementation: both hand the two bags to the
engine's own `assert-answers` and `assert-includes-answers`, so the relation is
`subtraction-atom`'s, the failure is an `AssertionFailure` carrying the same
`.missing` and `.excess`, and everything below the first line of the message is
character-for-character what `assertEqualToResult` prints for the same bags. It
costs one engine crossing per call, 289 inferences over two four-answer bags
[measured 2026-09-25T22:18:48+10:00: beyond the 7 the `stats()` door itself reads],
and the failure is printed on stderr as well as raised, exactly as a MeTTa
assertion is. pytest's assertion rewriting is not involved.
`testing.cases(head)` is deal.cases's shape over MeTTa's contracts: every
parameter of a `@m.define`d head draws through Hypothesis's `from_type`, so
`Annotated[int, Gt(0)]` draws positive integers, an atom class draws atoms
(the atom classes are registered with `register_type_strategy` on first use),
a MeTTa type atom draws the values the space declares to inhabit it, and
`strategies=` overrides a parameter by name; each generated call runs and is
held to three contracts: no `(Error ...)` answer, every answer inside the
return annotation's refinements, and a declared effect class at or below
`nondeterministicReadOnly` neither writing into the space nor answering
differently when repeated. The failing example is Hypothesis's shrunk one with
the MeTTa call form, `(shrink 1) answered (Error (shrink 1) (BadReturnValue
(Ge 0) -4))`. Three shapes: `test_double = testing.cases(double)` is a pytest
test, `@testing.cases(double)` decorates a test taking one `Case` whose
`.call` is the form and whose call runs the checks, and iterating yields the
generated cases unrun. `testing.laws(algebra, space)` does the same for a
declared algebra's law rows and answers a `Laws` object that is a pytest
test, an iterable of `(law, test)` pairs, and a callable; values come from
the finite carrier, from the declared type (`Number` draws integers, because
floating-point addition is not associative), or from `values=`, and a preset
with no carrier row is tested over its two identities. There is no exception
contract row, so an `(Error ...)` answer for a generated call is always a
violation: narrow the precondition with a refinement instead. Use
`BenchmarkBaseline.observe_counter` for deterministic engine counts,
`observe_measurement` for a declared noisy-counter band, and
`observe_configuration` before comparing either. `metta.pytest_plugin` gives the `metta` and
`scratch_space` fixtures; `metta.ipython` gives `%metta <source>` and
`%%metta [space]` in a notebook, one registration in IPython's `line_cell`
form. The line means a different thing in each, because it is the argument
line in both: for `%metta` it IS the program, for `%%metta` it names a space
and the cell is the program. A one-line evaluation therefore has no room to
name a space, and `metta.ipython.use(m)` is the rung below it, pointing both
at one runtime for the session. `%metta` with nothing after it refuses.
The full-notebook experience is `trueagi-io/jupyter-petta-kernel`, which
runs MeTTa cells with no prefix at all; it asks its host for a `petta`
module under `$PETTA_PATH/python`, which this fork does not ship, so it
runs against upstream PeTTa and this package's contribution to it is the
lexer its `language_info` MIME type resolves to. The `kernel` REPORT lane
installs it at a pinned commit and starts it.

`import metta` loads the atom model (`metta._atoms` and its submodules),
`metta._errors.errors`, `metta.vocabularies`, `metta._spaces.ambient` and the
`metta._binding` and `metta._spaces` package shells, and nothing else, so it
never pulls in the HTTP, subscription and table machinery boot composes over.
Every other public submodule (`aio`, `algebra`, `cli`, `convert`,
`derivation`, `doors`, `events`, `foreign`, `importing`, `integrate`,
`ipython`, `library`, `lint`, `live`, `manifest`, `parallel`, `paths`,
`pytest_plugin`, `remote`, `seam`, `spaces`, `structures`, `subscribe`,
`tables`, `testing`, `typing`) and every root name that lives in one, the
classes `MeTTa`, `Space`, `Answer` and `State` and the carrier objects among
them, loads on first access. `dir(metta)` lists what `metta.__all__` declares
and the submodules, which is the whole surface: `metta.__all__` is generated
from the root's re-exports and module doors.
`metta.convert` is one door for the whole crossing now,
`encode`, `decode`, `from_wire`, `atom_from_wire`, `cast` and the projection
half together; `metta.wire` and `metta.casting` are gone with no alias.

## The MeTTa language surface

Special forms are compiled by the translator rather than defined by equations,
and most answer false to "is this a function", so "no equations" does not mean
"nothing can prove it". These sixty, plus the internal
`__metta_type_syntax__` the registry section below names:

```
add-atom add-atoms add-reduct add-reducts annotation call case catch
chain collapse cut elapsed eval evalc explain filter-atom foldall
foldl-atom forall get-atoms get-metatype hyperpose if inferences let
let* map-atom match match-under metta-thread new-space noeval nop
not-provable once prog1 progn quote reduce remove-atom return sealed space-atom-count
space-contains subtract-atom super superpose switch take test
test-no-answer timeout top transaction translatePredicate unify
with-pragma! with-seed with_mutex |->
```

Eight more are written in MeTTa, as prelude equations saying what the call
expands to: `and-then`, `or-else`, `trace!`, `unique`, `alpha-unique`,
`union`, `intersection`, `subtraction`.

Each of those is an ordinary equation plus one registration, and KERNEL.md is
the ledger of which head is which, what it answers to in the minimal
instruction set the arbiter presents, and for a derived form still fused into
the compiler, the measurement that keeps it there.

`(eval-one Source)` requires exactly one answer and returns it as data.
It accepts a successful answer followed by failing alternatives, counts equal
answers separately and stops at the second answer. Zero or multiple answers
raise `metta_cardinality_violation`. The successful source/result binding
graph keeps sharing and constraints without repeating their hooks. Evaluation
and cleanup stay in the caller's engine and transaction. The editable example
is `examples/ch05-equations-and-evaluation/05-01-an-equation-is-a-rewrite/11-single_answer.metta`.

`(owned-record-read (@owned-record Home Owner Storage Prefix))` reads a native owned
record as data: the held key names the home, its `(owned-by Owner)` marker, the storage
and the row prefix, and the answer is the record's zero or one complete rows with a
stored expression left unevaluated, read in one database snapshot. A retired owner, a
second value or an unresolved storage refuses. An `(@owned-record ...)` declaration in
`&metta` governs writes: at the outer commit one value and one live owner per key. The
editable example is `examples/ch15-writing-transactions-and-worlds/07-owned_records.metta`.

`(on-unwind Source Handler)` evaluates held Source and applies held Handler
once when evaluation fails, is cut or throws. Handler is an ordinary native
callable and receives the actual catcher product: `(fail)`, `(!)`,
`(exception Ball)` or `(external_exception Ball)`. Deterministic completion
does not evaluate Handler. Cleanup uses the caller's source context and SWI's
exception precedence. `examples/ch05-equations-and-evaluation/05-01-an-equation-is-a-rewrite/10-unwind_cleanup.metta`
and its Python twin exercise an editable handler equation with a captured home.

### Sequence variables: a pattern child that stands for a run

A gap is an expression CHILD standing for a finite run of zero or more sibling
children, and only what the program WROTE is one. Two spellings: the bare
symbol `...` is anonymous and every occurrence of it is its own variable, and
`(:seg $x)` with a variable in second position is named and answers the run it
took. `(:seg foo)` is ordinary data, a marker that arrived through a binding is
ordinary data, and the ROOT of a pattern is never a gap. Wolfram's `___` and
`x___` are the same two notions.

Five doors read one: a space `match`, one conjunct of a `(, ...)` join, a `let`
pattern, a `case` arm, and an equation HEAD, which makes that function
variable-arity. `(= (allof (:seg $xs)) (kept $xs))` answers for every arity,
and in the body an ordinary `$xs` keeps the run as ONE expression while a
written `(:seg $xs)` SPLICES it into the expression around it. Two gaps in one
head make the CALL nondeterministic: matching enumerates the splits and the
call answers once per split, shortest prefix first.

A run projects as the Expression its children make, so `size-atom`, `car-atom`
and `index-atom` read it in MeTTa and a Python answer row carries an
`Expression` slice. In Python `...` is the same glyph (`space[(S.A, ..., S.D)]`),
`seg(V.rest)` builds the named form, and `case (S.Order, id, *rest):` inside
`@m.define` lowers a star pattern to one. A star PARAMETER is refused, because
`*args` has no MeTTa image, so a variadic head is written as data:
`m += equation(S.allof(seg(V.xs))).to(S.kept(V.xs))`.

THE FENCE. General sequence unification is INFINITARY (Kutsia, Journal of
Symbolic Computation 42(3), 2007, Theorem 62), so an ask outside the three
restrictions proved finite REFUSES rather than searching. `metta_seq_classify/3`
in `engine/spaces/segment_matching.pl` names them: `one_sided`, one side
carrying no gap at all; `last_position`, every gap the last child of its own
expression on both sides, deterministic and unitary (Kutsia Section 6.3);
`linear_shallow`, every gap a direct child of the root and each named gap
occurring once across the pair (Kutsia Section 6.2). One name may not be both a
gap and an ordinary variable, except in an equation head, which is one-sided by
construction and binds the run before the ordinary occurrence is compared.

WHICH DOOR REACHES WHICH FRAGMENT. `unify` is the one form whose two operands
are both syntax, so it is the only door a TWO-SIDED ask can go through, and it
parses both of them: a gap written on either side is a gap there. Every other
door faces a value or stored data on one side -- `match` reads a space, `let`,
`case` and an equation head take an evaluated subject, and Python's `solve` is
a `let` -- so those are `one_sided` by construction and a marker written on the
value side is data. So `(unify (f a b) (f a b (:seg $v)) $v none)` answers the
empty run `()`, `(unify (f (:seg $u) b) (f a (:seg $v)) ($u $v) no)` answers
`((a) (b))`, and `(unify (f (:seg $u)) (f (:seg $u)) yes no)` answers `yes`,
which is what upstream PeTTa at the parity pin answers for the same program.
A pair with gaps on both sides that fits no fragment refuses with
`no_certificate`, and Kutsia's own infinitary witness is one:
`(unify (f (:seg $x) a) (f a (:seg $x)) yes no)`. A space operand makes the ask
a gap query, so `unify` and `match` answer the same rows for the same pattern.
`examples/ch08-data/08-02-sequence-variables/04-the-two-sided-fragments.metta`
pins every one of those answers, and `05-the-fence.metta` reads both refusals
apart. Measured 2026-09-07 through `m.stats()`, one warmed ask each: the five
two-sided shapes cost 390, 690, 582, 710 and 395 inferences, against 316 for a
gap-free `unify` of the same shape, which is unchanged to the inference.

Caught, a refusal is data: `(Error (metta_seq_outside_fragment left right mixed
reason) none)`, read apart with `index-atom`, where `reason` is `mixed_roles`
or `no_certificate`. It is CARRIED with the compiled pattern and thrown at the
ask, so an arm nothing reaches cannot stop a file from loading. Python sees an
`EngineError` whose message carries the theorem, the rule and the classifier;
the payload is not on the exception.

COST. A pattern with no gap pays nothing: the question is answered by the walk
that already lifts a pattern's modifiers, and both matching doors dispatch a
gap pattern through a wrapper an ordinary pattern never carries. A gap pattern
cannot use the store's arity-keyed read, since the gap rather than the pattern
decides the arity, so candidates are enumerated per admissible arity with the
pattern's leading child written into the candidate head first, which keeps the
store's first-argument index. Measured 2026-09-07 over a space holding three
`edge` atoms and 2,000 `node` atoms: `(match &self (edge a $y) $y)` costs 57
inferences and `(match &self (edge ... $y) $y)` costs 144, both FLAT in the
size of the node relation, while `(match &self (node ... $y) $y)` costs 46,070,
about one per row it answers. Matching m gaps against n children enumerates the
integer compositions of n into m parts, so the cost is exponential in the
NUMBER of gaps and polynomial in the subject; one gap is linear, which is the
shape every gap pattern in the corpus has.
`examples/ch18-performance/18-01-larger-workloads/06-a-gap-query-and-its-index.metta`
runs the measurement.


The exact-integer operators are engine heads rather than library equations:
`bit-and`, `bit-or`, `bit-xor`, `bit-not`, `bit-shift-left`,
`bit-shift-right` and `floor-div`, with division by zero answering error
DATA rather than raising.

Sixty-nine more engine heads the corpus exercises, by family. Numeric:
`min`, `max`, `pow-math`, `exp-math`, `log-math`, `round-math`, `trunc-math`, `ceil-math`,
`sin-math`, `cos-math`, `tan-math`, `asin-math`, `acos-math`, `atan-math`,
`isnan-math`, `isinf-math`. Atoms: `alpha-unique-atom`, `is-alpha-member`,
`is-member`, `is-var`, `is-expr`, `is-function`, `first-from-pair`,
`second-from-pair`, `reverse`, `last`, `id`, `for-each-in-atom`, `foldl`.
Logic: `xor`, `dif`. Spaces:
`is-space`, `new-state`, `has-declared-type`,
`space-admission-verdict`. Types: `match-types`, `match-type-or`, `type-cast`.
Text, IO and files: `repr`, `println!`, `readln!`, `read-form!`, `format-args`,
`sort-strings`, `parse-command`, `sleep`, `exists_file`.
Pre-add hooks: `declare-pre-add!`, `undeclare-pre-add!`. Translator, Prolog and
modules: `add-translator-rule!`, `remove-translator-rule!`,
`import_prolog_function`, `Predicate`, `callPredicate`,
`assertaPredicate`, `git-import!`, `residual-goals`. Minimal MeTTa: `unquote`,
`noreduce-eq`, `collapse-bind`, `superpose-bind`, `return-on-error`,
`if-equal`, `repra`. Assertions beyond the four the corpus is written in
(`assertEqual`, `assertAlphaEqual`, `assertEqualToResult`, `assertIncludes`): `assertEqualMsg`,
`assertAlphaEqualMsg`, `assertAlphaEqualToResult`, `assertEqualToResultMsg`,
`assertAlphaEqualToResultMsg`. `undocumented` reports what `doc` lacks.

Two names the corpus also exercises are LIBRARY heads and not in that count:
`file-exists`, which is `lib_file`'s spelling beside the engine's own
`exists_file`, and `import_prolog_functions_from_file`, which a library
registers.

`pragma!` accepts `max-time`, `max-inferences`, `package-budget`,
`verify-specializations`,
`verify-discharges`, `verify-cardinality`, `max-stack-depth`, `stack-limit`,
`plan-cyclic-joins`, `materialize-source-relations`, `type-check`, and
`interpreter`, `from-map`, and `load`. The last two belong to the current
receiver: `from-map` takes a head map, and `load` takes `eager`, `background`,
or `lazy`. The bounds, the verification modes and the two planning
switches change live engine mechanisms. `max-stack-depth` is validated exactly as the
arbiter validates it: a value that is not a non-negative integer
answers an `(Error ...)` atom while the program keeps running.
`type-check` and `interpreter` are HE spellings, accepted and not
enforced. A key outside the registry is refused rather than stored
inertly. `max-time` takes a positive number of seconds,
`max-inferences` a positive integer, and `none` explicitly disables
either bound; an invalid value leaves the previous setting unchanged.
`stack-limit` takes positive SWI combined-stack bytes and scopes the setting to
the current thread. `package-budget` takes a positive integer and bounds the
loader normalising ONE package row, defaulting to 1,000,000 inferences; it is
not `max-inferences`, which bounds a runnable the program wrote, because a row
is normalised while its file is still being read and no runnable is in flight. `verify-specializations` compares the first use of each
generated higher-order call with its generic form; turning the pragma off, or
leaving a process started with `METTA_VERIFY_SPECIALIZATIONS=1`, reports the
agreed and inference-bounded counts even under `sh tools/run.sh`'s quiet launch.
`METTA_VERIFY_BUDGET` replaces the default 200000-inference comparison bound
with a positive integer. `verify-discharges` similarly audits type checks the
compiler omitted and reports its coverage when disabled, and
`verify-cardinality` checks annotated `det` and `semidet` calls for failure or
leftover choicepoints. `plan-cyclic-joins` plans a full native cyclic
conjunction as a Generic Join instead of the retained nested loop, and
`materialize-source-relations` derives the finite function-free fragment once
at each source boundary and answers admitted ground calls from it.

### Package rows: what a library says about itself

`package` is a reserved head. It is internal in every space, so one library's
rows are never read as its importer's own, and it is not a head any library
declares. A library describes what backs its heads instead of telling the
engine to load them:

```metta
(= (package backing) (prolog (library lib_regex.pl) (regex-match regex-replace)))
(= (package requires) lib_json)
```

The row is DATA. Any implementation that can read atoms can read it, decide
which rows it can perform and refuse the rest by name, where
`!(import_prolog_functions_from_file ...)` was an instruction only this engine
understood. That spelling still works and is what the row performs.

The loader performs a file's rows once that file's load commits, and only that
file's. `(package requires)` names a library and `&catalogs` says where it
lives, so a requirement resolves by matching rather than by a resolver, and one
no catalog holds refuses by name. Adding a catalog is adding a row.

`pkg.metta` is the file a DIRECTORY is entered through, and the ONE way a
package is reached: `!(import! &self ./greeter)` loads `greeter/pkg.metta` and
`!(import! &self (library lib_json))` loads `lib/lib_json/pkg.metta`, so an
importer names the package and never an entry point inside it. A git
requirement enters its checkout the same way. The name is a convention rather
than the package's own, which is what `Cargo.toml`, `go.mod` and
`package.json` are, and for the same reason: an entry point named after its
directory means renaming the directory breaks every importer.

NOTHING infers a filename from a directory's name. A bare spec carrying an
extension, `(library lib_regex.pl)`, is REFUSED with both correct spellings
named, because the directory it lives in is exactly what the guess was
inventing. Write the path, `(library lib_regex/lib_regex.pl)`, or name the
package and let its manifest answer. A backing row names its file plainly,
`(prolog "lib_regex.pl" (...))`, resolved beside the manifest carrying it, the
base `Cargo.toml`'s `path` uses.

A file still beats a directory: `<name>.metta` and `<name>.metta.gz` are tried
first, so a module beside a package of the same name wins. `import!` and
`unimport!` enumerate the manifest from one predicate, because a directory
imported through its manifest is withdrawn by the name that imported it
[tested: examples/ch20-extending-the-engine/20-04-modules-and-the-catalog/14-package_manifest.metta,
tests/prolog/suites/seams/packages.plt].

Dispatch is unification. `(perform <row>)` evaluates in `&metta` against a
claim, `(= (perform (<token> ...)) ...)`, that a seat, library or program adds
there; the engine holds none of its own beyond the Prolog loader's. `perform`
takes its row as an `Atom`, so the row arrives exactly as written and the
engine never decides what a token's payload means.

A row whose head a claim answers is performed as written. Any other payload is
NORMALISED first, evaluated in the home space under a ceiling of space reads
and runtime facts, and under `package-budget`. A row reaching the filesystem or
a host call refuses by name, naming the operation, because that work belongs in
a claimant, which runs when the row is performed rather than while it is read.

`if-decons-expr` reads a held expression, unifies its head and tail with the
provided patterns, and evaluates the selected branch. Empty expressions and
incompatible patterns select the fallback.

314 builtins are registered; `m.self.builtins()` lists the live union of the
functions callable from `&self` and the translator special forms. That live union in full, measured
2026-09-25 on a boot with this tree's extensions present, which is where the
three `mork-add-atoms`, `mork-flush` and `mm2-exec` heads come from:

`!=` `#*` `#+` `#-` `#//` `#<` `#=` `#=<` `#>` `#>=` `#\=` `#div` `#max`
`#min` `#mod` `%` `*` `+` `-` `/` `<` `<=` `=` `==` `=?` `=alpha` `>` `>=`
`Predicate` `__metta_type_syntax__` `abs-math` `acos-math` `add-atom`
`add-atoms` `add-reduct` `add-reducts` `add-translator-rule!`
`add-typing-rule!` `alpha-unique` `alpha-unique-atom` `and` `and-then`
`annotation` `append` `argv` `asin-math` `assert` `assert-answers`
`assert-includes-answers` `assertAlphaEqual`
`assertAlphaEqualMsg` `assertAlphaEqualToResult`
`assertAlphaEqualToResultMsg` `assertEqual` `assertEqualMsg`
`assertEqualToResult` `assertEqualToResultMsg` `assertIncludes`
`assertaPredicate` `assertzPredicate` `atan-math` `atom-subst`
`atom_chars` `atom_concat` `atomically` `bind!` `bit-and` `bit-not`
`bit-or` `bit-shift-left` `bit-shift-right` `bit-xor` `call`
`callPredicate` `car-atom` `case` `catch` `cdr-atom` `ceil-math` `chain`
`change-state!` `check_prolog_function_names` `collapse` `collapse-bind`
`cons` `cons-atom` `context-space` `copy_term` `cos-math` `current-time`
`cut` `declare-post-add!` `declare-pre-add!` `decons` `decons-atom`
`defined-name` `dif` `documented` `documented-space` `elapsed` `empty`
`error-payload` `eval` `eval-one` `evalc` `except` `exclude-item` `exists_file` `exp`
`exp-math` `explain` `filter-atom` `first` `first-from-pair` `floor-div`
`floor-math` `foldall` `foldl` `foldl-atom` `for-each-in-atom` `forall`
`format-args` `format-time` `function` `get-atoms` `get-doc`
`get-doc-atom` `get-doc-function` `get-doc-params` `get-doc-single-atom`
`get-doc-space` `get-metatype` `get-property` `get-state` `get-type` `get-type-space`
`git-import!` `has-declared-type` `help!` `hyperpose` `id` `if`
`if-decons-expr` `if-equal` `if-equal2` `if-error` `implies` `import!`
`import_prolog_function` `import_prolog_functions` `include` `index-atom`
`inferences` `interpret` `intersection` `intersection-atom`
`is-alpha-member` `is-expr` `is-function` `is-ground` `is-member`
`is-space` `is-var` `isinf-math` `isnan-math` `last` `length`
`let` `let*` `library` `list_to_set` `log-math` `map-atom` `maplist`
`match` `match-type-or` `match-types` `match-under` `max` `max-atom` `member` `metta`
`metta-thread` `min` `min-atom` `mm2-exec` `mork-add-atoms` `mork-flush`
`msort` `new-space` `new-state` `noeval` `nop` `noreduce-eq` `not`
`not-provable` `on-unwind` `once` `only` `or` `or-else` `owned-record-read`
`package-prolog` `parse` `parse-command` `pow-math`
`pragma!` `prefix` `pretty-atom` `println!` `prog1` `progn` `py-at` `py-atom`
`py-call` `py-container-kind` `py-dict` `py-dict-pairs` `py-dot` `py-eq` `py-except`
`py-format` `py-global-read` `py-global-write` `py-in` `py-iter`
`py-iter-once` `py-len` `py-list` `py-operator` `py-range` `py-repr`
`py-round` `py-sequence-image` `py-set` `py-set-pairs` `py-slice` `py-str` `py-str-join`
`py-truthy` `py-tuple` `qualified` `quote` `random-float` `random-int` `read-form!`
`readln!` `reduce` `register-token!` `register_metta_library_path`
`remove-atom` `remove-translator-rule!` `remove-typing-rule!` `rename` `repr`
`repra` `require-extension!` `residual-goals` `retractPredicate` `return`
`return-on-error` `reverse` `round-math` `sealed` `second-from-pair` `setup!`
`sin-math` `size-atom` `sleep` `sort` `sort-atom` `sort-strings`
`space-admission-verdict` `space-atom-count` `space-contains` `sqrt-math`
`sread` `subtract-atom` `subtraction` `subtraction-atom` `super`
`superpose` `superpose-bind` `switch` `take` `tan-math` `term_hash` `test`
`test-no-answer` `throw` `timeout` `top` `trace!` `transaction`
`translatePredicate` `trunc-math` `type-cast` `type-cast-holds`
`undeclare-post-add!` `undeclare-pre-add!` `undocumented`
`undocumented-space` `unify` `union` `union-atom` `unique` `unique-atom`
`unquote` `unregister-token!` `with-pragma!` `with-seed` `with_mutex`
`xor` `|->`

That roster is the whole registry: the py-* bridge, the atom algebra, the
assert family the example corpus is written in, and the CLP(FD) `#` relations
are all in it. The `#` relations RELATE rather than compute, so giving any two
of three solves the third.

The catalog also says which of those names are the language's own. A
`(visibility <name> PUBLIC|INTERNAL)` row in `&metta` classifies every one, and
seven read `INTERNAL`: `get-doc-atom`, `get-doc-function`, `get-doc-params`,
`get-doc-single-atom`, `interpret`, `match-type-or`, and
`__metta_type_syntax__`, which is the prelude casts' door for type syntax as
data. They are registered and callable, and they are implementation steps
behind public forms rather than spellings to write.

Hand a builtin an unbound variable where it needs a value and it refuses by
name: `!(car-atom $u)` is `car-atom: a value expected in argument 1, found an
unbound variable`. The guarded positions are derived from the type surface
(`guarded_input_position/3`, 82 of them over 62 names, measured 2026-09-05),
so a position declared `Expression`,
`Number`, `BigInt`, `String`, `Symbol` or `Bool` is an input to read. What stays
relational is named in the engine: `index-atom`'s index, the boolean
operations' truth table, `cons`'s open tail, `union-atom` and `member`, which
are `append/3` and `member/2` under MeTTa names, the `#` family throughout,
and every name lent to MeTTa from SWI (`msort`, `append`, `sort`, `maplist`,
`length`), which under that name IS the Prolog predicate.

Ordinary `+`, `-`, `*` and `/` are relational too, which is easy to miss
because they compute forwards. Each solves for ONE unbound slot among
integers, so `(= (double $x) (* 2 $x))` reads backwards for free and
`!(let 10 (double $x) $x)` answers `5`; a pair no integer satisfies FAILS
rather than erroring, so `(let 7 (double $x) $x)` answers nothing. Past one
unknown the rearrangement becomes a constraint: the engine posts it to CLP(FD)
and labels what propagation leaves, so `!(collapse (let 25 (* $x $x) $x))`
answers `(-5 5)`. A domain the constraint leaves unbounded is refused BY NAME,
because deciding a polynomial equation over the integers is undecidable
(Hilbert's tenth problem) and labeling needs a finite domain. Evaluation is
inside-out, so a composed backward query reaches its inner operation with two
unknowns and refuses; the `#` operators POST rather than solve and compose
across several operations, which is what they are for.
`examples/ch05-equations-and-evaluation/05-04-arithmetic-that-runs-backwards/02-relational_arithmetic.metta` runs all of it.

<!-- begin generated library roster -->
60 libraries load with `!(import! &self (library lib_x))`:
`lib_builtin_types`, `lib_cli`, `lib_combinatorics`, `lib_compression`, `lib_conformance`, `lib_constraints`, `lib_crypto`, `lib_csv`, `lib_database`, `lib_datastructures`, `lib_datetime`, `lib_derived`, `lib_dict`, `lib_doc`, `lib_encoding`, `lib_file`, `lib_functional`, `lib_graph`, `lib_he`, `lib_http`, `lib_import`, `lib_json`, `lib_logging`, `lib_markup`, `lib_math`, `lib_measure`, `lib_memo`, `lib_mm2`, `lib_nars`, `lib_observe`, `lib_pairs`, `lib_parsing`, `lib_patrick`, `lib_pln`, `lib_pln2`, `lib_process`, `lib_random`, `lib_redis`, `lib_reflect`, `lib_regex`, `lib_roman`, `lib_sets`, `lib_socket`, `lib_soft`, `lib_spaces`, `lib_statistics`, `lib_strategy`, `lib_string`, `lib_system`, `lib_tabling`, `lib_testing`, `lib_thread`, `lib_torch`, `lib_unicode`, `lib_uri`, `lib_uuid`, `lib_vector`, `lib_yaml`, `lib_zar`, `minimal_metta_lib`. Scored answers and every documented head are listed in
`website/reference/metta-libraries.md`.
<!-- end generated library roster -->

<!-- begin generated library glossary -->

#### lib_cli

- `cli-arguments!` (-> Expression) -- The host process argument vector as Strings, preserving numeric spelling, empty tokens and order
- `cli-help` (-> Atom String) -- Validate the same held declarations as cli-parse and render their aliases, types, literal defaults, metavariables and help
- `cli-parse` (-> Atom Expression Symbol Expression) -- Parse a held String argument vector into (Pairs Operands), where each pair is (Key Value)
- `cli-types` (-> Expression) -- The built-in option conversion names, in declaration order

#### lib_combinatorics

- `binomial` (-> Number Number Number) -- The exact number of unordered choices
- `cartesian-power` (-> Expression Number Expression) -- The Cartesian product of Length copies of Items, retaining literal values and variable sharing
- `choose2` (-> Expression Expression) -- Choose two positions, the later index varying slowest
- `choose2l` (-> Expression Expression) -- The existing collected spelling of choose2: collapse its answer stream
- `chooseK` (-> Expression Number Expression) -- Choose a nonnegative integer Count of the positions, keeping input order
- `chooseKl` (-> Expression Number Expression) -- The existing collected spelling of chooseK: collapse its answer stream
- `factorial` (-> Number Number) -- The exact factorial of a nonnegative integer, with zero giving one
- `permutation-count` (-> Number Number Number) -- How many ordered choices of Chosen items there are among Count of them, exactly: Count falling by one, Chosen times
- `permutations` (-> Expression Expression) -- Every ordering of the items, one per answer, in the host's own order: the items as given first, then the orderings that swap the latest elements
- `range-step` (-> Number Number Number Number) -- Answer numbers from From toward the excluded To, moving by a nonzero integer Step
- `range` (-> Number Number Number) -- Answer numbers from K to the excluded N in unit steps; the unit-stride specialization of range-step
- `subsets` (-> Expression Expression) -- Every subset, one per answer, each keeping the items' own order: the powerset, so n items give 2^n answers, starting with the whole set and ending with the empty one
- `takeK` (-> Number Expression Expression) -- The first K items, or the whole expression when it is shorter
- `tuples` (-> Expression Expression) -- Choose one literal value from every population, the last varying fastest

#### lib_compression

- `archive-entries!` (-> %Undefined% Expression) -- Inspect every entry as (archive-entry Index NameString PropertyPairs), with zero-based ordinals and archive order, retaining duplicate names
- `archive-extract!` (-> %Undefined% %Undefined% Bool) -- Publish regular files and directories into a missing or empty destination directory
- `archive-read!` (-> %Undefined% Number Expression) -- Read one regular entry by its zero-based ordinal
- `compress-bytes` (-> Symbol Number Expression Expression) -- Compress integers 0..255 using gzip or zlib and level 0..9
- `compress-file!` (-> Symbol Number %Undefined% %Undefined% Bool) -- Stream a file into gzip or zlib and replace Destination after all streams close successfully
- `compression-formats` (-> Expression) -- Return the byte/file envelope names gzip and zlib
- `decompress-bytes` (-> Symbol Expression Expression) -- Decode complete gzip or zlib members, concatenating their bytes
- `decompress-file!` (-> Symbol %Undefined% %Undefined% Bool) -- Stream complete gzip/zlib members into one file, replacing Destination after checksum validation and close

#### lib_crypto

- `crypto-hash-bytes` (-> %Undefined% %Undefined% String) -- Hash an expression of byte integers 0..255 without text transcoding
- `crypto-hash-file!` (-> %Undefined% %Undefined% String) -- Hash a file's bytes through a bounded buffer
- `crypto-hash` (-> %Undefined% %Undefined% String) -- Hash UTF-8 text, with the same contract as crypto_hash
- `crypto-hmac-bytes` (-> %Undefined% %Undefined% %Undefined% String) -- Authenticate raw bytes with a raw byte key; both expressions contain only integers 0..255
- `crypto-hmac` (-> %Undefined% %Undefined% %Undefined% String) -- Authenticate UTF-8 text with a UTF-8 key and a fixed-output digest
- `crypto-password-hash` (-> %Undefined% Number String) -- Derive a PBKDF2-SHA512 password record from UTF-8 Password with 16 random salt bytes and 2^Cost iterations
- `crypto-password-verify` (-> %Undefined% %Undefined% Bool) -- Verify a PBKDF2-SHA512 record, returning True or False for a valid record
- `crypto-random-bytes` (-> Number Expression) -- Return Count cryptographically secure byte integers
- `crypto-random-hex` (-> Number String) -- Return secure random hexadecimal, with the same contract as crypto_random_hex
- `crypto-random-integer` (-> Number Number Number) -- Uniformly sample Lower <= Value < Upper with secure randomness
- `crypto_hash` (-> %Undefined% %Undefined% String) -- Hash UTF-8 text to lowercase hexadecimal
- `crypto_random_hex` (-> Number String) -- Return Count secure random bytes as 2*Count lowercase hexadecimal characters

#### lib_csv

- `csv-append!` (-> %Undefined% Expression Bool) -- Append field lists as one atomic file transaction and return True
- `csv-encode` (-> Expression Expression String) -- Encode field lists as CSV
- `csv-parse` (-> %Undefined% Expression) -- Parse text into a list of field lists
- `csv-read!` (-> %Undefined% Expression) -- Stream one field list per answer from a UTF-8 file, preserving order and duplicates
- `csv-snapshot!` (-> %Undefined% Expression SpaceType) -- Read once into a fresh mutable space of (row Number Field...) atoms
- `csv-space` (-> %Undefined% Expression SpaceType) -- Return a live read-only space of (row Field...) atoms
- `csv-write!` (-> %Undefined% Expression Bool) -- Atomically replace a UTF-8 CSV file with field lists and return True

#### lib_database

- `database-add!` (-> %Undefined% Atom Bool) -- Append one held value, retaining duplicate occurrences
- `database-atoms` (-> %Undefined% Atom) -- Return an expression containing every stored value in insertion order, including duplicates
- `database-close!` (-> %Undefined% Bool) -- Finish journal, schema and lock cleanup before answering
- `database-open!` (-> %Undefined% Symbol %Undefined%) -- Open or create a store directory and return an opaque native handle
- `database-remove!` (-> %Undefined% Atom Bool) -- Remove one alpha-identical held occurrence, returning False if absent
- `database-sync!` (-> %Undefined% Bool) -- Flush and close the journal stream while retaining the store's lifetime lock
- `with-database` (-> %Undefined% Symbol Atom %Undefined%) -- Own opening directly, apply held Function to the native handle in the calling module, and yield its answers

#### lib_datastructures

- `ft-back` -- The back element, the tree untouched
- `ft-concat` -- Both trees' elements, left then right, in O(log n): the operation finger trees exist to make cheap
- `ft-empty` -- The empty finger tree; every other tree grows from it with ft-push-front and ft-push-back
- `ft-from-list` -- A finger tree holding the expression's elements in order
- `ft-front` -- The front element, the tree untouched
- `ft-is-empty` -- Whether a finger tree holds nothing
- `ft-pop-back` -- The back element and the remaining tree, as the pair ($x $rest): ft-pop-front's mirror
- `ft-pop-front` -- The front element and the remaining tree, as the pair ($x $rest)
- `ft-to-list` -- The elements front to back, as an expression: ft-from-list's inverse
- `map-empty` (-> Expression) -- The empty sorted map
- `map-from-pairs` (-> Expression Expression) -- A map holding every (Key Value) pair
- `map-get-or` (-> %Undefined% %Undefined% %Undefined% %Undefined%) -- The value Key holds, or Default when the key is absent
- `map-get` (-> %Undefined% %Undefined% %Undefined%) -- The value Key holds
- `map-has` (-> %Undefined% %Undefined% Bool) -- True when the map holds Key, False otherwise
- `map-keys` (-> %Undefined% Expression) -- Every key, in the standard order of terms
- `map-max` (-> %Undefined% Expression) -- The (Key Value) pair with the largest key
- `map-min` (-> %Undefined% Expression) -- The (Key Value) pair with the smallest key
- `map-pairs` (-> %Undefined% Expression) -- Every (Key Value) pair, in key order
- `map-put` (-> %Undefined% %Undefined% %Undefined% Expression) -- The map with Key holding Value, replacing whatever Key held
- `map-remove` (-> %Undefined% %Undefined% Expression) -- The map without Key
- `map-size` (-> %Undefined% Number) -- How many keys the map holds
- `map-values` (-> %Undefined% Expression) -- Every value, in its key's order
- `pq-empty` (-> Expression) -- The empty priority queue
- `pq-from-pairs` (-> Expression Expression) -- A queue holding every (Priority Value) pair, repeated priorities included
- `pq-insert` (-> %Undefined% %Undefined% %Undefined% Expression) -- The queue with Value added at Priority, after existing entries of that priority
- `pq-merge` (-> (:seg %Undefined%) Expression) -- One queue holding every entry of zero or more queues
- `pq-min` (-> %Undefined% Expression) -- The (Priority Value) pair at the smallest priority, without removing it
- `pq-pairs` (-> %Undefined% Expression) -- Every (Priority Value) pair in priority order, which is the sorted sequence the queue exists to produce
- `pq-pop` (-> %Undefined% Expression) -- The (Priority Value Rest) triple: the first entry at the smallest priority and the queue without that occurrence
- `pq-remove` (-> %Undefined% %Undefined% %Undefined% Expression) -- The queue without the first entry holding this identical priority and value
- `pq-size` (-> %Undefined% Number) -- How many entries the queue holds, counting repeated priorities separately

#### lib_datetime

- `date-add` (-> Number Expression %Undefined% Number) -- Add (Years Months Days Hours Minutes Seconds) in Zone's calendar, then normalize overflow
- `date-field` (-> Expression Symbol %Undefined%) -- Read year, month, day, hour, minute, second, utc_offset, time_zone, daylight_saving, date or time
- `date-fields` (-> Expression Expression) -- Enumerate (Field Value) pairs from a date record, omitting unknown zone/DST
- `date-timestamp` (-> Expression Number) -- Convert (date Y M D) at UTC midnight or a full timestamp-date record to Unix seconds
- `date-weekday` (-> Expression Number) -- Return the weekday of a normalized calendar date: Monday 1 through Sunday 7
- `date-year-day` (-> Expression Number) -- Return the one-based day of the normalized year, including leap days
- `day-of-week` (-> Number Symbol) -- Return the UTC weekday name, with the same contract as day_of_week
- `day_of_week` (-> Number Symbol) -- Return the UTC weekday name in the process locale as a Symbol
- `format-date` (-> Number %Undefined% Symbol) -- Format Timestamp in UTC as a Symbol, with the same contract as format_date
- `format-datetime` (-> Number %Undefined% %Undefined% String) -- Format Timestamp as String in UTC, local, or integer seconds west of UTC
- `format_date` (-> Number %Undefined% Symbol) -- Format Timestamp in UTC using SWI strftime directives; return a Symbol
- `leap-year` (-> Number Bool) -- Test the proleptic Gregorian leap-year rule, including negative years
- `month-days` (-> Number Number Number) -- Count days in Month 1 through 12 of the proleptic Gregorian Year
- `now` (-> Number) -- Read Unix seconds from the system wall clock
- `parse-date` (-> %Undefined% Number) -- Parse ISO 8601, RFC 1123, RFC 1036 or asctime text, optionally selecting iso_8601, rfc_1123, rfc_1036 or asctime
- `timestamp-date` (-> Number %Undefined% Expression) -- Convert Unix seconds to (date Y M D H Min S Offset Zone DST)

#### lib_derived

- `once` (-> Atom %Undefined%) -- The first answer of an expression, and no more

#### lib_dict

- `dict-get` (-> SpaceType %Undefined% %Undefined% %Undefined%) -- The key's value, or the supplied default when the key is absent
- `dict-merge` (-> SpaceType SpaceType SpaceType) -- Put every pair of the second dict into the first, so the second's value wins on a shared key
- `dict-pop` (-> SpaceType %Undefined% %Undefined%) -- The key's value, removed from the dict
- `dict-update` (-> SpaceType %Undefined% %Undefined% SpaceType) -- Apply a function to the key's current value and put the result back, answering the dict

#### lib_encoding

- `base64-decode` (-> Symbol String Expression) -- The bytes that base64 spells under the named host decoder policy
- `base64-encode` (-> Symbol Expression String) -- The bytes as base64 in one of the two RFC 4648 alphabets: `standard`, padded with `=` as mail and JSON carry it, or `url`, which uses `-` and `_` and no padding, as a URL and a file name carry it
- `hex-decode` (-> String Expression) -- The bytes that hexadecimal spells, in either case
- `hex-encode` (-> Expression String) -- The bytes as hexadecimal, two lower-case digits each and nothing between them, which is how a hash, a key and a wire dump are all written
- `utf8-decode` (-> Expression String) -- The text those UTF-8 bytes spell
- `utf8-encode` (-> String Expression) -- The UTF-8 bytes of the text, as an expression of Numbers from 0 to 255

#### lib_file

- `append-bytes!` (-> %Undefined% Expression Bool) -- Append an expression of integers 0 to 255 to the file at Path, creating it when absent
- `append-file!` (-> %Undefined% %Undefined% Bool) -- Append UTF-8 text to the file at Path, creating it when absent
- `copy-dir!` (-> %Undefined% %Undefined% Bool) -- Copy a directory tree to a new path: the contents of Source become the contents of Destination, which must not exist; missing parents of Destination are created
- `copy-file!` (-> %Undefined% %Undefined% Bool) -- Copy bytes to a destination filename with staged replacement: the copy is written beside the destination, both streams close, and one rename publishes it, so an existing destination is replaced only after the complete copy succeeds
- `delete-dir!` (-> %Undefined% Bool) -- Remove an empty directory; missing or nonempty directories raise
- `delete-file!` (-> %Undefined% Bool) -- Remove a regular file; an absent file is already removed and answers True
- `delete-tree!` (-> %Undefined% Bool) -- Remove whatever is at Path: a directory with everything under it, a file, or a symbolic link, which is unlinked without touching its target
- `dir-exists` (-> %Undefined% Bool) -- True when a directory exists at the path, following links, False otherwise
- `dir-glob` (-> %Undefined% %Undefined% Expression String) -- Answer every path under Directory matching a relative pattern of slash-separated components, in depth-first codepoint order
- `dir-walk` (-> %Undefined% Expression String) -- Answer every descendant of a directory, one full path per answer, depth first with each directory's names in codepoint order
- `exit!` (-> %Undefined% %Undefined%) -- Terminate the entire process with integer status 0 through 255, including an embedding host; not an application-level return, so MeTTa catch does not turn it into a local value
- `file-close!` (-> %Undefined% Bool) -- Close a handle file-open! gave
- `file-exists` (-> %Undefined% Bool) -- True when a regular file exists at the path, following links, False otherwise
- `file-get-size!` (-> %Undefined% Number) -- Answer the size of the whole file in bytes, not of what is left to read, so seeking does not change the answer; a handle without a file name measures the stream position instead
- `file-kind` (-> %Undefined% Symbol) -- Classify the entry at Path without following it: link for a symbolic link, dangling or not; directory; file; other for an entry that exists and is none of those, such as a FIFO, socket or device; missing when nothing is observable at the path
- `file-lines!` (-> %Undefined% Expression) -- The lines of a UTF-8 file as an expression of Strings, split on LF with one terminal empty line omitted; CR and NUL stay data
- `file-metadata!` (-> %Undefined% %Undefined%) -- Snapshot kind, modified Unix time and file size as queryable atoms in a new space: (kind file|directory), (modified Seconds) and, for a file, (size Bytes)
- `file-open!` (-> %Undefined% %Undefined% Number) -- Open a file and answer a handle
- `file-read-bytes!` (-> %Undefined% %Undefined% Expression) -- Read the remaining bytes, or at most Count bytes, from a binary handle's cursor as an expression of integers 0 to 255
- `file-read-exact!` (-> %Undefined% %Undefined% String) -- Read at most Count characters from a text handle's cursor, HE's contract: a short read near the end of the file is the answer, not an error
- `file-read-to-string!` (-> %Undefined% String) -- Read from the cursor to the end of a text handle as one String
- `file-seek!` (-> %Undefined% %Undefined% Bool) -- Move the cursor to a byte offset from the start of the file, so the next read starts there; a negative position moves to the start
- `file-space!` (-> %Undefined% %Undefined%) -- A file as a SPACE, the mettafied reading of reading a file: its lines become (line Number Text) atoms in a fresh space, so the file is queryable with match instead of being one long string to take apart
- `file-write!` (-> %Undefined% %Undefined% Bool) -- Write text to a text handle and flush, adding no newline
- `file-write-bytes!` (-> %Undefined% Expression Bool) -- Write an expression of integers 0 to 255 to a binary handle and flush
- `list-dir!` (-> %Undefined% Expression) -- The names in a directory, without 
- `make-dir!` (-> %Undefined% Bool) -- Create a directory and missing parents; an existing directory succeeds
- `make-link!` (-> %Undefined% %Undefined% Bool) -- Create a symbolic link at Path holding Target exactly as written; a relative target is read relative to the link's own directory
- `path-absolute` (-> %Undefined% String) -- Anchor a relative path to the process working directory and normalize it lexically, as CPython's posixpath.abspath does; no links are resolved
- `path-extension` (-> %Undefined% String) -- Text after the final dot in the filename, without the dot; empty when absent
- `path-join` (-> %Undefined% %Undefined% String) -- Join lexical paths; an absolute second path replaces the first
- `path-name` (-> %Undefined% String) -- Lexical final path component
- `path-normalize` (-> %Undefined% String) -- Collapse repeated separators and dot components and resolve 
- `path-parent` (-> %Undefined% String) -- Lexical parent directory; a bare filename has parent dot
- `path-parts` (-> %Undefined% Expression) -- The components of a path as an expression of Strings: \"/\" first for an absolute path, empty and dot components dropped, 
- `path-relative` (-> %Undefined% %Undefined% String) -- The path from the directory Start to Path, lexically, as CPython's posixpath.relpath does: both are made absolute, the common prefix is dropped, and one 
- `path-resolve` (-> %Undefined% String) -- The absolute path with every symbolic link on the way replaced by what it points to, as CPython's non-strict posixpath.realpath does: a relative path starts at the process working directory, a link's target is read before any later 
- `path-stem` (-> %Undefined% String) -- The final path component without its extension, the complement of path-extension: \"a/b.tar.gz\" has stem \"b.tar\", and \".env\" has stem \"\"
- `read-bytes!` (-> %Undefined% Expression) -- Read a whole file as an expression of integers 0 to 255
- `read-file!` (-> %Undefined% String) -- Read a whole UTF-8 file as one String without the open/close dance
- `read-link` (-> %Undefined% String) -- The text a symbolic link holds, exactly as it was written, relative or absolute; a path that is not a link raises with its kind
- `rename-file!` (-> %Undefined% %Undefined% Bool) -- Rename a file or directory within one filesystem, the host's own rename: a file replaces an existing file and a directory replaces an existing empty directory in one step, so a reader sees the old entry or the new one
- `replace-file!` (-> %Undefined% %Undefined% Bool) -- Publish a new file at Path by rename: the content is written to a staging file beside the destination, closed, and renamed over Path in one step, so a reader sees the old file or the complete new one and never a partial write
- `same-file` (-> %Undefined% %Undefined% Bool) -- True when both paths name one physical file or directory, through links, hard links and different spellings; False when they differ or either is missing
- `stderr!` (-> %Undefined% Bool) -- Write text to stderr and flush, without adding a newline
- `stderr` (-> Number) -- The handle for standard error, which is 2; (file-write! (stderr) $text) is stderr! reached through the handle surface
- `stdin-to-string!` (-> String) -- Consume standard input through EOF as UTF-8 text
- `stdin` (-> Number) -- The handle for standard input, which is 0; every handle operation takes it, so (file-read-to-string! (stdin)) reads standard input through EOF
- `stdout` (-> Number) -- The handle for standard output, which is 1; (file-write! (stdout) $text) writes without a newline
- `temp-dir!` (-> %Undefined% String) -- A unique fresh directory in the system temporary directory, created exclusively so concurrent runners cannot mint the same name; the caller owns it and removes it with delete-dir! or delete-tree!
- `temp-path!` (-> %Undefined% String) -- A unique fresh path in the system temporary directory, created exclusively so concurrent runners cannot mint the same name; the caller owns the file from that point (write-file! truncates it, delete-file! ends it)
- `with-file` (-> %Undefined% %Undefined% %Undefined% %Undefined%) -- Open Path with file-open!'s option letters, apply Function to the handle and answer every result of that application; the handle closes when the answers are exhausted, when the caller stops after one, and when the body raises
- `with-temp-dir` (-> %Undefined% %Undefined% %Undefined%) -- Mint a fresh directory with temp-dir!, apply Function to its path and answer every result; the directory and everything under it are removed when the answers are exhausted, when the caller stops after one, and when the body raises
- `write-bytes!` (-> %Undefined% Expression Bool) -- Create or truncate the file at Path in place and write an expression of integers 0 to 255
- `write-file!` (-> %Undefined% %Undefined% Bool) -- Create or truncate the file at Path in place and write UTF-8 text

#### lib_functional

- `apply-to` (-> %Undefined% Expression %Undefined%) -- Apply Function to zero or more literal argument values
- `chunk` (-> Expression Number Expression) -- The collection cut into pieces of that size, in order, with a shorter last piece when the size does not divide the length
- `drop` (-> Expression Number Expression) -- The collection without its first Count elements, and empty when there are fewer than that
- `flatten-deep` (-> Expression Expression) -- Every level of nesting removed, so the answer holds only the leaves, in order
- `flatten-once` (-> Expression Expression) -- One level of nesting removed: the elements of every element that is itself a collection, in order, with anything else kept as it is
- `group-by` (-> %Undefined% Expression Expression) -- Gather items into (Key Members) groups in first-appearance order
- `partition` (-> %Undefined% Expression Expression) -- Split Items into (Yes No), preserving input order
- `pipe` (-> Atom %Undefined% %Undefined%) -- Pass Value through a held collection of functions from left to right
- `repeat` (-> Number Atom %Undefined%) -- Evaluate the held body that many times, answering each result
- `scan` (-> %Undefined% %Undefined% Expression Expression) -- Every running fold result, beginning with Start
- `sort-by` (-> %Undefined% Expression Expression) -- Compute a key for each item, sort the groups by term order and concatenate their members
- `unfold` (-> %Undefined% %Undefined% Expression) -- Grow a collection from a seed
- `unless` (-> Atom Atom %Undefined%) -- Evaluate the held body when the held condition answers False, and answer nothing when it answers True: if with one arm, read the other way round
- `unzip` (-> Expression Expression) -- The two collections a zip was made from, as (Lefts Rights)
- `while` (-> Atom Atom %Undefined%) -- Evaluate the held body while the held condition answers True, answering each body result
- `window` (-> Expression Number Expression) -- Every run of that many consecutive elements, overlapping by all but one: the sliding window a moving average or a bigram is written over
- `zip` (-> Expression Expression Expression) -- The pairs of corresponding elements, truncating at the shorter collection, so zipping a long one with a short one answers the short one's length

#### lib_graph

- `graph-add-edges` (-> Expression Expression Expression) -- Add edges written (From To), including their endpoints as vertices
- `graph-add-vertices` (-> Expression Expression Expression) -- Add vertices, retaining existing edges
- `graph-closure` (-> Expression Expression) -- The transitive closure: an edge for every path of one or more steps
- `graph-edges` (-> Expression Expression) -- Every edge as a (From To) pair, ordered by tail and then head
- `graph-is-acyclic` (-> Expression Bool) -- Whether no vertex reaches itself through one or more edges
- `graph-is` (-> %Undefined% Bool) -- Whether a finite expression consists of (Vertex Neighbours) rows with canonical vertex and neighbour sets, and every neighbour identical to a vertex
- `graph-neighbours` (-> Expression %Undefined% Expression) -- The vertex's outgoing neighbours as a set
- `graph-of` (-> Expression Expression Expression) -- Build canonical (Vertex Neighbours) rows from (From To) edges and extra isolated vertices
- `graph-reachable` (-> Expression %Undefined% Expression) -- Every reachable vertex, including the origin, as a set
- `graph-remove-edges` (-> Expression Expression Expression) -- Remove the named edges, retaining every vertex
- `graph-remove-vertices` (-> Expression Expression Expression) -- Remove vertices and every incident edge
- `graph-topological-order` (-> Expression Expression) -- Unfold zero-indegree layers and concatenate them
- `graph-transpose` (-> Expression Expression) -- Reverse every edge, retaining all vertices
- `graph-union` (-> (:seg Expression) Expression) -- Unite zero or more graphs
- `graph-vertices` (-> Expression Expression) -- Every vertex in canonical term order

#### lib_http

- `http-header` (-> Expression String %Undefined%) -- Enumerate every matching parsed field, case-insensitively and in received order
- `http-methods` (-> Expression) -- The installed client's method symbols, including extensions registered with its native method map
- `http-open!` (-> Symbol String Expression Expression) -- Open (http-response Status Fields Handle)
- `http-request!` (-> Symbol String Expression Expression) -- Read (http-response Status Fields Bytes) and close its stream before returning
- `http-server-start!` (-> String Number Atom Expression Expression) -- Listen at Host and Port; zero asks the OS for a free port
- `http-server-stop!` (-> Expression Bool) -- Finish active requests and release the server's workers, queue and listener
- `http-server-url` (-> Expression String) -- The server's HTTP origin, with IPv6 brackets when needed and a trailing slash
- `with-http-server` (-> String Number Atom Expression Atom %Undefined%) -- Apply held Function to the evaluated server value and yield every answer
- `with-http` (-> Symbol String Expression Atom %Undefined%) -- Apply a held Function to the evaluated streaming response and yield every answer

#### lib_import

- `import_prolog_functions_from_file` -- Consults a Prolog file and registers the named predicates as MeTTa functions
- `import_prolog_functions_from_module` -- Loads a Prolog module and registers the named predicates as MeTTa functions
- `imports` -- A live read-only space of (import CanonicalPath) atoms for the destination's committed MeTTa source imports; query with (match (imports &space) (import $path) $path)
- `unimport!` -- Withdraw exactly one MeTTa source's surviving native atoms and compiled definitions; equal atoms from other owners survive

#### lib_json

- `dict-space` (-> Expression SpaceType) -- Build a fresh object space from (Key Value) pairs
- `get-keys` (-> SpaceType %Undefined%) -- Enumerate object keys in storage order, preserving duplicates
- `get-value` (-> SpaceType %Undefined% %Undefined%) -- Enumerate values whose keys unify with Key
- `json-at` (-> %Undefined% Expression %Undefined%) -- Follow object keys and zero-based array indexes
- `json-decode` (-> %Undefined% %Undefined%) -- Decode one JSON document
- `json-encode` (-> %Undefined% String) -- Encode one compact JSON document
- `json-lines-decode` (-> %Undefined% %Undefined%) -- Enumerate JSON values from LF or CRLF lines
- `json-lines-encode` (-> Expression String) -- Encode each value as one compact JSON line, ending every record with LF
- `json-lines-read!` (-> %Undefined% %Undefined%) -- Stream UTF-8 JSON Lines from Path, reading at most one record ahead
- `json-lines-write!` (-> %Undefined% Expression Bool) -- Atomically replace Path with UTF-8 JSON Lines, serializing one record at a time
- `json-pretty` (-> %Undefined% Number String) -- Format JSON with a nonnegative target column width
- `json-read!` (-> %Undefined% %Undefined%) -- Read one UTF-8 JSON file, closing it before creating object spaces
- `json-write!` (-> %Undefined% %Undefined% Bool) -- Atomically replace Path with one compact UTF-8 JSON document

#### lib_logging

- `log!` (-> String Symbol Atom Expression) -- Send a held payload through print_message/2 when its topic is enabled
- `log-enabled` (-> String Bool) -- Whether the exact topic is enabled
- `log-format` (-> String Symbol Atom String) -- The message's diagnostic text, whether or not its topic is enabled
- `log-levels` (-> Expression) -- The supported host message levels
- `log-to!` (-> Atom String Symbol Atom Expression) -- Send through the host message mechanism with an explicit MeTTa handler
- `log-topic!` (-> String Bool Expression) -- Enable or disable this exact topic for every level
- `log-topics` (-> Expression) -- A sorted snapshot of configured (log-topic Name Enabled) rows

#### lib_markup

- `markup-attribute` (-> %Undefined% Atom String) -- One attribute's value as a String, with no answer when the element does not carry it, which is the shape a lookup has here and in lib_pairs
- `markup-parse-html` (-> %Undefined% Expression) -- One HTML document in the same shape
- `markup-parse-xml` (-> %Undefined% Expression) -- One XML document as (element Name Attributes Children): the name a Symbol, each attribute an (attr Name Value) row and the children an expression of elements and Strings
- `markup-select` (-> %Undefined% Atom %Undefined%) -- Every match of the selector, one answer each and in document order
- `markup-text` (-> %Undefined% String) -- Every text node under the element, in document order, joined: the content a reader sees with the markup taken out
- `markup-write` (-> %Undefined% String) -- The element as XML text, without the declaration the host writes by default and without layout, so the text is exactly the element's own markup and parses back to it

#### lib_math

- `math-class` (-> Number Symbol) -- The numeric species: integer, rational, or a host float class of zero, subnormal, normal, infinite or nan
- `math-factor-pairs` (-> Number Expression) -- Stream positive (A B) factor pairs of a positive integer with A<=B, in ascending A order
- `math-float` (-> Number Number) -- Convert a Number to binary64 by scaling one coordinate by 1.0
- `math-gcd` (-> Expression Number) -- The nonnegative greatest common divisor of a finite expression of integers
- `math-integer-root` (-> Number Number Expression) -- Exact (Root Remainder) with Root^Degree+Remainder=Value
- `math-lcm` (-> Expression Number) -- The nonnegative least common multiple
- `math-power-mod` (-> Number Number Number Number) -- Compute Base^Exponent modulo a positive Modulus using native modular exponentiation, without constructing the full power
- `math-ratio` (-> Number Expression) -- The exact (Numerator Denominator) of a finite Number
- `math-rational` (-> Number Number) -- Construct an exact reduced Number with a positive denominator
- `math-rationalize` (-> Number Number) -- Preserve exact numbers and approximate finite floats within the host's floating rounding error, often with a much smaller denominator
- `math-real-functions` (-> Expression) -- The native floating functions provided here as (math-function Name Arity) rows
- `math-real` (-> Symbol Expression Number) -- Apply one function listed by math-real-functions to its numeric arguments
- `math-sqrt` (-> Number Number) -- Correctly rounded floating square root of a nonnegative finite Number

#### lib_observe

- `observe-source` (-> SpaceType String String SpaceType) -- Run source with coverage and error diagnostics
- `trace-source` (-> SpaceType String Atom Number SpaceType) -- Run source in a space and return a space of trace-event atoms

#### lib_pairs

- `pairs-group` (-> Expression Expression) -- The relation as a multimap: every key once, in the standard order of terms, with every value it has as (Key Values)
- `pairs-is` (-> %Undefined% Bool) -- Whether the value is a relation: a collection whose every element is a two-element expression
- `pairs-keys` (-> Expression Expression) -- The key of every pair, in order and with duplicates kept, so the length is the relation's own
- `pairs-lookup` (-> Expression %Undefined% %Undefined%) -- Every value whose key is identical to Key, in input order
- `pairs-sort-by-key` (-> Expression Expression) -- The relation ordered by key in the standard order of terms, STABLY: pairs with equal keys keep their relative order, and none is dropped
- `pairs-sort-by-value` (-> Expression Expression) -- The relation ordered stably by its values in the standard order of terms
- `pairs-swap` (-> Expression Expression) -- The converse relation with the order kept: every (Key Value) becomes (Value Key) where it stands
- `pairs-ungroup` (-> Expression Expression) -- The relation a multimap holds: one (Key Value) per value, keys in the multimap's order and values in each group's order
- `pairs-values` (-> Expression Expression) -- The value of every pair, in order and with duplicates kept

#### lib_parsing

- `grammar-forms` (-> Expression) -- Return the (Name Arity) rows from the same parsing-form metadata that prepares grammars
- `grammar-is` (-> Atom Bool) -- Whether the held value is a well-formed grammar under parsing-form metadata
- `grammar-parse-prefix` (-> Atom String Expression) -- Parse a prefix and return (Value UnreadString), one answer per match
- `grammar-parse` (-> Atom String %Undefined%) -- Parse the whole String with a held grammar
- `grammar-parser` (-> Atom %Undefined%) -- Prepare a held grammar as an ordinary unary function over a finite expression of input tokens

#### lib_process

- `process-run!` (-> %Undefined% %Undefined% Expression) -- Run the program with those arguments, wait for it, and answer (process-result Code Output Error): the exit code as a Number, and everything it wrote to its two streams as Strings
- `process-run-input!` (-> %Undefined% %Undefined% %Undefined% Expression) -- The same, with that text written to the program's standard input and the stream closed, which is how a program that reads its input is fed without a temporary file
- `process-signal!` (-> %Undefined% Symbol Bool) -- Send one of the signals this library names: `term` asks a program to stop, `kill` takes it away without asking, `int` is what a terminal's interrupt sends and `hup` is what a closed terminal sends
- `process-signals` (-> Expression) -- Every signal process-signal! sends, as data: the same list its refusal names
- `process-start!` (-> %Undefined% %Undefined% Number) -- Start the program and answer its identifier without waiting
- `process-status` (-> %Undefined% %Undefined%) -- Whether the process is still running, without waiting for it: the Symbol `running` while it is, and its exit code once it is not
- `process-wait!` (-> %Undefined% Number) -- Wait for the process and answer its exit code, or the negative of the signal that ended it

#### lib_random

- `random-bernoulli` (-> Number Expression) -- A Bool sample program with finite Probability in [0,1]
- `random-beta` (-> Number Number Expression) -- A beta sample program with finite positive Alpha and Beta
- `random-choice` (-> Atom Expression) -- A sample program that chooses one occurrence uniformly from held, nonempty Items
- `random-exponential` (-> Number Expression) -- An exponential sample program with a finite positive Rate
- `random-gamma` (-> Number Number Expression) -- A gamma sample program with finite positive Shape and Scale
- `random-lognormal` (-> Number Number Expression) -- Exponentiate the program made by random-normal
- `random-normal` (-> Number Number Expression) -- A normal sample program with finite Mean and nonnegative StandardDeviation
- `random-pareto` (-> Number Expression) -- A Pareto sample program with finite positive Shape and minimum one
- `random-sample!` (-> Atom Number Expression) -- Select Count ordered, distinct positions from held Items
- `random-shuffle!` (-> Atom Expression) -- A permutation of all held occurrences, derived by sampling the population size without replacement
- `random-triangular` (-> Number Number Number Expression) -- A triangular sample program with finite Low<=Mode<=High
- `random-uniform` (-> Number Number Expression) -- A uniform sample program between finite Low and High, with Low<=High
- `random-weibull` (-> Number Number Expression) -- A Weibull sample program with finite positive Scale and Shape

#### lib_reflect

- `arity-of` -- The registered arities for a name, one per solution
- `atom-replace` (-> Atom Atom %Undefined%) -- Replace exact subterms through a literal (From To) relation
- `atom-variables` (-> Atom Expression) -- Every written variable once, in first-appearance order, preserving its identity and sharing with the original term
- `builtins` -- Every builtin name, one per solution
- `extension-points` -- Every extension point the engine declares, as (name arity kind), one per solution
- `functions` -- Every function the engine knows, builtin or not
- `knows?` -- Whether the engine knows a name at all, as True or False
- `origin-of` (-> Atom Expression) -- The (origin space file line) rows from get-property, one per defining occurrence; an unavailable line is -1
- `special-forms` -- Every translator special form, one per solution
- `surface-counts` -- How many builtins, special forms, functions and user functions
- `surface-json` -- The engine's whole surface as a JSON string, for external tools
- `user-functions` -- Every function this space defines itself

#### lib_regex

- `re-captures` (-> %Undefined% %Undefined% Expression) -- Return the first match's capture pairs, with the regex_captures contract
- `re-compile` (-> %Undefined% %Undefined%) -- Compile pattern text to an immutable native regex value accepted by every regex operation
- `re-count` (-> %Undefined% %Undefined% Number) -- Count matches using re-find's empty-match progression
- `re-escape` (-> %Undefined% String) -- Quote literal text for a PCRE2 pattern, including whitespace in extended mode and embedded \\E quoting terminators
- `re-find` (-> %Undefined% %Undefined% String) -- Enumerate every whole match, with the regex_find contract
- `re-fullmatch` (-> %Undefined% %Undefined% Bool) -- Return whether one match covers all Text
- `re-match` (-> %Undefined% %Undefined% Bool) -- Return whether Pattern matches anywhere in Text, with the regex_match contract
- `re-ranges` (-> %Undefined% %Undefined% Expression) -- Enumerate (Start Length) records for whole matches in Unicode characters, starting at zero
- `re-replace-all` (-> %Undefined% %Undefined% %Undefined% String) -- Replace every match, with the regex_replace_all contract
- `re-replace` (-> %Undefined% %Undefined% %Undefined% String) -- Replace the first match, with the regex_replace contract
- `re-scan` (-> %Undefined% %Undefined% Expression) -- Enumerate capture-pair records for every match in order
- `re-split` (-> %Undefined% %Undefined% Expression) -- Split Text into skipped/matched parts, with the regex_split contract
- `regex_captures` (-> %Undefined% %Undefined% Expression) -- Return the first match as ((Key Value) ...) pairs
- `regex_find` (-> %Undefined% %Undefined% String) -- Enumerate every whole match in left-to-right order, preserving repeated and empty answers
- `regex_match` (-> %Undefined% %Undefined% Bool) -- Return whether Pattern matches anywhere in Text
- `regex_replace_all` (-> %Undefined% %Undefined% %Undefined% String) -- Replace every match, including empty matches and a nonempty alternative at the same position
- `regex_replace` (-> %Undefined% %Undefined% %Undefined% String) -- Replace the first match
- `regex_split` (-> %Undefined% %Undefined% Expression) -- Return alternating skipped and matched Strings, beginning and ending with a skipped part

#### lib_sets

- `set-difference` (-> Expression Expression Expression) -- The elements of the first that the second does not hold
- `set-disjoint` (-> Expression Expression Bool) -- Whether they share no element
- `set-insert` (-> Expression %Undefined% Expression) -- The set with the element added, which is the set itself when it was already there
- `set-intersection` (-> (:seg Expression) Expression) -- The elements every argument holds, once
- `set-is` (-> %Undefined% Bool) -- Whether the value is a set: an expression in the standard order of terms with no duplicates
- `set-member` (-> Expression %Undefined% Bool) -- Whether the term belongs to the canonical set
- `set-of` (-> Expression Expression) -- Canonicalize an expression through unique-atom and sort-atom: each literal term once, in the standard order of terms
- `set-remove` (-> Expression %Undefined% Expression) -- The set without the element, which is the set itself when it was not there, so removing something absent is not an error
- `set-subset` (-> Expression Expression Bool) -- Whether every element of the first is in the second
- `set-symmetric-difference` (-> Expression Expression Expression) -- The elements exactly one of them holds, which is the union of the two differences and the same set whichever way round the arguments go
- `set-union` (-> (:seg Expression) Expression) -- Every element of any canonical input set, once and in term order

#### lib_socket

- `socket-endpoint` (-> Number Symbol Expression) -- Return (endpoint ipv4|ipv6 NumericHostString Port) for local or peer
- `socket-kind` (-> Number Symbol) -- Return listener, tcp or udp from the live descriptor
- `socket-shutdown!` (-> Number Symbol Bool) -- Shut down a TCP connection's read, write or both directions
- `socket-wait!` (-> Expression %Undefined% Expression) -- Wait for readable sockets using nonnegative finite seconds or infinite
- `tcp-accept!` (-> Number Number) -- Wait for one connection and return its independent binary File handle
- `tcp-connect!` (-> Expression Number) -- Connect to (endpoint ipv4|ipv6 HostString Port), resolving Host in that family
- `tcp-listen!` (-> Expression Number Number) -- Bind and listen at an endpoint, allowing port zero to request a free port
- `udp-bind!` (-> Expression Number) -- Bind an IPv4 or IPv6 datagram socket, allowing port zero
- `udp-receive!` (-> Number Expression) -- Wait for (datagram Endpoint Bytes), retaining a complete numeric sender endpoint, empty packets and arbitrary bytes
- `udp-send!` (-> Number Expression Expression Bool) -- Send one datagram, including an empty one
- `with-socket` (-> Atom Atom %Undefined%) -- Evaluate held Acquire once and take ownership of its returned socket handle

#### lib_soft

- `soft-symbol?` (-> Atom Bool) -- Tests written symbol representation, regardless of function registration

#### lib_spaces

- `move-atoms` (-> SpaceType SpaceType Atom %Undefined%) -- Add the atoms matching a pattern to another space and remove them from the source; one answer per atom moved
- `space-copy` (-> SpaceType SpaceType Atom %Undefined%) -- Copy the atoms matching a pattern into another space, leaving the source unchanged; one answer per atom copied
- `space-drain` (-> SpaceType Atom %Undefined%) -- Remove the atoms matching a pattern and answer each removed atom, so a caller sees what left
- `space-snapshot` (-> SpaceType SpaceType) -- A fresh space holding a copy of every atom, so what a space holds now survives later writes to it
- `space-subtract` (-> SpaceType SpaceType %Undefined%) -- Remove from a space every atom another space holds; one answer per atom attempted, including an atom the space did not hold

#### lib_statistics

- `stats-correlation` (-> Expression Expression Number) -- Pearson correlation, correctly rounded into [-1,1] from exact paired moments
- `stats-covariance` (-> Expression Expression Number Number) -- Paired covariance, dividing the sum of centered products by N-DegreesOfFreedom
- `stats-geometric-mean` (-> Expression Number) -- Floating geometric mean of nonnegative finite observations
- `stats-harmonic-mean` (-> Expression Number) -- N divided by the sum of reciprocals, for nonnegative finite observations
- `stats-mean` (-> Expression Number) -- Arithmetic mean of a nonempty finite expression, with stats-sum's exact accumulation and result type
- `stats-median` (-> Expression Number) -- Middle observation, or the exact mean of the two middle observations
- `stats-mode` (-> Atom %Undefined%) -- Every most frequent held term, once, in first-occurrence order
- `stats-quantile` (-> Expression Number Symbol Number) -- Linearly interpolate sorted observations at Probability in [0,1]
- `stats-quantiles` (-> Expression Number Symbol Expression) -- The Partitions-1 cut points at i/Partitions, using stats-quantile's inclusive or exclusive interpolation
- `stats-ranks` (-> Expression Expression) -- One-based numeric ranks in input order
- `stats-regression` (-> Expression Expression Bool Expression) -- Least-squares (linear-fit Slope Intercept) from finite paired observations
- `stats-stdev` (-> Expression Number Number) -- Correctly rounded floating square root of the exact variance
- `stats-sum` (-> Expression Number) -- Sum finite observations exactly before any rounding
- `stats-variance` (-> Expression Number Number) -- Sum of squared deviations divided by N-DegreesOfFreedom
- `weighted-subset-mass-independent` (-> Atom Number Expression) -- Exact mass of an independent additive observation, as a reduced (ratio N D)
- `weighted-subset-posterior-independent` (-> Atom Number Expression) -- Return (subset-posterior Mass ((candidate-posterior ID Ratio) ...)) in candidate order under the mass operation's exact-input contract
- `ws-add-bernoulli-independent` (-> Expression Number %Undefined%) -- Add one independent Bernoulli trial with finite Probability in [0,1] to every numeric outcome
- `ws-average-independent` (-> Expression %Undefined%) -- The law of the arithmetic mean of a nonempty expression of mutually independent numeric laws
- `ws-central-moment` (-> Expression Number %Undefined%) -- The nonnegative integer Degree moment about a numeric law's mean
- `ws-condition-joint` (-> Expression Atom %Undefined%) -- Condition a joint law of (Pair Input Output) values on the held observed Input, using term identity
- `ws-deviation` (-> Expression %Undefined%) -- The floating square root of ws-variance, in the outcome's units
- `ws-map-independent` (-> %Undefined% (:seg Expression) %Undefined%) -- Push a function through zero or more independent finite laws
- `ws-map` (-> %Undefined% Expression %Undefined%) -- Push a function through one finite law
- `ws-mass-at-least` (-> Expression Number %Undefined%) -- Inclusive upper-tail probability P(X>=Threshold) of a numeric finite law
- `ws-mass-at-most` (-> Expression Number %Undefined%) -- Inclusive cumulative probability P(X<=Threshold) of a numeric finite law
- `ws-median` (-> Expression %Undefined%) -- The finite law's inverse CDF at one half
- `ws-prob-gt-independent` (-> Expression Expression %Undefined%) -- Strict independent win probability P(X>Y)
- `ws-quantile` (-> Expression Number %Undefined%) -- The smallest supported value whose cumulative mass reaches the finite Level in (0,1]
- `ws-sum-independent` (-> Expression Number %Undefined%) -- The law of a total of Count independent draws
- `ws-support` (-> Expression %Undefined%) -- The law's supported values, once each, in increasing term order
- `ws-variance` (-> Expression %Undefined%) -- The second central moment of a numeric finite law

#### lib_strategy

- `TP` Type -- The type-preserving strategy scheme: accept a declared arrow with the same input and output sort
- `TU` (-> Type Type) -- The type-unifying strategy scheme: accept a declared arrow whose output has the supplied sort
- `all` (-> Atom Atom %Undefined%) -- Apply a strategy to all immediate children
- `alltd` (-> Atom Atom %Undefined%) -- Return every root rewrite when the strategy has answers; otherwise descend into every child
- `bottomup` (-> Atom Atom %Undefined%) -- Recursively rewrite children, then their rebuilt parent
- `choice` (-> Atom (:seg Atom) %Undefined%) -- Use the first strategy with any answers and preserve its whole bag
- `fail` (-> Atom %Undefined%) -- Decline every term
- `gtry` (-> Atom Atom %Undefined%) -- The generic try spelling: apply a strategy or preserve the original term when it declines
- `innermost` (-> Atom Atom %Undefined%) -- Rewrite children before parents and revisit every reduct until no rule applies
- `one` (-> Atom Atom %Undefined%) -- Apply a strategy at exactly one child position, preserving every successful position as an answer
- `seq` (-> Atom (:seg Atom) %Undefined%) -- Apply zero or more held strategies from left to right to the final literal term
- `stratego-all` (-> Atom Atom %Undefined%) -- The Stratego spelling of all: rewrite all immediate children, preserving leaves
- `stratego-one` (-> Atom Atom %Undefined%) -- The Stratego spelling of one: answer every successful single-child rewrite
- `strategy-all-tail` (-> Atom Atom %Undefined%) -- Map a strategy over a literal expression through map-atom
- `strategy-all` (-> Atom Atom %Undefined%) -- Rewrite every immediate child, including an expression's head
- `strategy-apply` (-> Atom Atom %Undefined%) -- Lower a held strategy application to strategy-eval through the ordinary translator-rule door
- `strategy-choice-tail` (-> Atom Atom %Undefined%) -- Apply held strategies in order until one has answers, then return that complete bag
- `strategy-eval` (-> Atom Atom %Undefined%) -- Apply a held rewrite plan or callable value to a literal term
- `strategy-one` (-> Atom Atom %Undefined%) -- Rewrite exactly one immediate child, answering every successful position from left to right
- `strategy-repeat` (-> Atom Atom %Undefined%) -- Repeat a rewrite until it declines, retaining every resulting normal form
- `strategy-typed-apply` (-> Atom Type Atom %Undefined%) -- Apply a strategy when match-types accepts the term's current-space type against the expected sort
- `strategy-typed-tp` (-> Atom Atom %Undefined%) -- Match a strategy's equal input and output sorts, then apply it when the term fits that sort
- `strategy-typed-tu` (-> Atom Type Atom %Undefined%) -- Match a strategy's declared output against the requested result sort, then check its input sort and apply it
- `topdown` (-> Atom Atom %Undefined%) -- Rewrite the root, then recursively visit the children of each result
- `try` (-> Atom Atom %Undefined%) -- Apply the strategy, or return the original term when it has no answers
- `◁` (-> Atom Type Atom %Undefined%) -- Apply a declared strategy through TP or TU(ResultSort), filtering its input by the term's type in the current space

#### lib_string

- `number-to-string` (-> Number String) -- Return the host String representation of a Number, including rationals
- `parse-number` (-> %Undefined% Number) -- Parse the host numeric syntax
- `string-center` (-> %Undefined% Number %Undefined% String) -- Assign half the missing codepoints to the left; an odd extra character goes on the right
- `string-chars` (-> %Undefined% Expression) -- Return one-character Strings, preserving Unicode and embedded NUL
- `string-codes` (-> %Undefined% Expression) -- Return Unicode scalar integers
- `string-contains` (-> %Undefined% %Undefined% Bool) -- Test the shared search index for a literal occurrence, including an empty Part
- `string-count` (-> %Undefined% %Undefined% Bool Number) -- Count literal occurrences, nonoverlapping by default
- `string-dedent` (-> %Undefined% String) -- Remove the common literal space/tab prefix of nonblank LF-separated lines
- `string-edit-distance` (-> %Undefined% %Undefined% Number) -- Return exact unit-cost Levenshtein distance over Unicode codepoints
- `string-ends-with` (-> %Undefined% %Undefined% Bool) -- Compare the final codepoint slice with the coerced suffix
- `string-from-chars` (-> Expression String) -- Join text items with an empty separator
- `string-from-codes` (-> Expression String) -- Build a String from Unicode scalar integers
- `string-indent` (-> %Undefined% %Undefined% String) -- Prefix each LF-separated line except lines containing only spaces and tabs
- `string-index-of` (-> %Undefined% %Undefined% Number) -- Return the first zero-based codepoint index, or -1
- `string-isub` (-> %Undefined% %Undefined% Expression Number) -- Return SWI's substring-based ontology-label ISub score, preserving complete text
- `string-join` (-> %Undefined% Expression String) -- Join coerced text parts once with Separator; an empty list produces \"\"
- `string-last-index-of` (-> %Undefined% %Undefined% Number) -- Return the last zero-based codepoint index, including overlapping matches, or -1
- `string-length` (-> %Undefined% Number) -- Count Unicode codepoints, including embedded NUL
- `string-lines` (-> %Undefined% Expression) -- Split at LF and omit one terminal empty component
- `string-lower` (-> %Undefined% String) -- Apply the host Unicode lowercase mapping and return a String
- `string-pad-left` (-> %Undefined% Number %Undefined% String) -- Assign all missing padding to the left through the shared MeTTa padding equation
- `string-pad-right` (-> %Undefined% Number %Undefined% String) -- Assign no padding to the left, using string-pad-left's width and filler rules
- `string-repeat` (-> %Undefined% Number String) -- Collect a range of text copies and join once
- `string-replace` (-> %Undefined% %Undefined% %Undefined% String) -- Replace every nonoverlapping literal occurrence
- `string-similarity` (-> %Undefined% %Undefined% Number) -- Normalize the shared exact edit distance as 1 - distance/max(lengths), in [0,1]
- `string-slice` (-> %Undefined% Number Number String) -- Return the half-open codepoint interval [From,To)
- `string-split-exact` (-> %Undefined% %Undefined% Expression) -- Split at nonoverlapping occurrences of the complete, nonempty Separator
- `string-split` (-> %Undefined% %Undefined% Expression) -- Split on each character in Separators, retaining empty fields
- `string-starts-with` (-> %Undefined% %Undefined% Bool) -- Test whether the first literal occurrence is at index zero
- `string-template` (-> %Undefined% Expression String) -- Replace {Name} or {Name,Default} using unique (Name Value) pairs
- `string-trim` (-> %Undefined% String) -- Remove ASCII space, tab, LF and CR from both ends
- `string-unlines` (-> Expression String) -- Append LF to every coerced line and concatenate
- `string-upper` (-> %Undefined% String) -- Apply the host Unicode uppercase mapping and return a String
- `string-wrap` (-> %Undefined% Number %Undefined% String) -- Greedily wrap words to a positive codepoint width

#### lib_system

- `change-directory!` (-> String Bool) -- Change the process's current directory
- `env-all` (-> Expression) -- The whole environment as a relation of (Name Value) pairs, names and values both Strings, in the order the host reports
- `env-get` (-> String String) -- One environment variable's value, with NO answer when it is not set: unset and empty are different states, and a program that defaults one has to be able to tell
- `env-set!` (-> String String Bool) -- Set the variable for this PROCESS: every space sees it and so does every child process started afterwards
- `env-unset!` (-> String Bool) -- Remove the variable from this process
- `platform-info` (-> Symbol %Undefined%) -- What the host says about itself: the architecture, the operating-system family, the SWI-Prolog version as a String and as its three numbers, this process's identifier, how many cores the host reports, whether integers are bounded, and the executable and home directory of the running system
- `platform-keys` (-> Expression) -- Every key platform-info answers for, as data: the same list its refusal names
- `working-directory` (-> String) -- The process's current directory, as an absolute path with no trailing separator

#### lib_testing

- `lib_testing` -- Compose finite generators with core assertions

#### lib_thread

- `capture` (-> Atom Atom) -- Hold an expression with its current evaluation space as an evalc value
- `drop-space` (-> SpaceType Bool) -- Release a space through its scope owner, including owned children and deferred cleanup
- `scope-defer` (-> %Undefined% Atom Bool) -- Register held cleanup in the current scope; returning its value transfers cleanup and current dependencies to the enclosing scope; outside a scope no cleanup is registered
- `scope_defer` (-> %Undefined% Atom Bool) -- Native spelling of scope-defer
- `scope` (-> Atom %Undefined%) -- Join children and release resources created by the body; child failure cancels siblings; returned spaces transfer to the enclosing scope
- `space_drop` (-> SpaceType Bool) -- Native spelling of drop-space

#### lib_torch

- `torch-add` (-[det,writesState]-> %Undefined% %Undefined% %Undefined%) -- Adds :attr:`other`, scaled by :attr:`alpha`, to :attr:`input`
- `torch-arange` (-[det,writesState]-> %Undefined% %Undefined%) -- Returns a 1-D tensor of size :math:`\\left\\lceil \\frac{\\text{end} - \\text{start}}{\\text{step}} \\right\\rceil` with values from the interval ``[start, end)`` taken with common difference :attr:`step` beginning from `start`
- `torch-backward` (-[det,oracleIO]-> %Undefined% %Undefined%) -- Computes the gradient of current tensor wrt graph leaves
- `torch-div` (-[det,writesState]-> %Undefined% %Undefined% %Undefined%) -- Divides each element of the input ``input`` by the corresponding element of :attr:`other`
- `torch-grad` (-[det,oracleIO]-> %Undefined% %Undefined%) -- This attribute is ``None`` by default and becomes a Tensor the first time a call to :func:`backward` computes gradients for ``self``
- `torch-item` (-[det,readOnlyLookup]-> %Undefined% %Undefined%) -- Returns the value of this tensor as a standard Python number
- `torch-matmul` (-[det,writesState]-> %Undefined% %Undefined% %Undefined%) -- Matrix product of two tensors
- `torch-mean` (-[det,writesState]-> %Undefined% %Undefined%)
- `torch-mul` (-[det,writesState]-> %Undefined% %Undefined% %Undefined%) -- Multiplies :attr:`input` by :attr:`other`
- `torch-ones` (-[det,writesState]-> %Undefined%) -- Returns a tensor filled with the scalar value `1`, with the shape defined by the variable argument :attr:`size`
- `torch-randn` (-[det,oracleIO]-> %Undefined%) -- Returns a tensor filled with random numbers from a normal distribution with mean `0` and variance `1` (also called the standard normal distribution)
- `torch-requires-grad` (-[det,writesState]-> %Undefined% %Undefined%) -- Change if autograd should record operations on this tensor: sets this tensor's :attr:`requires_grad` attribute in-place
- `torch-shape` (-[det,readOnlyLookup]-> %Undefined% %Undefined%) -- Returns the size of the :attr:`self` tensor
- `torch-sigmoid` (-[det,writesState]-> %Undefined% %Undefined%) -- Alias for :func:`torch.special.expit`
- `torch-sub` (-[det,writesState]-> %Undefined% %Undefined% %Undefined%) -- Subtracts :attr:`other`, scaled by :attr:`alpha`, from :attr:`input`
- `torch-sum` (-[det,writesState]-> %Undefined% %Undefined%) -- Returns the sum of all elements in the :attr:`input` tensor
- `torch-tensor` (-[det,writesState]-> %Undefined% %Undefined%) -- Constructs a tensor with no autograd history (also known as a \"leaf tensor\", see :doc:`/notes/autograd`) by copying :attr:`data`
- `torch-tolist` (-[det,readOnlyLookup]-> %Undefined% %Undefined%) -- Returns the tensor as a (nested) list
- `torch-zeros` (-[det,writesState]-> %Undefined%) -- Returns a tensor filled with the scalar value `0`, with the shape defined by the variable argument :attr:`size`

#### lib_unicode

- `unicode-casefold` (-> String String) -- The text case-folded for caseless comparison, which is NOT a lowercasing: it maps to whatever compares equal regardless of case, so German sharp s becomes two letters and the answer may be longer than the input
- `unicode-codepoint-valid` (-> Number Bool) -- Whether the database ASSIGNS this number a character: in range, not a surrogate half, and not unassigned or a noncharacter
- `unicode-graphemes` (-> String Expression) -- The user-perceived characters of UAX#29, one string each: a base character with its combining marks is ONE answer, where string-chars answers a code point each
- `unicode-is` (-> %Undefined% Symbol Bool) -- Whether the character belongs to a class the Unicode database defines: letter, upper, lower, title, digit, number, mark, punctuation, symbol, separator, white-space, control, ascii or assigned
- `unicode-map` (-> String Expression String) -- The text transformed by a collection of flags in ONE pass, which is the general operation the normalizations and the fold are compositions of: stable, compat, compose, decompose, ignore, rejectna, nlf2ls, nlf2ps, nlf2lf, stripcc, casefold, charbound, lump and stripmark
- `unicode-normalize` (-> Symbol String String) -- The text in one of the five standard forms: nfc and nfd are the canonical composition and decomposition of UAX#15, nfkc and nfkd their compatibility counterparts, and nfkc-casefold the caseless identifier form of UAX#31
- `unicode-property` (-> %Undefined% Symbol %Undefined%) -- What the database says about one character: its general category, combining class, bidi class and mirroring, compatibility decomposition type, default ignorability, grapheme boundary class, display width, East-Asian ambiguity, its three single-character case mappings and its Indic conjunct break
- `unicode-version` (-> String) -- The version of the Unicode database every other answer here comes from

#### lib_uri

- `uri-build` (-> Expression String) -- Compose encoded String pairs
- `uri-contexts` (-> Expression) -- Encoding contexts: path keeps slash; segment encodes it; query-value protects pair separators and plus; fragment retains its own reserved punctuation
- `uri-decode` (-> String String) -- Decode percent octets exactly once as strict UTF8
- `uri-encode` (-> Symbol String String) -- Encode Unicode text as UTF8 percent octets in a context from uri-contexts
- `uri-normalize` (-> String String) -- Lowercase the scheme and host, decode unreserved percent bytes and uppercase other escape digits
- `uri-parts` (-> String Expression) -- Encoded String pairs in scheme/authority/path/query/fragment order
- `uri-query-build` (-> Symbol Expression String) -- Encode String pairs in order using the native query-value safe characters
- `uri-query-parse` (-> Symbol String Expression) -- Decode an ampersand-separated query into String pairs, preserving order, duplicates and empty values
- `uri-resolve` (-> String String String) -- Resolve by RFC3986 section5.2

#### lib_uuid

- `uuid-bytes` (-> String Expression) -- The 16 bytes of a UUID in network order
- `uuid-is` (-> %Undefined% Bool) -- Whether Text is a UUID String with exactly 8-4-4-4-12 hexadecimal digits, accepting either case
- `uuid-name` (-> Number %Undefined% String String) -- Derive a version 3 (MD5) or version 5 (SHA-1) UUID from a namespace and the complete UTF-8 name
- `uuid-namespaces` (-> Expression) -- The predefined namespace Symbols accepted by uuid-name
- `uuid-nil` (-> String) -- The all-zero identifier, distinct from a missing answer
- `uuid-of-bytes` (-> Expression String) -- Exactly 16 byte integers as a canonical lower-case UUID String
- `uuid-random!` (-> String) -- Generate a version 4 random identifier
- `uuid-time!` (-> String) -- Generate a version 1 identifier using the host's OSSP provider
- `uuid-timestamp` (-> String Number) -- Seconds since the Unix epoch for an RFC version 1 UUID
- `uuid-variant` (-> String Symbol) -- The layout selected by the variant bits: ncs, rfc, microsoft or future
- `uuid-version` (-> String Number) -- The four version bits as a Number from 0 to 15

#### lib_vector

- `cosine-of-normalized` (-> Expression Expression Number) -- The dot specialization used for normalized vectors, as an ordinary equation
- `cosine` (-> %Undefined% %Undefined% Number) -- Return the cosine similarity of equal-dimensional numeric expressions
- `dot` (-> %Undefined% %Undefined% Number) -- Return the dot product as a float
- `norm` (-> %Undefined% Number) -- Return the correctly rounded Euclidean length of a numeric expression
- `random-normal-vector` (-> Number Expression) -- Fold Count fresh positive uniform draws onto Accumulator with cons-atom, then normalize
- `vector-add` (-> %Undefined% %Undefined% Expression) -- Add equal-dimensional numeric expressions component by component
- `vector-distance` (-> %Undefined% %Undefined% Number) -- Return the correctly rounded Euclidean distance of equal-dimensional numeric expressions
- `vector-divide` (-> %Undefined% %Undefined% Expression) -- Divide corresponding components
- `vector-fill` (-> Number Number Expression) -- Collect Count copies of Value from a MeTTa range
- `vector-multiply` (-> %Undefined% %Undefined% Expression) -- Multiply corresponding components, with vector-add's exact, floating and dimension rules
- `vector-normalize` (-> %Undefined% Expression) -- Return floating coordinates in the same direction with unit length, rounding each exact finite ratio once
- `vector-scale` (-> %Undefined% %Undefined% Expression) -- Multiply every component by Factor, with vector-multiply's number rules
- `vector-subtract` (-> %Undefined% %Undefined% Expression) -- Subtract Right from Left component by component, with vector-add's exact, floating and dimension rules

#### lib_yaml

- `yaml-decode` (-> String %Undefined%) -- One YAML document as a MeTTa value: a mapping becomes a space of (Key Value) atoms, a sequence an expression, a string a String, a number a Number, the booleans True and False, and null Null
- `yaml-encode` (-> %Undefined% String) -- One YAML document as text: a space becomes a mapping of its (Key Value) atoms, an expression a sequence, a String a string, a Number a number, True and False the booleans and Null the null scalar
- `yaml-read!` (-> %Undefined% %Undefined%) -- One YAML document read from a file, as yaml-decode answers it
- `yaml-write!` (-> %Undefined% %Undefined% Bool) -- One YAML document written to a file, published atomically through replace-file!: the destination is replaced only after the whole document is written, so a reader never sees half of one
<!-- end generated library glossary -->

The standard-library basis includes `lib_builtin_types` for existing callable
types and `lib_string` for text. The 36 concerns in the library census have
35 principal library owners: finite distributions and descriptive statistics
share `lib_statistics`. `lib_testing` imports generators for core `forall`
and `test`; it adds no assertion protocol. `lib_reflect` and `lib_strategy`
compose code-as-data traversal and replacement over ordinary expressions.
Derived operations are stored MeTTa equations that callers can match and
reconstruct; native halves own their host services, maintained algorithms
and resource boundaries. `EXTENDING.md` describes how to author both halves.

`engine/packages.pl` is the engine's package interpreter. Package equations are an
argument record: `requires` runs first, then a required library's `package-load`
equation may interpret the canonical path, home and rows. The default validates
backing coverage and contracts, registers heads at home, and validates boot
rows before local effects. `setup!` prepares dependencies explicitly and writes
performed.metta and lock.metta under an OS directory lock. `package-prolog`
performs a `(= (package backing) (prolog File (heads)))` row: it loads the file
and registers exactly the heads the row lists, leaving the artifact's other
exports alone. Imports use local artifacts and pins. `get-property` with two inputs reflects package keys,
available backings and `perform` claims. Acquired answers retire in reverse on
withdrawal, replacement, failure or space release. The executable policy fixture
is `tests/data/package_laws/policy.metta`; the implementation and verification are in
`docs/record/package-laws-6-13.md`.

Library contracts: `lib_builtin_types` the declared type surface of the shipped
builtins; `lib_cli` typed option declarations, literal String argument vectors,
explicit repeat policies and (Pairs Operands) results. Short and long names use
separate namespaces; defaults retain literal values and absent options contribute
no pair. Six built-in converters and (parse Type Function) support ordinary held
functions, with one-answer collection and live argument-type validation. Every
occurrence converts before repeat selection; syntax validates before custom effects.
The terminator preserves later operands, empty tokens remain empty and malformed
options raise with their cause and repair. Help uses the same declarations;
raw argv retains runner arguments and spelling. All parse state travels in arguments;
`lib_combinatorics` derives ranges, prefixes, choices, permutations, subsets,
Cartesian products and exact counts from MeTTa equations, segments and folds.
Choices preserve literal occurrences and answer order; chooseK streams and
chooseKl collects. Exact additive probability belongs to Statistics;
`lib_compression` complete gzip/zlib byte
members and streaming file replacements, with levels 0..9. Archive metadata keeps
order, duplicate names and native properties; ordinal reads distinguish entries.
Extraction publishes regular files and directories only after the whole archive
passes, refusing escaping or nonportable names, links, special files and file
collisions. Existing nonempty destinations survive refusal. Every gzip layer is
validated even inside other native filters; those inputs use owned intermediate
files so decoders close before archive readers open. File's staged publisher owns
publication and cleanup. Native name conversion uses a thread-local UTF8 locale
and restores it after archive close. ZIP names default to CP437, retaining UTF8
flags and Unicode extra fields; unconvertible pathnames raise; `lib_conformance` proves
a foreign space provider before its users find out; `lib_constraints` CLP(Q)
over rationals and CLP(B) over booleans; `lib_csv` streams CSV rows through the foreign space seam; `lib_crypto` hashes and secure
randomness, refusing by name where OpenSSL is absent; `lib_database` independent
ordered multisets of native syntax in store directories containing a
journal and a permanent lock file. Opaque engines own their schemas and streams;
requests serialize and competing owners refuse. database-atoms returns passive
expression snapshots with duplicates and fresh variables shared within each
occurrence. MeTTa segment patterns derive selection and joins; stored equations
can be inspected and explicitly reconstructed as functions. Removal deletes one
alpha-identical value, keeping variable sharing and numeric kinds distinct.
Old ground journals remain valid; variable encodings must be canonical.
Sync uses journal-sync buffering modes and never claims
fsync or transactions. Writes survive caller backtracking; write/sync failures
end the attachment. Opening rejects malformed UTF8 and journal records before
replay. Close and with-database finish cleanup and retain combined errors; native
atom collection releases abandoned engines asynchronously. Keep each open store's
directory and contents managed exclusively through its API; `lib_datastructures` an
amortised O(1) functional queue, a finger tree, and map/priority-queue equations
over ordered pair expressions. `(SortedMap Rows)` has distinct identity keys;
`(PriorityQueue Rows)` preserves every occurrence and stable ties. Operations
validate the representation, preserve literal terms and variables, and return
new values. Missing lookups, minima and queue removals have no answer; an absent
map removal returns the same value. `pq-merge` accepts zero or any number of
queues, with left-to-right order among ties. Pair sorting may take quadratic
work; recipes can be matched, reconstructed and specialized; `lib_datetime` clocks,
parsing, explicit-zone formatting, date records, calendar fields and addition;
`lib_derived` the derived forms the engine keeps FUSED
into its compiler, written out as equations; `lib_dict` a dictionary that IS a
space, with defaulted lookup, update, merge and pop; `lib_doc` keeps the old doc import path working after
its vocabulary moved; `lib_encoding` shares strict byte/text boundaries and
UTF8/base64 host codecs. Hex uses one ASCII alphabet, arithmetic and segments in
MeTTa. Base64 takes its alphabet as an argument; its host URL decoder also reads
classic digits. Cancellation, resource errors and unrelated decoder exceptions
propagate unchanged. Malformed input raises a boundary error or assertion naming
what was wrong; `lib_file` text and byte files whole or through handles, publication by rename, directory creation, tree copy and removal, renaming, a link-aware walk and glob, lexical and resolved paths, entry kinds, symbolic links, scoped handles and temporary directories, queryable metadata and process streams;
`lib_functional` derives collection operations in MeTTa: zip and unzip, drop,
chunk and window, one-level and every-level flatten, partition, group and sort
by a key function, scan, unfold, pipe and apply-to, and the three held control
forms while, repeat and unless. Segments select heads, tails and prefixes;
unfold supplies zip, chunk and window. Callback operators share apply-to, which
reduces a call built from finished values. Held/eager functions, lambdas and
partial applications preserve literal data and variable identity. Callback
alternatives remain alternative results, partition asks for a True answer,
and grouping binds a key before comparing it so Error remains a literal key.
Growing accumulators and slices can take quadratic work. Neither flatten takes the bare name, which is
the host's own every-level one; `lib/lib_gitimport/` is no library, having no
manifest to import, but the Prolog backing of the engine's `git-import!`, which
acquires a module from a repository into a local checkout;
`lib_graph` derives directed graphs as canonical (Vertex Neighbours) expressions
from Sets, Pairs and Functional. Vertices compare by identity, including shared
variables and quoted runnable terms. Construction, projections, edits, transpose
and variadic union use ordinary collection operations. A fold defines closure;
reachability and cycle detection share that recipe. Topological ordering unfolds
canonical zero-indegree layers and refuses a cycle with an actual cycle vertex.
Matching can reconstruct or specialize the path equation. No native graph
algorithm remains; a single-origin query computes all-pairs closure;
`lib_he` the exact upstream compatibility equations, which shadow the
importing space's prelude locally. Its assertions compare individual answers;
native assertions compare answer bags. Its `add-reduct` equation returns the
Boolean from `add-atom`; native `add-reduct` returns the reduced atom. The
shared `if-equal`, `if-equal2`, and `match-types` use identity, `match-type-or`
takes the upstream arguments, and `return-on-error` returns the bare error;
`lib_http` method-based byte requests, parsed String-key header fields and status
codes, with response streams shared through File handles. Non-2xx statuses remain
data; redirects require an option. Independent local servers carry their MeTTa
handler and execution module, route by ordinary equations and supply one response.
Scopes release streams and servers on exhaustion, cut and exception. Server IDs
protect reused ports; start/stop refuse transactions and a worker cannot stop its
own server. HTTP owns framing and refuses malformed headers, options and bodies.
Plain HTTP and optional HTTPS client transport have separate capabilities;
`lib_import` importing that fails LOUDLY where a missing file once answered
nothing; matchable `(import Path)` rows through `(imports &space)`,
and `unimport!` for exact source-owned atom withdrawal; `lib_json` JSON objects
as spaces, native formatting, structural paths, UTF-8 document files and
streaming JSON Lines, with atomic file publication and cycle refusal; `lib_logging`
structured topic/level messages through host hooks, exact process-wide topic
settings and explicit capture handlers carried by each message. Handlers receive
an evaluated event Expression, preserving the held payload; their first Bool
consumes or delegates the message, and failed verdicts raise. Earlier host hooks
retain precedence, and log-format uses the same diagnostic translation;
`lib_markup` XML and HTML as expressions, an element being
(element Name Attributes Children) with tagged (attr Name Value) rows, a selector
language over it converted to the host's xpath, strict parses that refuse every
repair the host's own reader would make quietly, and an external entity refused
rather than fetched; declares the `markup` capability; `lib_math` derives gcd/lcm
folds, factor-pair choices and scalar floating conversion as MeTTa equations.
Unary math-rational converts a finite Number exactly; its binary form constructs
a ratio. Rationalization explicitly permits approximation. Integer roots,
modular powers and floating-function names use the native numeric provider.
math-sqrt takes the root before final rounding and retains signed zero.
Vector supplies shared conversion and root rounding. Factorial and binomial
compose from Combinatorics; exact construction refuses host approximation;
`lib_measure`
weighted superpositions: normalize, softmax, rank, top-k, sample; `lib_memo` the
resident automatic and explicit memoisation controls; `lib_mm2` notation over
&mork, loaded on demand: `＋` and `－` add and remove one atom, `＋*`
bulk-adds a whole expression in one crossing, and `~>` runs one MM2 transform; `lib_nars` NARS truth functions, inference rules and
bounded derivation; `lib_observe` filtered traces, source coverage and attributed error frames as queryable atoms; `lib_parsing` prepares held grammars as written MeTTa lambdas.
One metadata relation supplies fourteen primitives and twelve combinators and
accepts new parsing functions. Whole and prefix text doors retain every answer;
callable parsers consume finite token expressions and return (Contribution Rest),
where () skips and (Value) retains any literal payload. Code, Error, Empty and
shared variables survive composition and Python round trips. Cat and alt accept
zero or any number of parts. Repetition preserves longest-first prefixes and
refuses a step that consumes no input. Grammar checks never run callbacks or ref
targets. String conversions supply the host boundary; ASCII classes and grammar
composition are MeTTa equations; `lib_patrick` compose, for, iterate; `lib_pln` PLN truth
formulas, consistency and ranking, over `/safe`, the division that answers
nothing rather than raising when the denominator is zero; `lib_pln2` selected Beta and moment formulas
with explicit evidence scale and support-checked independence; `lib_process` a program run with an
argument VECTOR and never a command line, its exit code answered as a status beside
everything it wrote, and a started process watched, signalled and waited for through
its identifier. There is no shell: running one is the caller's explicit choice in the
program's own name, `(process-run! "sh" ("-c" "..."))`; `lib_random` constructs
inspectable sample programs for ten numeric families and occurrence choice.
Construction validates without drawing; bind the program before eval or repeat.
Core demand and with-seed control sampling and generator restoration. Programs
can be stored, matched, rewritten or combined with alternative answers. Sampling
distinct positions unfolds immutable populations through segments; shuffling
samples every position. Repeated independent choices derive from choice and
repeat, while map-atom preserves caller variable sharing. Held populations keep
runnable terms literal. Gamma factors and log corrections delay underflow until
the final scale or ratio. Numeric providers declare their effects beside their
implementations; recording requires the same visible specialization equations
and conservatively refuses possible assertion output;
`lib_redis` shared spaces over Redis;
`lib_reflect` the engine's surface and literal code as data. atom-variables
collects written variables by first-appearance identity, including binder syntax.
atom-replace composes Strategy's topmost traversal with exact Pairs lookup:
root matches win, replacements are final for the pass, duplicate rows and
independent occurrences preserve their full answer bags. Runnable, Empty and Error
expressions stay literal. This is structural replacement, not lexical capture
avoidance. atom-subst remains the single-written-variable template operation;
`lib_regex` PCRE2
over strings; `lib_pairs` a collection of (Key Value) pairs read as a relation: the two
projections, the converse, the two stable orderings, the grouping into a multimap
and back, and a lookup that answers once per value a key has. These equations
reuse Functional's projections, grouping and sorting. Duplicates and caller
variable identity survive; lookup selects a row by segments and compares its key
by identity without binding a different key;
`lib_sets` sets as ordered expressions: construction, membership by term rather
than unification, insertion and removal, union, intersection, differences, subset
and disjointness. Union accepts zero or more canonical sets; intersection accepts
one or more. Both use variadic arrows and folds, subsuming the former all-forms.
Pass runtime argument collections through apply-to. Core unique-atom, sort-atom,
intersection-atom and subtraction-atom supply the operations; invalid canonical
inputs raise through core assertions;
`lib_roman` a list and fold basis, head, init, fold-flat,
foldr-flat; the three general set operations `/?\`, `\?` and `\?/`, which take
the comparison as an argument and are what the nine fixed spellings are sugar
over; `fst`, `snd` and the pair-shaped `cns`; and `traceid` and `tracem`, which
print and answer their subject unchanged; `lib_socket` IPv4/IPv6 TCP connections,
listeners and complete UDP packets through File handles. Endpoint values include
the actual family, numeric address and port. File byte operations carry TCP;
UDP retains packet boundaries and empty payloads. Readiness preserves input
order and duplicates, and shutdown selects a connection's direction. Scopes
keep acquisition cancellable, close on every exit and retain original outcomes
when cleanup also fails. Openers refuse transactions; declares the `socket`
capability. Native adapters preserve complete IPv6 addresses and release failed
stream publication; `lib_soft` soft structural unification over written symbols, including
function names, with grounded values compared crisply; match quality as a measure;
`lib_spaces` whole-space work: find, match-count, copying, moving, draining, snapshotting, subtracting and clearing, each answering once per atom it touched;
`lib_statistics` sample summaries and finite probability laws expressed as
MeTTa equations. Sample totals, moments, three means, quantiles, ranks and
regression retain exact intermediates; floating observations round the final
result once. Variance composes covariance, deviation takes its root before
rounding, and ranking both inputs composes Spearman correlation. Modes preserve
term identity and answer every tie. Match can reconstruct or specialize a
recipe as a function. Finite laws use Measure's (Weight Value) rows for mapping,
independent products, conditioning, thresholds, inverse CDFs and moments.
ws-map-independent is variadic and preserves alternative function rewrites as
separate laws. Sample quantiles interpolate; law quantiles retain support values.
First central moments are exactly zero after finite numeric validation.
Insufficient samples, nonfinite data and invalid count domains refuse.
weighted-subset-mass-independent and weighted-subset-posterior-independent
hold literal (candidate ID LOSS (ratio N D)) rows. Ground acyclic IDs compare
by identity; losses and targets share a nonnegative integer scale, and integer
priors satisfy0<=N<=D withD>0. Sparse ordered integer coefficient rows merge
equal sums and truncate at the target. A rolling fold computes exact mass;
prefix/suffix unfolds and two-pointer joins recover all marginals in candidate
order. Integer ratios remain exact without constructing host rationals. Zero
mass is defined; zero-mass conditioning raises an assertion refusal that names
the mass operation. The former Distribution import and Combinatorics probability
operations are consolidated into this library;
`lib_strategy` traversal through ordinary MeTTa equations, callable values and
held plans. Bound terms remain literal for named functions, lambdas and partial
applications. seq and choice accept zero or any number of strategies; choice
returns the first nonempty complete answer bag. Failure is no answer, produced
by (empty); literal Empty remains data. alltd stops at each successful
root replacement; topdown, bottomup and innermost retain their distinct orders.
strategy-repeat names direct rewriting until failure; held (repeat Rule) plans
coexist with Functional's numeric repeat. Type selection reads current-space
declarations and filters with match-types;
`lib_string` codepoint text with String/Symbol/Number coercion and embedded NUL
preservation. Nine MeTTa recipes derive literal membership, prefixes/suffixes,
character joining, repetition, padding and normalized edit similarity. One
function parameter assigns padding to the left; empty construction still
validates complete inputs, and retained assertions keep replay conservative.
Shared native boundaries own conversion, exact search, licensed layout/template
grammars, RapidFuzz edit distance and ISub; no second text representation;
`lib_system` the environment as a relation, a read with no answer for an unset
variable, process-wide writes, the working directory and ten platform keys, with
no shell anywhere; `lib_tabling` expert-only tabling
control; `lib_testing` imports finite generators for properties expressed with
core assertions. Compose range or cartesian-power with forall and test;
assertEqualToResult checks complete answer bags and duplicate occurrences.
foldall counts with a value/count callback, including zero for an empty domain.
once selects the first answer of a filtered generator and retains its binding.
Quote runnable values as data, select them with index-atom and request fresh
variables explicitly with copy_term. Ordinary traversal preserves calling-module
resolution and closes generators on success, failure and exceptions;
`lib_thread` parallel data operations, M:N futures and timers;
`lib_torch` PyTorch from plain MeTTa through py-call, GENERATED from torch's
own signatures by `extensions/python/tools/facegen.py` and gated by the
`face-sync` lane; `lib_unicode` the Unicode database and the standard text transformations, each
head taking its variant as an argument: normalization in the five UAX#15 and
UAX#31 forms, case folding for caseless comparison, the general mapper with
utf8proc's flags, thirteen per-character properties, fourteen locale-free
character classes, grapheme clusters and code-point validity, with the database
version as a head; declares the `unicode` capability; `lib_uri` generic URI
components as encoded String pairs, preserving missing versus empty delimiters,
userinfo case and reserved octets. RFC3986 resolution handles relative paths,
authority-only bases and opaque URNs. Native context-sensitive percent encoding
accepts Unicode; decoding requires valid UTF8. Query relations preserve repeated
keys and blank values, with explicit uri/form plus convention. URI spelling is
ASCII, and authorities remain encoded data rather than resolved addresses;
`lib_uuid` explicit random
and time UUIDs, UTF-8 namespace/name identifiers for versions 3 and 5, validation,
version/variant fields, version-1 timestamps, nil and lossless 16-byte conversion;
custom UUID namespaces and embedded NUL names are preserved. Namespaces, names,
nil, byte conversions and field formulas are MeTTa equations that can be
reconstructed as functions. One field layout drives validation and formatting;
generation, strict validation and version-1 timestamps remain native. Shape
assertions make recording replay conservative. Version 1 may expose the host's
MAC address; `lib_vector` exact finite numeric kernels with
one final rounding and IEEE signs/classes; MeTTa equations derive fill from
range, random construction from foldall/cons-atom and the core seeded draws,
and cosine-of-normalized from dot. Complete validation precedes entropy;
count assertions and supplying numeric operations identify their own refusals;
retained construction assertions make recording replay conservative, while
the dot specialization keeps its structural numeric effect;
`lib_yaml` YAML documents as values in lib_json's own shape, a mapping becoming a
space and a sequence an expression, with the file doors derived from lib_file's
and four refusals the host only fails at: a multi-document stream, an unsupported
tag, a duplicate key and malformed text; declares the `yaml` capability;
`lib_zar` Prolog interop, consult and
use_module wrappers; `minimal_metta_lib` minimal MeTTa's instruction set
(`function`, `collapse-bind`, `superpose-bind` and its own `unify-mod`), with
switch, reduce and a Turing machine written over them under an `mm-` prefix,
because the library loads into `&self` where those names would land on a
program's own. Scored answers and fuzzy or regex matching
are `lib_measure` and `lib_regex` riding the general seam, not Python modules:
there is no `metta.measure` and no `metta.matching`.

## Contracts that cost real debugging

The Python binding lives under `extensions/python/metta/_binding/`.
Evaluation axes belong to `doors.EvaluationOptions`; each door's
`Binding.evaluation` selects its fixed record. `metta_py_evaluate/4` is the
shared entry. `interface.py` and `provides/<kind>.pl` own the service and
supplied-clause declarations; `bindinggen.py` generates their projections.
Run `sh tools/check.sh binding` after changing a crossing. Every wire-tag row is
held by codec and frame tests, and `door-order` fails on unresolved boundaries.
Tagged query guards spend the same cumulative budget as their derivation.

`match` evaluates its space and its body, never its pattern: patterns are
structural, so compute first and match after with `let`.
MeTTa equations ACCUMULATE. Redefining a function ADDS an alternative rather
than replacing the old one, so a second `(= (f x) ...)` gives `f` two answers.
Equations are alternatives, not sequential clauses; a literal-headed default
needs a guard or it fires too.
A typed call rejects a bad argument by answering empty, not by raising: use `cast`.
A failing `assertEqual` or `assertEqualToResult` names the call as WRITTEN and
prints the two answer bags under it, `missing:` then `excess:`; both empty
means the answers agree and only their order differs, which `assertEqual`
fails on because it compares the collapsed tuples by term equality. A failing
`assertIncludes` prints `missing:` ALONE and no `excess:` line, because an
answer in excess of its expectation is legal under that relation and naming
one would blame a bag that is not a reason for the failure; the absent side
reaches `AssertionFailure.excess` as `None`, which a harness tells from the
empty tuple an emptied comparison gives. `assert` prints no bag line at all,
its operand being a verdict. A user's own assertion over answer bags gets the
same report from `assert-answers` for a two-sided relation and
`assert-includes-answers` for a one-sided one; each takes the verdict, the
call to report, the answers produced and the answers expected, computes its
differences only on the failing path, and never decides the verdict.
An unreduced call is a non-empty answer, so test truth with `any(a == True)`,
never "the result was non-empty".
Python `None` from an operation answers nothing.
`(empty)` yields no answer at all, which is how a branch prunes itself.
`collapse` is a special form: a helper "around" `collapse` collapses an
already-chosen answer (an unmasked argument evaluates eagerly) or answers the
held term itself (a masked argument is not re-run), so inline `collapse`.
`forall` stops its generator when the check fails (it compiles to Prolog's
`\+ (Gen, \+ Test)`), so a bounded take over an infinite producer is writable
and terminates where `collapse` cannot run at all.
`(top k ...)` pushes its bound into a foreign provider only when three
declarations hold together: `handles(pattern, "Exact")`, an ordered algebra
through `annotations`, and `emits("best-first")`. Drop one and the bound stays
here. `emits("best-first")` is therefore a CORRECTNESS promise, not a
formatting preference: a provider that declares it and yields out of order
makes `(top k ...)` answer the wrong rows, not a permutation of the right ones.
A Python `limit=k` or `[:k]` slice of an ordered-carrier match asks the same
promise of the same provider, so `emits("best-first")` decides all three. A slice that does not
meet every condition under `under=` above drains the provider and orders here,
which is correct whatever the provider promises and costs the whole store.
`py-iter` is lazy and yields one answer at a time; a Python generator is not
drained. Each enumeration gets its OWN cursor over a shared cache, so reading
the same iterator twice, or nesting two reads of it, answers the cartesian
product rather than exhausting it once. `py-iter-once` is the other rule, kept
by name: Python's own consumptive iteration, which is what a compiled `for`
statement wants. An iterator that RAISES mid-enumeration is reported at the
pull that raised, naming that `py-iter` call and the iterator's own repr, the
way a deterministic Python call's failure is; answers already yielded before it
are never delivered as a complete set. A `py-iter` source remembers its
failure, so a second enumeration of it reports the same failure at the same
index rather than reading the prefix as complete; a `py-iter-once` source is
spent either way. The guard is one inference an item and no extra crossing.
`py-atom` takes a metatype argument, `Grounded` for the live reference and
`Expression` for a snapshot.
Strings carry hyperon's five escapes (quote, backslash, `\n`, `\t`, `\r`).
Symbols containing whitespace, parentheses or quotes are refused at save and
digest rather than written unreadably.

## Measuring

Native writes allocate one occurrence generation through SWI's atomic `flag/3`.
That adds five inferences per accepted atom while preserving linear bulk-write
cost. Fast-image validation retains its normalized tokens, and a nonempty load
uses one rollback marker and three receipt requests for the whole batch. The
10,000-atom memory-scale load falls from 891612 to 591623 inferences. A drop of
2,000 equations falls from 1036804 to 914781: unnested removals find the nearest
transaction frame, and scopes with no reservation send no receipt cleanup.
Nested transactions retain the outer receipt owner. These measurements and the
rejected attachment-only batch are in
docs/journal/2026-09-07-every-fact-has-a-token.md.

Vocabulary membership uses an index built once from the declared and registered
members. A warm ground membership read checks at most its base and member
clause references; a cold read builds all positive entries in one pass. The
first-read ladder at 32 through 1024 words changed from 11182 through 8481870
inferences to 910 through 27694. Erasure inside a transaction is checked in
that transaction's visible clauses, and rollback restores the catalog and its
cache together. Rejected words are not cached. Relational reads retain the
declared member order.

Initial vocabulary type atoms load as compiled removable facts only when the
catalog still has its shipped metadata, no type schema or watcher, no existing
type atom and no &metta execution module. Other states use ordinary publication.
The warmed same-path control saves 8847 inferences and 3323787 instructions
while preserving the ordered 257 atoms. Shipped typing-rule patterns likewise
compile once; user rules, constrained outcomes and callback errors retain their
existing semantics. The measurements and negative controls are recorded in
docs/journal/2026-09-08-what-the-waivers-were-paying-for.md.

Fresh Python wire decodes keep one named variable in the existing ordered
binding pair and build the backtrackable hash index at the second distinct
name. Ground and anonymous-only terms need no index. Repeated names preserve
identity even when outputs are prebound; failed decodes roll back the index
and bindings. Alpha-unique measures 2853800984 instructions against cut
3701142714, with 4161492 explicit Prolog inferences. The native list scan it
replaces hid its quadratic element visits from that counter. The Node
benchmark sampler collects Prolog setup garbage before its V8 collections;
workload collections remain inside the measured window.

PERFORMANCE.md separates the frozen corpus snapshot from the current 24-waiver
audit. Pinned upstream skips the original C examples' file preflight, fails six
other original programs and has no stable PyTorch cost. The common C programs
execute on both engines; direct calls cost about 414 instructions for c-bump
and 583 for a handle call on each. Those original skip costs are not C-call
comparisons. No cross-engine allowance was enlarged.

Wall clock under ~100ms is bimodal on a loaded box and has produced false
results here twice. `m.stats().inferences` is deterministic (five runs of one
workload gave 1,000,601 every time, 0.0000% spread, while wall clock swung
6.86%, measured 2026-08-18), so gate on inferences and let wall clock advise. For pure-Python paths
where the engine does nothing, use `perf stat -e instructions:u`. Instruction
counts move with code LAYOUT, so perturb with inert clauses before believing a
regression. Check `/proc/loadavg` before trusting any timing.

A declared cost class is a claim the gate can fail. `sh tools/check.sh cost-rows`
runs `benchmarks/costs.py` over every `(cost ...)` row the engine holds: one
fresh process per row, one fresh space per size, inferences per size fitted
against the declared class in BOTH directions, so a row that overstates its cost
fails as one that understates it does. Its ledger is
`benchmarks/cost-baseline.json`, which is where the docstring's measurement date
comes from. Five planted controls ride along permanently, one per gate
direction, and the lane fails if any of them stops landing where it is planted:
a quadratic body declared linear must fail the class gate, the same body
declared quadratic must pass it, a linear body declared quadratic must fail it
the other way, a naive Fibonacci with the memo refused must pass the exponential
test, and a body whose answer counts are pinned from another row must fail the
work gate while passing the class one. About 23 to 31 seconds (measured
2026-09-07), and load-immune,
because the counter is inferences. `--paired` adds the retired-instruction
curve for the heads whose work crosses into C; it is advisory, never a gate, and
it is why `unique-atom` has no row.
`sh tools/check.sh memo-advisor` reads a workload's own call counts and proposes
`(cache <head> force|refuse)` rows, pricing each one by re-running the whole
workload in a fresh process with the row declared and reporting the inference
count before and after. It NEVER writes a row: a proposal is a line in the
report and in `--json`, and declaring it is the program's own
`!(add-atom &metta (cache <head> <policy>))`. `--workload` takes `bench` (the
memoisation chapter, the default), `examples` (the whole corpus) or a path;
`--candidates N` bounds how many proposals are measured, most-called first. A
workload that ran no compiled head at all is refused by name rather than
reported as having nothing to say. The hit ratio is a property of the PAIR of
runs, not of either: under the automatic memo a head's profile counts its
MISSES, because a hit never reaches the predicate.

## Downstream packages built on this surface

`metta-fabricpc` projects a FabricPC predictive-coding network into a space, so
settling, attention and comparison are MeTTa rather than Python. It is not a
special case in the engine: it is an ordinary user of `op`, `arrays.install`,
`integrate.facts` and the provider seam.

The file library adds `make-dir!`, `delete-dir!`, `copy-file!`, `file-metadata!`,
`temp-dir!`, `path-join`, `path-parent`, `path-name`, and `path-extension`.
`stderr!` writes and flushes standard error; `stdin-to-string!` consumes
standard input through EOF; `(stdin)`, `(stdout)` and `(stderr)` are those same
three streams as handles 0, 1 and 2, so every handle operation reaches them and
`file-close!` refuses all three. `exit!` terminates the entire process with an
integer status from 0 to 255, including an embedding host. `csv-space` returns a
read-only row space whose queries reopen and stream the CSV file;
`csv-snapshot!` reads the file once into an ordinary space of
`(row Number Field...)` atoms, so repeated queries pay one parse and the record
number can skip a header; fields remain strings either way. `trace-source`
returns a space of selected trace events; Python selects the same functions
with `m.trace(source, filter=...)` before recording bounds are applied.

`observe-source` takes an execution space, a source label and source text. Its
report space contains binary `source-coverage` rows, unchanged `source-error`
values and `source-frame` rows with exact or `generated-by` attribution.
Coordinates are one-based Unicode codepoints with exclusive ends. Unavailable
source metadata is explicit; only the observation collects diagnostic state.
A host error or the `observation-exception` kept as text is written from the
term as raised, its variables numbered, so two observations of one source store
identical rows whatever exception hooks other libraries hold.

`metta_with_trailed(Key, Value, Goal)` runs a host goal with temporary engine
context. Entry and ordinary return use backtrackable global writes, so failure,
exception, cut and redo restore the correct enclosing value. An unset key reads
as the inactive value `[]` after ordinary return. Read through `nb_current/2`;
never replace a scoped root with `nb_setval/2`, `nb_linkval/2` or `nb_delete/1`.
Mutate a context payload through `nb_setarg/3` or `nb_linkarg/3` when needed.
A reader of such a context is declared once beside the door that writes its
key, `:- seam:context_reader(Head, Key, Shape)` with `Shape` one of
`value(Pattern)` or `stack(Pattern)`; the declaration defines the predicate and
compiles every resolving call to the read, one inference for an absent,
inactive or one-element context, the cost of the dynamic fact it replaced.

`metta_with_trailed_enumeration(Key, Value, Goal)` is the same context over
Goal's WHOLE enumeration: the value stays in place between answers and the
prior value returns once Goal is finished, cut, failed or raised, which is
`setup_call_cleanup/3`'s scope with its entry write registered first and
trailed. Use it where a caller collects Goal's answers and reads nothing
between them, and `metta_with_trailed/3` where each answer's continuation
must see the enclosing value. The enumeration door costs one write per scope
where the other costs one per answer.
The `prolog-static` lane refuses state writes in cleanup-wrapper setup goals.
