Skip to main content
Version: 1.0.0

Multi-team ownership and review gates

Platform owns a local package and its tool; customer operations owns the memory; security reviews the production profile. These are illustrative team declarations in an isolated project, not authenticated signatures or real organizational approvals. The handler reads an actual local customer file; it does not simulate a CRM API.

Prerequisites: Touba, Node.js 24 and npm. Use a macOS/Linux terminal.

Terminal
mkdir -p team-review-demo
cd team-review-demo
mkdir -p packages/customer/src/org/example src/examples handlers/org/example/customer vendor
npm init -y
node --input-type=module -e 'import {execFileSync} from "node:child_process"; import {copyFileSync} from "node:fs"; const v=JSON.parse(execFileSync("touba",["version","--json"],{encoding:"utf8"})); copyFileSync(v.distribution.sdk_archive,"vendor/touba-sdk.tgz");'
npm install --offline --ignore-scripts --save-exact ./vendor/touba-sdk.tgz

Package and importing module​

packages/customer/src/org/example/customer.tb
module org.example.customer

memory CustomerNotes

type CustomerRequest
customer_id is Text

type CustomerProfile
customer_id is Text
segment is Text
status is Text

tool FetchCustomerProfile
uses memory CustomerNotes read
takes request as CustomerRequest
gives CustomerProfile
requires filesystem_read, secret_read, memory_read
secrets CRM_API_TOKEN
packages/customer/touba.package.json
{
"package_schema_version": "touba-package-v1",
"name": "org.example.customer",
"version": "0.1.0",
"root": ".",
"touba": {
"air_profile": "touba-air-json-canonical-v1",
"runtime_compatibility": ">=1.0 <2.0"
},
"exports": {
"types": [
"type:org.example.customer/CustomerRequest",
"type:org.example.customer/CustomerProfile"
],
"defines": [],
"functions": [],
"tools": [
"tool:org.example.customer/FetchCustomerProfile"
],
"skills": [],
"strategies": [],
"agents": [],
"memories": [
"memory:org.example.customer/CustomerNotes"
]
},
"provenance": {
"kind": "local_path",
"source": "."
}
}

Integration tests for this local package run through exercise.mjs in the last section, covering successful execution and expected refusals.

src/examples/customer_review_app.tb
module examples.customer_review_app

import type CustomerRequest from org.example.customer
import type CustomerProfile from org.example.customer
import memory CustomerNotes from org.example.customer
import tool FetchCustomerProfile from org.example.customer

skill BuildCustomerReview
takes request as CustomerRequest
gives CustomerProfile
uses FetchCustomerProfile
memory CustomerNotes read
do
FetchCustomerProfile
with request as request
into profile
give profile

strategy RunCustomerReview
takes request as CustomerRequest
gives CustomerProfile
uses BuildCustomerReview
do
BuildCustomerReview
with request as request
into profile
show
with message as "Customer profile ready"
give profile

Explicit resources, ownership and runtime authority​

customer-notes.json
[
{
"customer_id": "CUST-001",
"segment": "enterprise",
"status": "review_ready"
}
]
touba.resources.json
{
"resource_bindings_schema_version": "touba-resource-bindings-v1",
"resources": {
"memory:org.example.customer/CustomerNotes": {
"kind": "memory_backend",
"provider": "host.local.customer_notes",
"config": {
"path": "customer-notes.json"
},
"grants": [
"memory.read"
],
"secrets": [],
"limits": {
"max_payload_bytes": 65536
}
}
}
}
touba.ownership.json
{
"ownership_schema_version": "touba-ownership-v1",
"teams": {
"team:platform": {
"display_name": "Platform"
},
"team:security": {
"display_name": "Security"
},
"team:customer_ops": {
"display_name": "Customer Operations"
}
},
"owners": {
"package:org.example.customer": [
"team:platform"
],
"tool:org.example.customer/FetchCustomerProfile": [
"team:platform"
],
"memory:org.example.customer/CustomerNotes": [
"team:customer_ops"
],
"resource_bindings:touba.resources": [
"team:platform"
],
"run_plan:touba.run-plan": [
"team:platform"
],
"lock:touba.lock.json": [
"team:security"
]
},
"review_gates": {
"prod": {
"requires_review_for": [
"package_export",
"tool_binding",
"required_capability",
"required_secret",
"resource_binding",
"run_plan",
"supply_chain_lock"
],
"reviewers": [
"team:security"
]
}
},
"reviews": [
{
"review_id": "review:customer/security-package",
"profile": "prod",
"target_ref": "package:org.example.customer",
"reviewer": "team:security",
"decision": "approved"
},
{
"review_id": "review:customer/security-tool",
"profile": "prod",
"target_ref": "tool:org.example.customer/FetchCustomerProfile",
"reviewer": "team:security",
"decision": "approved"
},
{
"review_id": "review:customer/security-resources",
"profile": "prod",
"target_ref": "resource_bindings:touba.resources",
"reviewer": "team:security",
"decision": "approved"
},
{
"review_id": "review:customer/security-run-plan",
"profile": "prod",
"target_ref": "run_plan:touba.run-plan",
"reviewer": "team:security",
"decision": "approved"
},
{
"review_id": "review:customer/security-lock",
"profile": "prod",
"target_ref": "lock:touba.lock.json",
"reviewer": "team:security",
"decision": "approved"
}
]
}
touba.manifest.json
{
"manifest_version": "touba-manifest-v1",
"bindings": {
"tool:org.example.customer/FetchCustomerProfile": {
"handler": {
"kind": "process",
"command": "node",
"cwd": ".",
"args": [
"handlers/org/example/customer/fetch_customer_profile.handler.mjs"
]
},
"grants": [
"filesystem_read",
"secret_read",
"memory_read"
],
"secrets": [
"CRM_API_TOKEN"
],
"memories": [
{
"ref": "memory:org.example.customer/CustomerNotes",
"access": "read"
}
],
"timeout_ms": 5000,
"max_payload_bytes": 1048576,
"effect_contract": {
"kind": "none"
}
}
}
}
handlers/org/example/customer/fetch_customer_profile.handler.mjs
import { readFile } from "node:fs/promises";
import { defineTool, ToubaHandlerError } from "@touba/sdk";
await defineTool({ toolRef: "tool:org.example.customer/FetchCustomerProfile",
requiredGrants: ["filesystem_read", "secret_read", "memory_read"], requiredSecretHandles: ["CRM_API_TOKEN"],
inputSignature: [{ name: "request", type_ref: "type:org.example.customer/CustomerRequest" }],
outputType: "type:org.example.customer/CustomerProfile",
run: async ({ request, context }) => {
const memory = context.resourceBindings.find(item => item.resource_ref === "memory:org.example.customer/CustomerNotes");
if (!memory || memory.provider !== "host.local.customer_notes" || !context.env.CRM_API_TOKEN)
throw new ToubaHandlerError("CustomerStoreUnavailable", "The authorized customer store is not configured.");
const profiles = JSON.parse(await readFile(memory.config.path, "utf8"));
const profile = profiles.find(item => item.customer_id === request.customer_id);
if (!profile) throw new ToubaHandlerError("CustomerNotFound", "No profile matches the requested customer.");
return profile;
},
});
configure.mjs
import { readFileSync, writeFileSync } from "node:fs";
const manifest = JSON.parse(readFileSync("touba.manifest.json", "utf8"));
manifest.bindings["tool:org.example.customer/FetchCustomerProfile"].handler.command = process.execPath;
writeFileSync("touba.manifest.json", JSON.stringify(manifest, null, 2));
prepare.mjs
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
export function prepare({ mode = "check", ownership = "touba.ownership.json", resources = "touba.resources.json", expected = 0 } = {}) {
const child = spawnSync("touba", ["prepare", "--source", "src/examples/customer_review_app.tb",
"--package", "packages/customer/touba.package.json", "--manifest", "touba.manifest.json",
"--resource-bindings", resources, "--require-resource-bindings", "--run-plan", "touba.run-plan.json",
"--entry", "strategy:examples.customer_review_app/RunCustomerReview", "--ownership", ownership,
"--require-ownership", "--profile", "prod", "--handler-command", process.execPath, "--mode", mode, "--json"], { encoding: "utf8" });
assert.equal(child.status, expected, child.stderr || child.stdout);
return JSON.parse(child.stdout);
}
if (process.argv.includes("--write")) console.log(JSON.stringify(prepare({ mode: "write" }), null, 2));
Terminal
node configure.mjs
node prepare.mjs --write

Preparation resolves the imports, preserves the completed handler and grants, and writes the profile-specific AIR and run plan. Ownership documents never grant runtime permissions. The synthetic credential below tests secret injection only; there is no external account or service.

Exercise the positive and negative paths​

The original generated lock remains pending until a separate, explicitly identified automated review records the admission checks. The pending version is preserved. This scripted review is not a human security approval. Real teams must provide their actual review evidence according to their release policy.

Each execution uses uniquely named locks, evidence and trigger state in the project directory. It does not overwrite a previous review. Keep the printed artifact prefix to inspect that attempt.

exercise.mjs
import assert from "node:assert/strict";
import { createHash, randomUUID } from "node:crypto";
import { readFileSync, writeFileSync } from "node:fs";
import { spawnSync } from "node:child_process";
import { TOUBA_SDK_METADATA } from "@touba/sdk";
import { prepare } from "./prepare.mjs";
const read = path => JSON.parse(readFileSync(path, "utf8"));
const write = (path, value) => writeFileSync(path, JSON.stringify(value, null, 2));
const attempt = `exercise-${randomUUID()}`;
const artifact = name => `${attempt}.${name}`;
const pendingPath = artifact("pending.lock.json");
const checkedPath = artifact("checked.lock.json");
console.log("Exercise artifacts:", attempt);
const ownership = read("touba.ownership.json");
for (const [name, mutate, code] of [
["missing-review", value => { value.reviews = []; }, "ReviewGateMissing"],
["missing-owner", value => { delete value.owners["run_plan:touba.run-plan"]; }, "OwnershipMissing"],
["unknown-reviewer", value => { value.reviews[0].reviewer = "team:unknown"; }, "ReviewReviewerUnknown"],
["rejected-review", value => { value.reviews[0].decision = "rejected"; }, "ReviewRejected"],
["authority", value => { value.grants = ["network"]; }, "OwnershipAuthorityFieldForbidden"],
]) {
const variant = structuredClone(ownership); mutate(variant); const path = name + ".ownership.json"; write(path, variant);
const report = prepare({ ownership: path, expected: 1 });
assert.ok(report.diagnostics.some(item => item.code === code), JSON.stringify(report));
}
const deniedResources = read("touba.resources.json");
deniedResources.resources["memory:org.example.customer/CustomerNotes"].grants = [];
write("denied.resources.json", deniedResources);
assert.ok(prepare({ resources: "denied.resources.json", expected: 1 }).diagnostics.some(item => item.code === "ResourceBindingGrantMissing"));
function cli(args, expected = 0) {
const child = spawnSync("touba", args, { encoding: "utf8", env: { ...process.env, CRM_API_TOKEN: "isolated-customer-credential" } });
assert.equal(child.status, expected, child.stderr || child.stdout);
assert.ok(!(child.stdout + child.stderr).includes("isolated-customer-credential"));
return JSON.parse(child.stdout);
}
cli(["supply-chain", "generate", "--air", ".touba/build/prod/air/examples/customer_review_app.air.json",
"--manifest", "touba.manifest.json", "--out", pendingPath, "--file", "customer-notes.json",
"--file", "vendor/touba-sdk.tgz", "--sdk-metadata-json", JSON.stringify(TOUBA_SDK_METADATA)]);
const pending = read(pendingPath);
assert.equal(pending.review.status, "pending");
const run = (expected, lockPath = checkedPath) => cli(["run", "--run-plan", "touba.run-plan.json", "--supply-chain-lock", lockPath, "--resource-bindings", "touba.resources.json",
"--require-resource-bindings", "--inputs-json", JSON.stringify({ request: { customer_id: "CUST-001" } }), "--output", "json"], expected);
assert.equal(run(1, pendingPath).status, "failure");
write(artifact("automated-review.json"), { scope: "tutorial ownership and resource admission checks", status: "passed", human_security_review: false });
const checked = structuredClone(pending);
checked.review = { status: "approved", reviewed_at: new Date().toISOString(),
reviewers: [{ kind: "tool", id: "tutorial:team-check", role: "isolated-contract-validation" }],
evidence: [{ kind: "validation_report", path: artifact("automated-review.json"), digest: { kind: "sha256",
value: createHash("sha256").update(readFileSync(artifact("automated-review.json"))).digest("hex") } }] };
write(checkedPath, checked);
const result = run(0);
assert.deepEqual(result.result, read("customer-notes.json")[0]);
for (const kind of ["tool_binding_authorized", "memory_access_authorized", "run_completed"])
assert.ok(result.trace.events.some(event => event.kind === kind));
const incomplete = structuredClone(checked); incomplete.handlers = [];
const incompletePath = artifact("incomplete.lock.json");
write(incompletePath, incomplete);
assert.equal(run(1, incompletePath).status, "failure");
const handler = "handlers/org/example/customer/fetch_customer_profile.handler.mjs";
const original = readFileSync(handler);
try {
writeFileSync(handler, Buffer.concat([original, Buffer.from("\n// isolated drift check\n")]));
const refused = run(1);
assert.ok(!refused.trace.events.some(event => event.kind === "tool_binding_authorized"));
} finally { writeFileSync(handler, original); }
write(artifact("run.result.json"), result);
console.log("TEAM_REVIEWS_RESOURCES_LOCK_AND_REAL_FILE_READ_OK");
Terminal
node exercise.mjs
# Run again: previous locks and evidence are preserved.
node exercise.mjs
touba inspect .touba/build/prod/air/examples/customer_review_app.air.json

Expected marker: TEAM_REVIEWS_RESOURCES_LOCK_AND_REAL_FILE_READ_OK. Inspect exercise-<id>.run.result.json for the result and trace. Missing reviews, owners, reviewers, resource grants and lock entries, rejected reviews, ownership authority fields and handler drift are refused. Imports only make declarations available: they do not authorize effects. This example provides neither SSO nor an OS sandbox.