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.
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
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
{
"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.
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_id": "CUST-001",
"segment": "enterprise",
"status": "review_ready"
}
]
{
"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
}
}
}
}
{
"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"
}
]
}
{
"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"
}
}
}
}
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;
},
});
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));
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));
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.
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");
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.