Aller au contenu principal
Version: 1.0.0

Référence manifest V1

Le manifest relie les tools à des handlers hôtes et peut activer explicitement des triggers. Il est fourni explicitement au runtime.

Dans un projet Touba, touba prepare peut générer ou vérifier le manifest à partir de l'AIR. Cela ne change pas le runtime : l'exécution avec tool demande toujours --manifest.

Le handler est lancé sans shell implicite et avec un environnement minimal. Pour un handler JavaScript, touba prepare écrit donc le chemin absolu du Node courant dans handler.command.

Forme minimale​

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"bindings": {
"tool:examples.search/SearchDatasets": {
"handler": {
"kind": "process",
"command": "/absolute/path/to/node",
"args": ["handlers/search_datasets.handler.mjs"],
"cwd": "."
},
"grants": ["network"],
"effect_contract": { "kind": "none" },
"sandbox": {
"required": true
},
"timeout_ms": 5000,
"max_payload_bytes": 1048576
}
}
}

Champs​

ChampRôle
manifest_versionVersion du manifest
effect_contractContrat d’effet explicite pour chaque binding
bindingsTable explicite tool → binding
triggersTable explicite trigger → activation
run_limitsBudgets d’autonomie applicables au run
handler.kindprocess
handler.commandExécutable lancé sans shell implicite
handler.argsArguments du process
handler.cwdDossier de travail optionnel
grantsCapabilities accordées explicitement
sandboxIsolation de plateforme exigée pour le process handler
secretsHandles de secrets accordés
memoriesAccès mémoire accordés
timeout_msTimeout process
max_payload_bytesLimite de payload

Contrat des effets​

touba-manifest-v1 est le seul format admis. Chaque binding possède exactement un contrat d'effet explicite :

Binding sans écriture externe
"effect_contract": { "kind": "none" }
Binding avec écriture externe
"effect_contract": {
"kind": "external_write",
"retry_mode": "idempotency_key"
}

Pour external_write, retry_mode vaut idempotency_key, reconcile ou none. Il est interdit avec kind: none. Les champs et valeurs inconnus sont refusés. Le runtime exige une portée d'effet et un journal durables avant de lancer une écriture externe.

Seule une écriture externe peut déclarer la relation inverse suivante :

Écriture externe compensable
"effect_contract": {
"kind": "external_write",
"retry_mode": "idempotency_key",
"compensation": {
"entry_ref": "strategy:orders/CancelOrder"
}
}

compensation contient seulement entry_ref. La stratégie doit exister dans l'AIR exact et se fermer sur un unique appel de tool externe suivi directement d'un terminal. L'inverse ne peut pas déclarer sa propre compensation.

Secrets​

Les secrets sont des handles. Le manifest ne contient pas les valeurs.

touba.manifest.json
"secrets": ["OPENAI_API_KEY"]

Scopes secrets par agent​

touba.manifest.json
{
"agent_secret_scopes": {
"agent:examples/Researcher": ["OPENAI_API_KEY"]
}
}

Si le handle est absent du scope de l'agent actif, le runtime refuse avant handler.

Mémoires​

touba.manifest.json
"memories": [
{ "ref": "memory:examples/ProjectKnowledge", "access": "read" }
]

Le runtime croise AIR, manifest et owner actif avant dispatch.

Isolation des handlers​

Un binding peut exiger une isolation de plateforme :

touba.manifest.json
"sandbox": {
"required": true,
"profile": "default"
}

Lorsque sandbox.required: true, macOS utilise sandbox-exec ; Linux x64 combine bubblewrap, seccomp et le lanceur natif touba-sandbox avec Landlock ABI 3 minimum. Les données hors périmètre, écritures, descendants et connexions réseau sont refusés par défaut. Les essais natifs Linux couvrent Ubuntu 24.04, Node et Python, y compris l'arrêt des descendants au timeout.

Sous Linux, bubblewrap doit être installé et les user namespaces utilisables. Un hôte Ubuntu protégé par AppArmor peut nécessiter un profil administrateur limité à ce binaire, sans désactiver les protections globales. Un chemin write_paths doit déjà exister : utilisez un répertoire de sortie dédié pour créer des fichiers. Écrire n'accorde pas la lecture. Les sockets Unix exacts exigent Landlock ABI 9 ; une politique non applicable est refusée avant lancement. La sonde exécute une commande sous confinement pour vérifier les prérequis.

Le backend Windows est encore en qualification pour la V1, notamment pour les handlers Python asynchrones sans autorisation réseau. Il n'est pas annoncé comme disponible dans une distribution finalisée. Un confinement indisponible ou une politique non applicable bloque le lancement, sans exécution directe de secours. Sans sandbox obligatoire, les handlers restent du code hôte de confiance. Le code HandlerSandboxUnsupportedPolicy désigne une politique non prise en charge par le backend sélectionné.

Les chemins sont relatifs au cwd du handler ou absolus. L'interpréteur doit avoir un chemin absolu ; l'alias node désigne le Node de Touba.

ChampGrant requisPortée
code_pathscode choisi par l'hôtefichiers individuels existants de code/bibliothèque
read_pathsfilesystem_readfichiers ou sous-répertoires
write_pathsfilesystem_writefichiers ou sous-répertoires
local_socketsnetwork_localchemins exacts de sockets Unix clients

process autorise des enfants qui héritent de la politique. network ouvre le réseau ; network_local seul n'ouvre pas le réseau IP. Un service autorisé peut lui-même être très privilégié : un socket Docker n'est pas équivalent à une connexion limitée à une base.

La base technique comprend le code exécutable, les bibliothèques chargées par Node, les bibliothèques système, les métadonnées de chemins et les configurations OpenSSL usuelles. Elle n'ouvre pas globalement le projet, le dossier personnel ni les fichiers temporaires. Les chemins explicitement accordés restent à auditer ; la sandbox ne prouve pas la sûreté du handler.

Contraintes de payload​

Un binding peut déclarer des contraintes de payload appliquées après le schéma AIR et avant le handler pour l’input, puis avant publication de résultat pour l’output.

touba.manifest.json
"payload_constraints": {
"input": {
"request.query": {
"non_empty": true,
"max_length": 120
},
"request.rows": {
"min": 1,
"max": 50
},
"request.mode": {
"allowed_values": ["dry_run", "review", "execute"]
},
"request.recipients": {
"min_items": 1,
"max_items": 5
}
},
"output": {
"$": {
"max_items": 20
}
}
}

Les opérateurs disponibles sont bornés :

  • non_empty et max_length pour Text ;
  • min et max pour Int ou Float ;
  • allowed_values pour scalaires JSON portables ;
  • min_items et max_items pour List<T>.

Un refus produit ToolPayloadConstraintViolation sans afficher la valeur brute du payload.

Budgets de run​

Le manifest peut restreindre les budgets d’autonomie :

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"run_limits": {
"max_steps": 100,
"max_tool_calls": 20,
"max_agent_invocations": 5,
"max_provider_calls": 4
},
"bindings": {}
}

run_limits concerne le run Touba. Les champs timeout_ms et max_payload_bytes dans un binding concernent le process handler.

Le manifest peut restreindre une limite AIR. Il ne peut pas l’élargir silencieusement.

Triggers​

Un trigger reste inactif tant que le manifest ne l’active pas.

touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"triggers": {
"trigger:examples.daily_research/DailyResearchSchedule": {
"enabled": true,
"source": {
"kind": "schedule"
},
"limits": {
"max_runs_per_day": 1,
"timeout_ms": 30000
}
}
}
}

Le runtime refuse si la source événementielle ne correspond pas ou si le manifest tente d’élargir une limite déclarée dans l’AIR.

Relation avec le lock supply chain​

Le manifest reste l’autorité runtime : il accorde le handler, les grants, les secrets, les mémoires, les limites et les triggers.

Un lock supply chain ne donne aucun droit supplémentaire. Il vérifie seulement que l’AIR, le manifest, les handlers, la metadata SDK et l’identité déclarée handler_package correspondent aux artefacts attendus. Avec l’extension artefacts de dépendances (SC-2), le même lock peut aussi vérifier des fichiers de paquet handler et des artefacts de dépendances déclarés explicitement. Avec l’extension provenance et revue (SC-3), il peut aussi porter une provenance et une revue déclarées.

Terminal
touba supply-chain validate \
--lock touba.lock.json \
--air program.air.json \
--manifest touba.manifest.json

Si le manifest change après la création du lock, la validation doit signaler une dérive. Le runtime continue toutefois à appliquer le manifest fourni à l’exécution.

Une revue de lock approuvée n’accorde aucun grant, secret, scope ou trigger. Elle documente une discipline de revue.

Frontières du manifest​

info
  • grants et sandbox sont deux contrôles distincts
  • une sandbox requise dépend du mécanisme disponible sur la plateforme
  • Le manifest n'est pas un système de permissions complet
  • Aucun handler n'est découvert automatiquement
  • Aucun secret n'est lu implicitement
  • Un manifest généré reste un artefact à relire, pas une autorisation invisible
  • Aucun trigger n'est activé automatiquement sans entrée manifest explicite