Docs / Embedding and internals

Architecture

Affordance has one engine, implemented in Rust. Applications and reusable application policies are written in the TSX subset described in LANGUAGE.md. CONTRACTS.md maps the public boundaries and their guarantees. File modules isolate declarations and share values only through explicit imports/exports; functions and closures retain their defining scope during calls and replay. Runtime source loading (loadModule from affordance:compiler) uses those same owned lexical environments and the same executor; apps supply dependency namespaces and own revision selection.

The renderer loads an app and its imports, evaluates it against state, lays out its token fragments, and returns exact token IDs plus the actions still visible in the final layout. Adapters project those actions into each model's protocol. Cropping never leaves an invisible action callable by the model.

The agent state machine takes one input and returns commands. The host runs model requests, machine calls, timers, and message delivery, then feeds their results back as journaled inputs. Each instance owns its state and children. The host owns external I/O, permissions, and durable storage. Replaying the journal reconstructs the instance. Eligible idle/stopped data states can use a verified checkpoint plus the newer journal inputs; full history stays on disk.

Conversation logs, folding, agent loops, and task-specific tools are TSX library or app code. The core provides the operations these policies need; it does not choose a task or training algorithm. Model servers and command executors are external bindings.

src/connectors/ supplies host integrations through the existing executor interface. The HTTP connector understands HTTP requests and responses; the MCP implementation is a TSX library over global Fetch (views/lib/mcp.tsx). The embedded standard library (src/web.tsx) provides Fetch, Headers and buffered Response behavior over the same executor boundary, without MCP in the engine. Apps choose which discovered tools become affordances. See docs/HTTP_AND_MCP.md for deployment and replay behavior.

#Repository boundary

The public framework consists of src/, reusable views/, the language/runtime specifications, API guides, regression tests, and small examples. The one installed binary is affordance. Rust benchmarks are development examples under tools/bench/.

Python in ref/, bench/, and test support is development tooling. It supplies independent reference outputs and tests interoperability; no Python process is required to use the Rust renderer or generic runtime. Examples that expose a Python tool do so explicitly through a machine binding, as an application choice. Their executable helpers live in tools/examples/ in the development checkout and are excluded from the runtime package.

The former phase2/ was a research program: training, game emulation, evaluation controllers, and experimental model runners. It is now a separate sibling checkout, affordance-research. Its results do not define the framework's behavior or install dependencies. Historical phase names describe project milestones, not framework versions.

A small Courier app remains as an example of state, layouts, and actions. Its training code, model weights, datasets, and game-specific executables belong to the research project.

#Release boundary

Cargo.toml lists the files included in the framework source package. Development caches and run output are ignored. A release must pass the validation in docs/DEVELOPING.md; publication also requires project license and release metadata to be chosen by the project owner.

Source: docs/ARCHITECTURE.md, about 2 minutes to read.