Memories and Scopes
The compiler checks statically resolvable scopes, including tools reached through an agent's selected skills and imported modules. A skill's scope does not lend authority to the active agent. Delegation establishes the callee's own boundary. Runtime checks remain mandatory for direct AIR, host bindings and dynamic decisions.
In Touba, a memory is a logical resource. It is not a native backend.
memory ProjectKnowledge
Principle
The connection between Touba and a real memory goes through four layers:
source .tb -> AIR -> resource binding + manifest -> handler -> real backend
The resource binding says which host backend corresponds to the logical memory. The manifest says which handler may execute the access tool. The runtime verifies both before dispatch.
Owner Scope
An owner can declare a scope:
agent Researcher
responsibility "Fulfill the declared Researcher responsibility using only authorized capabilities."
memory ProjectKnowledge read
uses ReadProjectKnowledge
callable_by strategy RunKnowledge
The scope says that this owner can request logical access.
Access Tool
Effective access goes through a tool:
tool ReadProjectKnowledge
uses memory ProjectKnowledge read
takes query as Query
gives KnowledgeResult
requires memory_read
The tool handler performs the concrete access: file, database, PostgreSQL, vector store, or internal service. Memory backends remain host-side components.
Resource Binding
The resource binding connects the logical memory to non-secret host wiring.
{
"resource_bindings_schema_version": "touba-resource-bindings-v1",
"resources": {
"memory:examples/ProjectKnowledge": {
"kind": "memory_backend",
"provider": "host.http.memory_backend",
"config": {
"endpoint_url": "http://127.0.0.1:39123"
},
"grants": ["memory.read"],
"secrets": ["MEMORY_BACKEND_TOKEN"],
"required_secrets": ["MEMORY_BACKEND_TOKEN"],
"limits": {
"max_payload_bytes": 65536
}
}
}
}
config must not contain a token, DSN, API key, raw payload, or secret value. Sensitive values stay in the secret system and are referenced by handles.
Manifest
The manifest must grant memory access to the tool binding.
"memories": [
{ "ref": "memory:examples/ProjectKnowledge", "access": "read" }
]
The runtime crosses the access declared by the tool, the manifest grant, the memory binding, and the active owner scope.
With resource binding transmission (RB-2), the runtime then sends to the handler only the resource bindings used by the called tool. In the JavaScript SDK, the handler reads them through context.resourceBindings.
PostgreSQL Example
If PostgreSQL acts as a memory, PostgreSQL stays in the handler or host service.
The Touba program declares the logical memory and access right. The resource binding identifies the host backend and expected handles. The manifest identifies which handler to call. The handler contains PostgreSQL code or calls an internal service, and receives only the explicitly granted secrets.
For a replayable HTTP scenario, see Memory with a Host Backend.
For a real PostgreSQL scenario with an active agent, read / write scopes, and refusal before database write, see PostgreSQL Memory with Agent and Scopes.
The host backend can be launched directly by your application, by an internal service, or by Docker. This does not change Touba semantics: the runtime always consumes an explicit resource binding and does not discover the backend by convention.
Runtime Contract
Touba provides the logical memory declaration, owner scopes, tool access declarations, manifest grants, resource bindings, and runtime checks before dispatch.
Memory stores, PostgreSQL or vector-database adapters, policy languages, and workspace writes connect through explicit host integrations.
Memory shared by parallel branches
Local branch values do not merge persistent memory. Compatible read accesses
to the same logical memory can coexist; write and append take an exclusive
lock during dispatch. Tools using several memories acquire locks in canonical
order. Locks do not cover a whole subworkflow or its model calls.
This protection belongs to the runtime executing the group. Other services or
processes may write to the same backend: handlers must use the backend's revision
checks, transactions or idempotency when needed. A parallel join is not a
distributed transaction. See Strategy and
Idempotent effects.