Skip to main content
Version: 1.0.0

Paradigm Transitions Toward Touba

A new paradigm does not make previous languages incapable. A Python, Java, or TypeScript program can call a model, control a secret, write a trace, or limit an access path.

The difference is where the complexity lives. Each paradigm moves part of that complexity into a more legible abstraction. Touba extends this movement to agentic systems: agent responsibility, tools, secrets, memory, human validation, and traces become explicit program contracts instead of dispersed conventions.

The examples below are pedagogical. They show the same question through four styles:

StepLanguage UsedWhat It Highlights
Imperative scriptPythonaction order is direct and quick to read
Object-orientedJavaresponsibilities become named objects and services
Typed functional styleTypeScripttransformations and types make boundaries more visible
Probabilistic Agentic Programming with ToubaToubaautonomy, authority, handlers, and traces become program artifacts

Case 1 - External Content or Agentic Instruction​

Question: a web page contains text that looks like an instruction. How can a program avoid treating it as a command addressed to the agent?

Imperative Python​

Python
def answer_from_page(url: str) -> str:
source_text = {
"kind": "external_content",
"content": fetch_url(url),
}

instruction = review_and_build_instruction(source_text)
return call_llm(instruction)

Python can handle the problem with clear discipline: name source_text, call a review step, then call the model.

Application responsibility: the boundary depends on code conventions. Nothing prevents another call path from sending source_text["content"] directly to the model.

Object-Oriented Java​

Java
final class SourceText {
private final String content;

SourceText(String content) {
this.content = content;
}

String content() {
return content;
}
}

final class AgentInstruction {
private final String content;

private AgentInstruction(String content) {
this.content = content;
}

static AgentInstruction fromReviewedSource(SourceText source, HumanReview review) {
review.requireAccepted();
return new AgentInstruction("Summarize this reviewed source: " + source.content());
}

String content() {
return content;
}
}

Objects absorb part of the complexity: SourceText and AgentInstruction are no longer interchangeable strings. Building an instruction goes through a named method.

Application responsibility: the actual model call, secrets, authority, and trace still live in host code or surrounding frameworks.

Typed Functional TypeScript​

TypeScript
type SourceText = Readonly<{
kind: "external_content";
content: string;
}>;

type AgentInstruction = Readonly<{
kind: "agent_instruction";
content: string;
reviewedBy: string;
}>;

const buildInstruction = (source: SourceText, reviewedBy: string): AgentInstruction => ({
kind: "agent_instruction",
content: `Summarize this reviewed source: ${source.content}`,
reviewedBy,
});

const callLlm = async (instruction: AgentInstruction): Promise<string> => {
return await llm(instruction.content);
};

The typed functional style absorbs another part of the complexity: the transformation becomes an explicit function, and callLlm expects an AgentInstruction, not arbitrary text.

Application responsibility: TypeScript helps during development, but execution, permissions, manifest, secrets, and structured traces still need to be organized elsewhere.

Touba​

source.tb
module examples.boundary

type SourceRequest
url is Text

type SourceText
content is Text

type AgentInstruction
content is Text

type LLMAnswer
content is Text

tool FetchExternalContent
takes request as SourceRequest
gives SourceText
requires network

tool BuildAgentInstruction
takes source as SourceText
gives AgentInstruction

tool CallLLM
takes instruction as AgentInstruction
gives LLMAnswer
requires network, secret_read
secrets LLM_API_KEY

skill AnswerWithReviewedSource
takes request as SourceRequest
gives LLMAnswer
uses FetchExternalContent
uses BuildAgentInstruction
uses CallLLM
do
FetchExternalContent
with request as request
into source

human.review
with context as source
into review

BuildAgentInstruction
with source as source
into instruction

CallLLM
with instruction as instruction
into answer

give answer

Touba places the boundary in the program: external content, agentic instruction, human review, the LLM tool, the secret, and requirements are visible in the .tb contract.

What Touba absorbs: the runtime can refuse an undeclared handler, an ungranted secret, or an incompatible payload before the call. The trace can then show steps and refusals without becoming a complete prompt log.

Scope: this separation makes confusion more visible, testable, and auditable. The security model extends this foundation with payload policies, external validation, and observability integrations.

Case 2 - Real Tool, Secret, and Access Right​

Question: an agent must call an external service with a key. Where should the network and secret requirements be declared?

Imperative Python​

Python
import os

def summarize(query: str) -> str:
api_key = os.environ["LLM_API_KEY"]
search_result = search_web(query)
return call_llm(api_key=api_key, text=search_result["text"])

The script is compact. The developer immediately sees the execution order.

Application responsibility: network access, the secret, key policy, timeout, payload size, and audit are details to maintain in code or in the environment.

Object-Oriented Java​

Java
final class SummarizeService {
private final SearchClient searchClient;
private final LlmClient llmClient;
private final SecretProvider secrets;

SummarizeService(SearchClient searchClient, LlmClient llmClient, SecretProvider secrets) {
this.searchClient = searchClient;
this.llmClient = llmClient;
this.secrets = secrets;
}

Summary summarize(String query) {
SearchResult result = searchClient.search(query);
String apiKey = secrets.resolve("LLM_API_KEY");
return llmClient.summarize(apiKey, result.text());
}
}

The object absorbs wiring complexity: dependencies become explicit in the constructor, and the service carries a readable responsibility.

Application responsibility: the language does not know that LLM_API_KEY is an agentic handle, that searchClient requires network, or that this service may only be called by specific agents.

Typed Functional TypeScript​

TypeScript
type Capability = "network" | "secret_read";
type SecretHandle = "LLM_API_KEY";

type Binding = Readonly<{
grants: readonly Capability[];
secrets: readonly SecretHandle[];
}>;

const requireBinding = (binding: Binding): void => {
if (!binding.grants.includes("network")) throw new Error("network grant missing");
if (!binding.grants.includes("secret_read")) throw new Error("secret grant missing");
if (!binding.secrets.includes("LLM_API_KEY")) throw new Error("secret handle missing");
};

const summarize = async (query: string, binding: Binding): Promise<string> => {
requireBinding(binding);
const source = await searchWeb(query);
return await callLlm("LLM_API_KEY", source.text);
};

Types make capabilities and handles more legible. The check becomes a separate, testable function.

Application responsibility: this discipline remains in the TypeScript code. It does not automatically create AIR, a manifest, a shared runtime refusal, or a shared trace surface.

Touba​

source.tb
module examples.secure_tool

type SearchRequest
query is Text

type SearchResult
text is Text

type Summary
text is Text

tool SearchWeb
takes request as SearchRequest
gives SearchResult
requires network

tool SummarizeWithLLM
takes result as SearchResult
gives Summary
requires network, secret_read
secrets LLM_API_KEY

skill BuildSummary
takes request as SearchRequest
gives Summary
uses SearchWeb
uses SummarizeWithLLM
do
SearchWeb
with request as request
into result

SummarizeWithLLM
with result as result
into summary

give summary

agent Analyst
responsibility "Fulfill the declared Analyst responsibility using only authorized capabilities."
uses BuildSummary
callable_by strategy RunSummary

strategy RunSummary
uses Analyst
do
Analyst

Touba separates the handler contract. The program states that SearchWeb requires network, and that SummarizeWithLLM requires network, secret_read, and the LLM_API_KEY handle. The manifest must then grant these elements explicitly to the runtime.

What Touba absorbs: the right to call a handler is not only a service convention. It becomes a relation between .tb source, AIR, manifest, runtime, and trace.

Scope: manifest grants express Touba authority at the execution-contract level. System controls, network controls, and handler dependency controls remain explicit host and supply-chain responsibilities.

Case 3 - Memory and Auditability​

Question: an agent reads project memory. How can a team know who read what, with which logical right, and where the access is observed?

Imperative Python​

Python
trace = []

def answer_with_memory(question: str) -> str:
trace.append({"event": "memory_read_requested", "query": question})
note = memory_read(question)
trace.append({"event": "memory_read_completed"})
return call_llm(f"Answer with project context: {note}")

The script can produce readable events.

Application responsibility: trace, memory, access right, and prompt handling are conventions that every function must respect.

Object-Oriented Java​

Java
final class AuditedMemory {
private final MemoryRepository repository;
private final AuditLog auditLog;

AuditedMemory(MemoryRepository repository, AuditLog auditLog) {
this.repository = repository;
this.auditLog = auditLog;
}

MemoryNote read(String agentName, String query) {
auditLog.record("memory_read_requested", agentName);
MemoryNote note = repository.read(query);
auditLog.record("memory_read_completed", agentName);
return note;
}
}

The object absorbs audit responsibility around the repository. Domain code can read AuditedMemory instead of calling the backend directly.

Application responsibility: the language does not force every access to go through this object. The link between agent, scope, backend, and trace depends on the application architecture.

Typed Functional TypeScript​

TypeScript
type TraceEvent = Readonly<{ name: string; actor: string }>;
type MemoryNote = Readonly<{ content: string }>;
type RunState = Readonly<{ trace: readonly TraceEvent[] }>;

const addTrace = (state: RunState, event: TraceEvent): RunState => ({
trace: [...state.trace, event],
});

const readMemory = async (
state: RunState,
actor: string,
query: string,
): Promise<readonly [RunState, MemoryNote]> => {
const started = addTrace(state, { name: "memory_read_requested", actor });
const note = await memoryRead(query);
const completed = addTrace(started, { name: "memory_read_completed", actor });
return [completed, note];
};

The functional style makes trace state explicit: reading memory also returns a new run state. Implicit mutation is reduced in typed code.

Application responsibility: the program carries scope rules, grants, memory binding, and the shared trace format itself.

Touba​

source.tb
module examples.memory_audit

define MemoryQuestion as Text = "incident policy"

type MemoryNote
content is Text

memory ProjectKnowledge

tool ReadProjectKnowledge
uses memory ProjectKnowledge read
takes query as Text
gives MemoryNote
requires memory_read

skill ReadContext
gives MemoryNote
memory ProjectKnowledge read
uses ReadProjectKnowledge
do
ReadProjectKnowledge
with query as MemoryQuestion
into note

give note

agent RiskAnalyst
responsibility "Fulfill the declared RiskAnalyst responsibility using only authorized capabilities."
memory ProjectKnowledge read
uses ReadContext
callable_by strategy RunMemoryCheck

strategy RunMemoryCheck
uses RiskAnalyst
do
RiskAnalyst

Touba places memory in the agentic contract. Memory is logical, the tool declares read access, the agent declares its scope, and the runtime checks these elements against the manifest before calling the handler.

What Touba absorbs: auditability does not depend only on a hand-written logger. Authorized or refused accesses can be connected to AIR, manifest, the active agent, and the trace.

Scope: Touba governs logical access, provenance, and traces. Memory backends, content verification, and handler audit remain explicit integration responsibilities.

What the Transition Shows​

TransitionAdded AbstractionComplexity Absorbed
Imperative to object-orientednamed responsibilitiesgrouping state, behavior, and dependencies
Object-oriented to typed functionalexplicit transformations and typesreducing implicit mutation and making boundaries visible
Typed functional to Toubaexecutable agentic contractconnecting agents, tools, secrets, memories, validations, and traces to the runtime

Touba's value is not that it makes possible what other languages cannot do. Its value is to give first-class program status to responsibilities that, in earlier paradigms, often remain spread across host code, configuration, team discipline, and documentation.

In practice, those responsibilities often look like this:

Usual LocationExample Responsibilities
Host codeverify that a handler receives the right payload, apply a timeout, avoid sending a secret value to a prompt, write audit events in the right place
Configurationconnect a tool to a handler, grant network or secret_read, choose the secret profile, set execution limits
Team disciplineavoid passing external content directly as instruction, request human review before a sensitive conversion, keep handlers small and reviewed
Documentationexplain which agent can call which other agent, which secret is used by which tool, which memory may be read, which trace proves a refusal or validation

Touba does not remove these responsibilities. It moves them closer to the program: they become more visible in .tb source, AIR, manifest, runtime, and traces.

Verification Sources for External Examples​