Cryptographic attestation for AI agent harness decisions. Orchestration, delegation, context management, sandbox enforcement, and eval gates.
Platform engineers, AI infrastructure teams, agent framework developers, GRC analysts mapping agentic AI controls.
An AI harness is the scaffolding around a foundation model: the orchestration loop, tool permissions, memory management, sandboxing, and guardrails that turn a raw LLM into a production agent. In 2026, harnesses are infrastructure -- Gartner projects 40% of enterprise applications will include task-specific AI agents by year-end.
The governance gap: harnesses make consequential decisions -- which routing topology, which agent gets which permissions, what context gets dropped, whether tools stayed in scope, whether evals passed -- but none of these decisions produce audit evidence. Agent frameworks govern agent logic and routing, but they cannot certify their own governance decisions.
SWT3 already covers ~70% of harness concerns through existing procedures: tool calls (AI-TOOL.1), agent identity (AI-ID.1), access control (AI-ACC.1), MCP security (AI-MCP.1-4). Five new procedures close the remaining 30% for the harness layer itself.
| Procedure | Title | What It Witnesses | Verdict Logic |
|---|---|---|---|
AI-ORCH.1 |
Orchestration Topology | Routing pattern selection (sequential, parallel, hierarchical, hybrid, mesh) | Informational (always PASS) |
AI-ORCH.2 |
Inter-Agent Handoff | Identity linkage when one agent delegates to another | PASS when delegator identity recorded |
AI-CTX.1 |
Context Window Management | Truncation, summarization, or eviction of context | PASS when tokens_after ≤ tokens_before |
AI-SAND.1 |
Sandbox Enforcement | Tool restriction compliance (self-reported) | PASS when violations = 0 |
AI-GATE.1 |
Eval Gate Decision | Pass/fail deployment gating from eval results | PASS when gate_score ≥ 70 |
When a harness selects a routing pattern for a multi-agent task, that decision shapes execution flow, latency, failure modes, and cost. Sequential pipelines have different risk profiles than parallel fan-outs or hierarchical delegation trees. Recording the topology choice creates an audit trail for incident investigation and capacity planning.
| Factor | Label | Description |
|---|---|---|
fa | topology_code | 0=sequential, 1=parallel, 2=hierarchical, 3=hybrid, 4=mesh |
fb | agent_count | Number of agents participating in the topology |
fc | dependency_depth | Maximum depth of the task dependency graph |
Pythonwitness.witness_orchestration_topology(
"parallel",
agent_count=3,
dependency_depth=2
)
TypeScriptwitness.witnessOrchestrationTopology({
topology: "parallel",
agentCount: 3,
dependencyDepth: 2,
});
Gow.WitnessOrchestrationTopology(swt3.TopoParallel, 3, 2)
MCP Toolwitness_orchestration_topology
topology: "parallel"
agent_count: 3
dependency_depth: 2
When one agent delegates work to another, the permission boundary may change. An orchestrator handing off to an executor might escalate permissions (granting tool access the orchestrator did not have) or restrict them (limiting scope to a specific task). The handoff itself is an accountability event -- who delegated to whom, and did the boundary expand or contract?
Agent identifiers are SHA-256 hashed before encoding into factors. Raw IDs never leave the SDK.
| Factor | Label | Description |
|---|---|---|
fa | delegator_hash | SHA-256[:8] of delegating agent ID, parsed to uint32 |
fb | delegate_hash | SHA-256[:8] of receiving agent ID, parsed to uint32 |
fc | permission_delta | 1=escalation, 0=lateral, -1=restriction (clamped) |
Python# Escalation: executor gets more permissions than planner
witness.witness_agent_handoff(
"planner-agent",
"executor-agent",
permission_delta=1
)
# Restriction: reviewer gets read-only scope
witness.witness_agent_handoff(
"executor-agent",
"reviewer-agent",
permission_delta=-1
)
TypeScriptwitness.witnessAgentHandoff({
delegatorId: "planner-agent",
delegateId: "executor-agent",
permissionDelta: 1, // escalation
});
Gow.WitnessAgentHandoff("planner-agent", "executor-agent", 1)
When a harness truncates, summarizes, or evicts context, the model loses information. That loss is invisible to the model, the user, and any downstream auditor unless explicitly recorded. Context eviction decisions directly affect output quality, safety, and compliance -- a truncated system prompt may remove safety instructions, a summarized conversation may lose consent signals.
| Factor | Label | Description |
|---|---|---|
fa | tokens_before | Token count before the management event |
fb | tokens_after | Token count after the management event |
fc | eviction_method | 0=none, 1=truncation, 2=summarization, 3=sliding_window, 4=priority_eviction |
Pythonwitness.witness_context_window(
tokens_before=128000,
tokens_after=32000,
eviction_method="summarization"
)
TypeScriptwitness.witnessContextWindow({
tokensBefore: 128000,
tokensAfter: 32000,
evictionMethod: "summarization",
});
Gow.WitnessContextWindow(128000, 32000, swt3.EvictionSummarization)
Harnesses declare which tools an agent may invoke (the sandbox allow-list), then report whether the agent stayed within scope. This procedure witnesses that report. It is explicitly self-attested: the harness reports its own compliance, not an external verifier.
| Factor | Label | Description |
|---|---|---|
fa | tools_declared | Number of tools in the sandbox allow-list |
fb | tools_invoked | Number of distinct tools actually invoked |
fc | violations | Count of out-of-scope invocations. 0 = clean. |
Python# Clean session: all tool calls within declared sandbox
witness.witness_sandbox_enforcement(
tools_declared=10,
tools_invoked=5,
violations=0
)
# Violation detected: 2 out-of-scope tool calls
witness.witness_sandbox_enforcement(
tools_declared=10,
tools_invoked=7,
violations=2
)
TypeScriptwitness.witnessSandboxEnforcement({
toolsDeclared: 10,
toolsInvoked: 5,
violations: 0,
});
Eval gates are the checkpoint between "model passed testing" and "model enters production." The gate decision -- pass or fail, with what score, based on how many evals -- is a compliance event. Recording it creates evidence for model governance audits and post-incident investigations.
The gate score is auto-computed from evals_passed / total_evals * 100 when not explicitly provided. The verdict threshold is 70.
| Factor | Label | Description |
|---|---|---|
fa | total_evals | Total evaluation checks executed in the gate |
fb | evals_passed | Number of checks that passed |
fc | gate_score | 0-100, auto-computed when omitted |
Python# Auto-computed score: 85/100 = 85 -> PASS
witness.witness_eval_gate(total_evals=100, evals_passed=85)
# Explicit score override
witness.witness_eval_gate(total_evals=100, evals_passed=85, gate_score=90)
TypeScriptwitness.witnessEvalGate({
totalEvals: 100,
evalsPassed: 85,
// gateScore auto-computed: 85
});
Go// Pass -1 as gateScore to auto-compute
w.WitnessEvalGate(100, 85, -1)
| Procedure | NIST AI RMF | EU AI Act | NIST 800-53 | OWASP Agentic | ISO 42001 |
|---|---|---|---|---|---|
AI-ORCH.1 |
GOVERN 1.3 | Art. 9 | -- | A07 | A.8.5 |
AI-ORCH.2 |
GOVERN 1.3 | Art. 9 | -- | -- | A.8.5 |
AI-CTX.1 |
MEASURE 2.6 | Art. 13 | -- | -- | A.7.4 |
AI-SAND.1 |
GOVERN 1.7 | Art. 15 | SA-11(8) | A03 | -- |
AI-GATE.1 |
MEASURE 2.5 | Art. 9(7) | SA-11 | -- | A.6.2.3 |
All five procedures follow the standard SWT3 clearing engine rules:
| Level | Name | What Survives |
|---|---|---|
| 0 | Analytics | Factors + ai_model_id + ai_context (topology name, token counts, tool counts, agent hashes) |
| 1 | Standard | Same as Level 0 (default) |
| 2 | Sensitive | Factors + ai_model_id only. ai_context stripped entirely. |
| 3 | Classified | Factors only. ai_model_id hashed. No metadata. |
Agent hashes in AI-ORCH.2 are SHA-256 truncated before encoding into factors -- raw agent identifiers never leave the SDK at any clearing level.
Both procedures involve multi-agent delegation. They are complementary, not overlapping:
| AI-MULTI.1 (v0.6.3) | AI-ORCH.2 (v0.7.2) | |
|---|---|---|
| Records | Permission manifest: what was delegated | Identity handoff: who to whom, with what delta |
| Factors | fa=permission_count, fb=time_bound, fc=depth | fa=delegator_hash, fb=delegate_hash, fc=permission_delta |
| Question | What capabilities were shared? | Did the boundary expand or contract? |
Use AI-MULTI.1 when you need to record the full permission envelope. Use AI-ORCH.2 when you need to record the handoff event with identity linkage and escalation direction.
Eight attack surfaces were analyzed during the design of these procedures:
| Attack | Surface | Status |
|---|---|---|
| Topology code overflow (fa=999) | AI-ORCH.1 | Accepted. String-to-code lookup defaults unknown values to 0. |
| Delegation chain forgery | AI-ORCH.2 | Accepted. IDs are SHA-256 hashed before encoding. Forgery requires the signing key. |
| Context count spoofing | AI-CTX.1 | Accepted. Honest-majority assumption. Eval catches impossible case (after > before). |
| Sandbox false attestation | AI-SAND.1 | Accepted with documentation. SDK docstrings note self-reported nature. Cross-reference AI-TOOL.1. |
| Gate score inflation | AI-GATE.1 | Mitigated. Auto-compute from fa/fb when not explicitly provided. |
| Permission delta out of range | AI-ORCH.2 | Mitigated. Factor clamped to [-1, 0, 1]. |
| Clearing level leakage | All 5 | Clean. Hashes (not raw IDs) in context. No tool names in SAND.1. Context stripped at level 2+. |
| Cross-SDK parity divergence | All 5 | Mitigated. 5 test vectors enforce fingerprint parity across Python, TypeScript, and Go. |
Call witness_orchestration_topology() when the graph router selects a branch. Call witness_context_window() in your ConversationSummaryBufferMemory callback.
Call witness_agent_handoff() in your task delegation callback. The permission_delta maps to whether the delegated agent has the same, expanded, or restricted tool set compared to the delegating crew member.
Call witness_orchestration_topology() when configuring the GroupChat pattern (round_robin=sequential, selector=hierarchical). Call witness_sandbox_enforcement() after the conversation completes, reporting the code executor's tool usage against the declared allow-list.
Call witness_eval_gate() from your CI pipeline after eval harness runs (Promptfoo, DeepEval, lm-evaluation-harness). The gate score maps directly to the eval pass rate. Use cycle_id to link the eval gate anchor to the deployment commit hash.
For custom orchestration loops, call each procedure at the natural event boundary: topology selection at loop initialization, handoff at delegation points, context management after truncation, sandbox after session completion, eval gate after test runs.