Context and tool delivery
Implemented under ADR 006. A tool is a versioned function contract carried by the same immutable release as its context. Workstation Design → Tools edits the catalogue; profile inclusion is explicit and defaults to no disclosure. Preview uses labelled synthetic fixtures. Tests protect inclusion, exclusion, argument validation, approval and call limits without executing actions.
Deliver a customer package
Use reference/agent-tools/context-project.json as a portable, editable reference. It has separate learner and authoring objectives: the learner cannot receive the proposal tool; authoring requires exact operator approval before a write.
runtime/node runtime/engine/context.mjs validate --project reference/agent-tools/context-project.json
runtime/node scripts/prove-context-tools.mjs --output evidence/context-tools-delivery.json --keep
The proof produces an immutable Build and a self-contained Runtime bundle in its printed delivery directory. It starts the exported Runtime from outside the repository using its bundled Node, exercises authenticated HTTP executors and the public SDK, verifies a write approval, suppresses duplicate dispatch, reproduces selection without calling the executor, and blocks a candidate that removes its forbidden-tool tests. All application/model data is synthetic. Setup effort, answer quality improvement and saved labor remain unmeasured.
A commercial handoff consists of the customer-owned Project/source repository, a verified Build and Runtime bundle, synthetic regression corpus, binding template and acceptance evidence. Operational data, credential values and Runtime data directories do not belong in Git. Git retains the authoring source; Build identity is the immutable release coordinate.
Project declarations
tools[] contains id, function name, semantic version, description, object parameters, optional result, effect (read/write), approval (none/required), maxCalls (1–20; defaults to 3 for reads and 1 for writes) and timeoutMs (100–30000). Writes always require approval. The engine recomputes contractDigest from id, name, version, arguments and result schema. Profile toolRules[] contains {tool, participation: include|exclude, required}. Excluded tools cannot be required.
Only a bounded JSON Schema subset ships: explicit object/array/string/integer/number/boolean/null types; properties, required, boolean additionalProperties, items, enum, const, min/max length, items and numeric values, description and title. Object properties default closed. Eight nesting levels, 32 properties per object and 32 tools/64 KiB per catalogue. $ref, unions, regex patterns, composition and other unsupported keywords fail explicitly. This is not a full JSON Schema implementation.
toolFixtures maps tool ids to {state: READY, version, contractDigest} or {state: UNAVAILABLE}. Native Use current contract fixtures explicitly generates the current descriptor for the selected test; it does not assert that a production executor implements it. expect.tools supplies include/exclude ids and calls {tool, arguments, expect: ALLOW|DENY, approved?, reason?}. approved is a synthetic test fact only; Runtime requests cannot approve themselves with a boolean. Existing baseline tests and reviewed guards remain promotion obligations. Context and tool metrics have separate denominators.
Tool-free Projects/Builds retain v1 digests. Tool Builds require seif.context-runtime.v2; previous runtimes reject them. Build registration re-verifies artifact bytes and reruns tests. Supported tool contracts, executor transport and native integrations are explicitly inventoried in /v1/capabilities.
Bind an executor
{
"tools": {
"inspect-context": {
"endpoint": "https://backend.example/seif-tools/inspect-context",
"secretRef": "env:CONTEXT_TOOL_INSPECT_TOKEN",
"timeoutMs": 5000,
"maxBytes": 65536
}
}
}
Bindings are environment revisions. Tool credentials use the existing reference allowlist (env:CONTEXT_TOOL_*, keychain:context-tool-*); Registry credentials are refused. Remote endpoints require HTTPS and an external credential; loopback HTTP is for fixtures. Redirects, arbitrary request destinations and credential reflection are refused. The Runtime injects only explicitly bound secrets into its runner. No credential is compiled into a Build.
An executor implements authenticated GET {endpoint}/describe:
{"contract":"context-tool-executor.v1","tool":{"id":"inspect-context","version":"1.0.0","contractDigest":"sha256:…"}}
and POST {endpoint}/execute. Requests carry the exact contract/version, arguments, callId, an idempotency key and context coordinates (Build, consumer, objective, environment, deployment, trace and context). Responses explicitly return {contract: "context-tool-executor.v1", ok: true, output} or ok: false. Optional result schemas are validated. The backend enforces authorization using its own trusted application state; a model-supplied identifier, tool description or trace is not a permission. The synthetic executor in examples/reference-tools/executor.mjs demonstrates this transport and performs no real business writes.
Readiness verifies the descriptor. Every resolve refreshes observations, and execute probes compatibility again before dispatch. Required unavailable/incompatible tools block resolution. Optional unavailable tools are omitted. Returned tools[] supplies the model-facing schemas; their estimated size shares the same token ceiling as context messages. Count remains an estimate unless independently measured.
Integrate the application
The TypeScript SDK runAgentTurn and Python run_agent_turn hand the application messages, function schemas and an execution callback. The application supplies its model loop and reports an external outcome only when it has one. For HTTP-only applications that need an enforced context-delivery boundary, use HTTP turn observation: the application, not the model, starts the turn, supplies the server-issued turn id on context calls and reports technical completion. For an existing composer, ContextDeliveryGateway.forwardAgent preserves the complete canonical context while instrumenting both messages and tools. Existing context-only helpers refuse tool Builds rather than silently dropping their tools.
const delivery = await client.runAgentTurn(request, async ({messages, tools, execute}) => {
// Bind these exact schemas to the existing model/framework.
const call = await existingAgent.choose(messages, tools);
const receipt = await execute(call.name, call.id, call.arguments);
// Inspect UNKNOWN/FAILED, duplicate and outputAvailable before continuing.
return existingAgent.finish(receipt);
});
reportDisclosure correlates the exact context contribution and function schemas with the trace. It is an application report, not independent proof of model processing. Telemetry failures preserve successful results with explicit reporting errors. Tool execution is never retried automatically. Caller cancellation after dispatch does not prove that the backend action was cancelled; inspect the receipt or reconcile with the backend. A SDK receipt is not a claim of agent intelligence or successful customer business outcomes.
Approval, execution and uncertainty
Application credentials need explicitly granted tools.execute; they cannot hold tools.approve. Managed approval uses a human credential at …/context/tools/approve (or …/runtime/v1/context/tools/approve). The Registry supplies the authenticated approver and a separate runner approval credential. Standalone Runtime uses SEIF_CONTEXT_TOOL_APPROVAL_TOKEN, distinct from its bearer token, in x-seif-tool-approval.
Approve the exact contextRef, tool, callId and arguments with a reason; then pass approvalId to execute. Approvals last five minutes. Tool contexts last fifteen minutes; new calls and approvals after expiry fail closed. A changed argument, tool or context cannot reuse approval. Application/backend authorization is still checked at execution.
Dispatch intent is persisted before network I/O. Concurrent/repeated call ids dispatch once within the retained context. Changed arguments conflict. Duplicate receipts do not return raw output or repeat effects; outputAvailable is false. Lost/interrupted/invalid responses and a prior intent without a completed receipt are UNKNOWN. Operator reconciliation and a backend business idempotency store are necessary for durable real-world effects. This mechanism does not provide exactly-once execution or distributed transactions. Separate Runtime data cannot share deduplication; concurrent processes using one tool data directory are refused, and a dead same-host owner can be reclaimed.
Raw arguments, outputs and approval reasons are not retained by this gateway. Persistent fingerprints are keyed with the binding trace key or a local private Runtime key. Context/source retention remains independently configured. Traces distinguish runtime disclosure, application-reported schemas, denials, dispatch intent, approval and executor-reported results. Replay re-evaluates historical context/tool disclosure from the Build and retained availability observations; it never calls a tool executor.
Framework interoperability
The supported boundary is HTTP/JSON and provider-neutral function schemas. An n8n HTTP Request node can call resolve/execute with scoped credentials; a LangChain tool callback can call executeToolByName. Adapters must preserve contextRef, deploymentId and the original call id, handle UNKNOWN explicitly, and keep approval in an operator-controlled workflow. Native n8n nodes and LangChain packages are future integrations, not shipped integrations. n8n HTTP Request and LangChain tools document their composition boundaries.
Guided tool setup
Open Design → Tools to customize a record-lookup, knowledge-search or ticket-creation contract, or create a custom tool. Edit arguments through fields or JSON Schema; profile inclusion remains explicit. Cards display the full affected audience, scenario protection and environment connection separately. Protect audience in all scenarios creates synthetic compatibility and disclosure guards for each scenario. Validate a call checks availability, arguments and simulated approval without dispatching a business action.
Use Get a runnable executor starter for a Node.js adapter carrying the exact contract digest. Implement its business handler and authorization in your service; the placeholder reports failure. Prepare release & connect saves, builds and registers the reviewed design, then opens the guided binding form. This prepares configuration without promotion or deployment. A saved URL is labelled as configured; deployment verifies executor readiness. Experience and executed proofs.