Skip to main content
Version: 1.0.0

Package reference

Package availability

Local packages are available now. The public package server is undergoing validation and testing and will be available soon.

Touba 1.0.0 supports creating, installing and sharing packages locally. Start with the practical guide. In a consuming project, install the shared directory or archive:

touba package add ./acme.echo-1.0.0.tar.gz
touba package check

Follow the server launch on the roadmap.

Shared host modules​

A package can distribute an attestation or decision adapter in hosts. Each entry has a unique id, a kind and a path: human_approval or decision_provider, with a JS or Python file. A host-only package may declare exports: {}.

Manifest fields
{
"hosts": [
{ "id": "approval", "kind": "human_approval", "path": "host/approval.mjs" },
{ "id": "decision", "kind": "decision_provider", "path": "host/decision.py" }
],
"files": ["host"]
}

The project enables a module through pkg:organization.package/identifier in --human-approval-host or --agent-decision-provider. Touba verifies every installed package's inventory before loading the module. Include helper files in files; install JS or Python dependencies explicitly in the application environment. Host modules are trusted application code. Restart the host after replacing a package that has already been loaded.

Proposed Python handlers use the consuming project's .venv interpreter when present. Touba prevents bytecode writes during their execution. For separately launched Python tests, use python -B. A cache added under packages/ remains an undeclared file: check its origin and reinstall a validated copy, keeping the approved lock unchanged.

Grants control admission of Touba operations. Configure host-process confinement separately through the sandbox policy.

The single author manifest is touba.package.json, using touba-package-v1. Contextual procedures and reusable agents share the same distribution format. Source imports remain typed.

Commands​

CommandEffect
touba package newQuestionnaire with confirmation before creation
touba package new "Invoice tools" --org "North Company" --yesCreates invoice-tools/, identity north-company.invoice-tools
touba package publish [directory] --registry <directory>Publish a local static draft, without overwriting or executing package code
touba package check [directory]Real validation, no tests executed; --publishing requires sharing metadata
touba package test [directory]Explicit declared Node tests; pass extra variables with --env NAME
touba package version patchStrictly higher version; also accepts minor, major or an exact version
touba package pack [directory]dist/<name>-<version>.tar.gz; optional --output, no overwriting
touba package add <name|directory|archive>Locked installation; a bare name selects a manual drop under packages/
touba package add org.name@1.0.0 --registry <source>Exact version from a chosen registry
touba package listList and validate registered dependencies
touba package remove org.nameRemove a dependency not required by another package

All accept --json and --root. Commands find the root from subdirectories; for new, --root is the parent of the new directory. With no target, check validates the author package or an application's registered dependencies. Exit codes: 0 success, 1 failed/missing tests or cancelled creation, 2 contract/argument error. Check/add/pack never execute third-party tests. A local organization name proves neither availability nor public ownership.

Manifest fields​

FieldRequirement
package_schema_versiontouba-package-v1
nameQualified lowercase identifier, such as acme.billing
versionExact SemVer, such as 1.2.0
touba.air_profiletouba-air-json-canonical-v1
touba.runtime_compatibilityA checked SemVer range
exportsObject with optional types, defines, functions, tools, skills, agents, strategies, memories lists
contextsOptional contextual procedures
dependenciesOptional map of package names to exact versions
filesIncluded relative files/directories; defaults to src for code
handlersSupplied implementations, not effective bindings or grants
enginesOptional node range and platforms list
description, publisher, licenseRequired to prepare the archive with pack
readmeREADME included in the archive; required for direct CLI publication. A publication service can accept a separately supplied overview.
contract_testsNode .test.mjs, .test.cjs, .test.js files; run only by package test
rootOptional; must be .
provenanceUnsigned kind, source, revision metadata

At least one export or context is required. Every exported reference must exist. For example, skill:acme.billing/PrepareInvoice is declared in src/acme/billing.tb. Constants in exports.defines use constant:.

Context​

Entry in contexts
{
"id": "review",
"description": "Review supplied material against explicit criteria.",
"procedure": "SKILL.md",
"activation": { "model_invocable": true, "user_invocable": true },
"resources": [
{ "name": "checklist", "path": "resources/checklist.md", "kind": "reference",
"description": "Acceptance checklist", "loadable_as_context": true }
],
"execution_links": []
}

The Markdown procedure must be nonempty. Resources have unique names, paths, kinds and descriptions. Kinds: procedure, reference, example, template, sample, script, fixture. Scripts cannot be loaded or run as context. Execution links contain label, target_ref and description; referring to a tool or skill does not authorize it.

Selection: --skill-pack packages/acme.review#review. Activation: --activate-skill-pack skill_pack:acme.review/review. Touba derives the internal touba-skill-pack-v1 protocol; authors do not maintain a second manifest.

Supplied handler​

Entry in handlers
{
"tool": "tool:acme.billing/ReadInvoice",
"path": "handlers/read_invoice.mjs",
"protocol": "touba-tool-handler-v1",
"documentation": "README.md"
}

The tool must be declared. Optional configuration points to a file describing configuration. The CLI checks its inclusion, not business-service availability. The consuming project chooses the process binding, grants, secrets, effect contract and limits.

Validation and diagnostics​

touba package check --json preserves source errors as objects in diagnostics: code, message, severity, source_path and source_ref when available. Its top-level code is PackageSourceInvalid. Source line and column indices are zero-based in JSON; terminal locations start at one. A failed source compilation is reported before export checks, so one source error does not generate a cascade of missing exports.

Paths are confined and relative. Archive links, special files, traversal and collisions are refused. Common secret files and node_modules cannot be distributed. Limits: 4,096 files/entries, 16 MiB per file, 64 MiB of content, 1 MiB per manifest, depth 32, and at most 128 packages per dependency closure. Installation executes no command supplied by a package.

DiagnosticAction
PackageDependencyMissingSupply the exact dependency
PackageDependencyConflictResolve conflicting versions or contents
PackageDependencyCycleRemove the cycle
PackageIntegrityMismatchCompare against the approved package and lock; do not blindly accept changes
PackageNotInstalledValidate and register with package add
PackageRequirementMissingSupply the declared host environment
PackageExportUnknownRefFix the export or declaration
PackageAuthorityFieldForbiddenConfigure authority in the consuming project
PackageInstallationIncompleteInspect the interrupted transaction before recovery

The installation lock does not replace execution supply-chain checks. See the author and consumer guide.

Explicit handler selection​

A package may propose a handler but never grants authority. In host decisions, select it with bindings[toolRef].package_handler = "organization.name". Keep the required grants, secrets, limits and effect contract explicit. Preparation uses the declared package entrypoint and avoids generating an unused local stub. Unknown or unrelated proposals are refused.

PackageExportMissing covers an unexported import, a declared module missing from the package inventory, or a package with no export or context. PackageExportUnknownRef covers an export whose declaration does not exist. A copied package is not implicitly activated: run touba package add organization.name.

Private drafts​

CommandResult
touba package submit [directory] --registry <URL>Checked archive submitted as a private draft
touba package checkout <id> --registry <URL> [--root <parent>]New author folder named after the package
touba package submit [directory] [--draft <id>]Resubmission to the linked or explicitly selected draft
touba package submit [directory] --ci <authorization> --registry <URL>New draft from an authorized GitHub Actions job

Interactive commands accept --no-browser and --json. Each operation uses browser authentication; the service requires strong authentication for these CLI operations. Checkout checks private access and integrity before extraction. Submission runs the service’s validation and isolated tests. Publication remains an explicit action.

The --ci mode uses GitHub OIDC with id-token: write. Its authorization binds the repository, workflow, branch and environment. It prepares a new draft, without a local link or automatic replacement. Final publication requires an authorized person and strong authentication in the service. The --draft and --no-browser options are incompatible with --ci.

The local .touba/package-draft.json link stays outside the archive. It stores registry, identity/version, ID, revision and digest, without a token. Resubmission keeps remote overview edits. A changed archive or concurrent revision stops replacement.

DiagnosticAction
PackageAlreadyExistsChoose a parent without a folder named after the package
PackageDraftConflictReview the remote draft before resubmitting
PackageDraftTargetMismatchCheck the target registry, identity and version
PackageDraftIntegrityMismatchAsk the operator to verify the archive
PackageDraftBusyInspect the active operation before recovering the lock
PackageOperationCancelledCheck the draft before retrying
PackageDraftRefusedCheck your session, permissions and the service diagnostic

Signed remote registry​

Publishing to a compatible service opens browser authentication:

touba package publish --registry https://registry.example.org/registry

The service checks your identity, namespace permissions, archive and isolated contract tests. --no-browser displays the link to open manually. Credentials remain in memory during the operation.

For installation, obtain approved keys from the operator:

touba package add acme.review@1.0.0 \
--registry https://registry.example.org/registry \
--trust registry-trust.json

For a private registry, the command opens the browser to authorize catalog reads. --no-browser displays the link to open manually. The read token stays in memory during installation; revocation is requested when the operation ends. Publishing uses a separate authorization.

The CLI verifies the signature, index validity, digests and version status. Installation preserves the consuming project's explicit execution permissions. These commands work with JavaScript and Python handlers.

The CLI keeps the last accepted revision and known keys in registry-trust.json.sqlite, beside the selected trust file. Keep both files together. An older revision, different content at the same revision or a revoked key stops the command. For rotation, the operator first supplies a trust file with both active keys, then removes or revokes the old one. An observed revocation remains effective if an older trust file is restored.

Moving the trust file without its SQLite state starts a new trust bootstrap. The first read relies on the verified key and signature validity; backing up the state then preserves rollback protection.

touba package check archive.tar.gz --publishing checks an archive directly, without installing it or executing its tests.

Read errors as JSON​

package ... --json returns errors on stdout with status: "error", diagnostics[].code, message, and a nonzero exit code. A file at the reserved packages/ path produces PackageDirectoryRequired; a symlink produces PackageSymlinkForbidden. A missing resource produces PackageFileMissing with its relative path. PackageExportMissing covers a non-exported import, an exported module missing from the inventory, or a package with neither exports nor context. PackageExportUnknownRef identifies an export pointing to an absent declaration.