Internet-Draft Tool-Dispatch Finality August 2026
Das Expires 28 February 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-das-agentic-execution-finality-01
Published:
Intended Status:
Informational
Expires:
Author:
S. Das
Independent Inventor

Tool Selection Is Not Execution: Finality for Agentic Tool Dispatch

Abstract

An agentic model can emit a tool call that today's runtimes treat as something to execute. Allowlists, OAuth tokens, MCP server auth, sandboxes, output filters, and human approval decide whether an agent may reach a tool. They do not decide whether this generated call, with this argument digest, from this instruction chain, at this delegation depth, may take effect now.

That gap is the incident surface. Prompt-injected content, poisoned retrieval, a malicious tool response, or a delegated sub-agent can produce a call that looks like ordinary tool use. If the dispatcher executes whatever the model selected, policy that lived upstream becomes advisory.

This document specifies a dispatch-time gate. The model may compute a call. The call remains a Candidate Act. A Protected Enforcement Domain binds agent, tool, arguments, purpose, destination, provenance, and policy epochs, then issues scoped non-bearer authority. A Tool-Dispatch Finality Sink verifies that authority against the actual invocation immediately before the tool runs, then consumes it. The same gate applies to support, coding, payments, clinical, SOC, browser-use, and multi-agent MCP deployments. Tool selection is not execution authority.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 28 February 2027.

Table of Contents

1. Introduction

Agent runtimes now sit on a short path:

user or retrieved text
        -> model reasoning
        -> tool_call{name, arguments}
        -> runtime.dispatch()
        -> external effect

The third arrow is the one this document controls. The model is allowed to propose. The runtime is not allowed to treat the proposal as a capability. A proposed tool call, API request, browser action, shell command, message, file write, memory write, payment request, or agent delegation remains non-effective until act-specific authority is verified at the dispatch boundary.

This profile uses the two-boundary execution-finality chain also applied to AI-native networks [I-D.das-6g-finality] and precision-bounded egress [I-D.das-egress]. It specifies only the agent-dispatch predicates: tool and function identity, argument digest, instruction provenance, delegation depth, consequence class, and alternate-path closure across MCP, HTTP, browser, and shell.

2. Requirements Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Failure to establish current dispatch authority MUST NOT be converted into permission to invoke the tool.

3. Problem Space

Tool-using agents fail in a different place than chat models. A chat model that is tricked produces text. An agent that is tricked produces an invocation. The invocation may send mail, write memory, move money, open a browser, run a shell, or hand work to another agent. The model's next token is then an action.

The practical failures look like this:

In each case some upstream control was satisfied: the agent was authenticated, the tool was in the list, a token existed, or a human had approved "use tools" for the session. The missing question is the one asked at the sink: may this exact act become effective now.

4. Existing Solutions and What They Do Not Bind

Current stacks already contain important controls. This profile is designed to consume them, not to replace them.

4.1. Tool Allowlists and Function Schemas

Hosted tool-use interfaces expose a list of functions and JSON schemas to the model. That answers "which tools exist for this session." It does not bind a particular argument vector, destination, or instruction provenance. A model that is allowed bash and http.post can still emit the wrong one.

4.2. OAuth, API Keys, and MCP Server Authentication

Tokens establish that the runtime or user may call a server. MCP server authentication establishes that the dispatcher is talking to a named server. Possession of a token is bearer-like with respect to every call the token can make. It is not act-specific, single-use, or argument-bound unless the application adds that layer.

4.3. Sandboxes and Computer-Use Isolation

OS sandboxes, containers, and browser isolation reduce blast radius. They do not decide whether a permitted tool inside the sandbox should fire. A sandboxed agent that can send email can still send the wrong email.

4.4. Model-Level Safety and Output Filters

Constitutional or policy-trained refusal, classifiers, and tool-argument filters try to stop bad calls before dispatch. They are probabilistic. An attacker who wins the prompt still needs a second gate that does not trust the model. A filter that is uncertain MUST NOT be treated as ALLOW at the sink.

4.5. Human Approval and Session Consent

"Allow this agent to use tools" or a one-time confirm for a tool class is a session decision. It goes stale when parental policy, enterprise policy, destination, or delegation depth changes. It also does not hash arguments, so approval of a search is reused as approval of a transfer.

4.6. Policy Engines and Agent Frameworks

OPA-style engines, graph orchestrators, and guardrail middleware can deny a call. If the same effect can be reached by a second path — raw HTTP, a plugin, a shell pipe, another agent — a policy decision on the first path is not finality. A component is a Finality Sink only if bypassing it makes the effect technically non-completable.

4.7. What This Profile Adds

  • the tool call remains a Candidate Act after the model emits it;
  • arguments are bound by a canonical digest, so approved arguments cannot be swapped;
  • instruction provenance and delegation depth are predicates, not log fields;
  • authority is non-bearer, sink-bound, epoch-bound, and consumed;
  • the dispatcher verifies the live invocation, not the model's self-description;
  • uncertainty, timeout, and unknown destination fail closed or escalate; and
  • alternate invocation paths that can produce the same effect are in scope.

5. Industrial Relevance and Use Cases

The profile is meant to sit in a production dispatcher, not only in an architecture review. The cases below are the deployments where a model already has tools and where an allowlist is no longer the last control.

5.1. Customer Support and CRM

A support agent is allowed to read tickets, search a knowledge base, and draft replies. The same runtime often also has refund, credit, account-close, and data-export tools. Session consent says "this bot may use CRM tools." Prompt-injected ticket text or a retrieved policy PDF can cause the model to select refund.create or customer.export_pii.

The sink binds function_id, arguments_digest (amount, beneficiary, ticket id), consequence_class FINANCIAL or DATA_DISCLOSURE, and instruction provenance. A digest issued for refund.create at 12.00 MUST NOT authorize 1,200.00. Export of a whole address book remains non-effective when provenance is retrieval rather than an authenticated supervisor instruction.

5.2. Software Engineering and Production Change

Coding agents already call repo.read, test.run, pull_request.open, and, in some fleets, deploy or cloud.cli. Sandboxing the workspace does not distinguish "open a PR on a feature branch" from "apply this Terraform to prod." A poisoned README or CI log can instruct the agent to raise IAM privileges or disable an alert.

Consequence class PERSISTENT_STATE_CHANGE or NETWORK_CONTROL, destination (org/repo/account), and delegation_depth are the load-bearing fields. Authority for git.commit on branch feature/x MUST NOT authorize kubectl apply in another cluster. Computer-use agents that drive an IDE or a cloud console are the same profile with sink_type BROWSER_CONTROLLER or SHELL_GATEWAY.

5.3. Payments, Treasury, and Commerce

Checkout, payout, and bookkeeping agents hold tools that move value. PCI and bank APIs already authenticate the application. They do not hash the model's chosen recipient, amount, and memo. Indirect injection in an invoice PDF or a supplier email is enough to retarget a payment tool the agent was allowed to use.

The Candidate Act MUST carry consequence_class FINANCIAL, a destination recipient_id, and a single-use authority bound to the arguments digest. Replay of yesterday's payout authority, or reuse at a second payment sink, MUST fail. Human approval, where required, is an input to the PED, not a substitute for sink verification.

5.4. Clinical, Payer, and Life-Sciences Assistants

Scheduling and chart-summary agents need lookup tools. The same session must not silently acquire record.disclose, prescription.send, or research.export_cohort. Existing EHR OAuth scopes are session-wide. A retrieved clinical note that contains "forward this chart to the address below" is an instruction provenance problem, not an authentication problem.

DATA_DISCLOSURE acts SHOULD escalate when provenance is not user or clinician. Destination jurisdiction and recipient_id bind cross-border or consumer-app egress. This document does not define medical policy. It keeps unauthorized disclosure non-completable when that policy says no.

5.5. Security Operations and IT Administration

SOC and IT agents query SIEM, open tickets, isolate hosts, rotate credentials, and in some designs push firewall or identity changes. Speed is the reason they exist. The failure mode is an attacker-authored alert or ticket that the model treats as an instruction to disable_monitoring or add_allowlist_entry.

NETWORK_CONTROL and PERSISTENT_STATE_CHANGE calls SHOULD leave the hot path. The sink binds tool, destination system, and arguments digest so that isolate(host=A) cannot be substituted with isolate(host=controller). Delegation from a triage agent to an enrichment agent MUST NOT inherit containment-tool authority.

5.6. Email, Calendar, and Knowledge-Work Assistants

Mail-send, calendar-accept, drive-share, and memory-write tools are already shipped in consumer and enterprise assistants. "You may send email on my behalf" is a session grant. Injected calendar notes and retrieved threads are the classic indirect-prompt path to message.send or file.share with a new recipient.

COMMUNICATION and DATA_DISCLOSURE classes bind recipient_id and arguments digest. A draft authorized for to=alice@example.com MUST fail if the live call is to=attacker@example.net. Memory writes that persist injected instructions are themselves Candidate Acts of type MEMORY_WRITE; leaving them unconstrained trains the next turn's provenance failure.

5.7. Browser and Computer-Use Agents

Agents that click, type, and submit forms cross the same boundary as an API tool, except the effect is whatever the current page will accept. Site isolation and a visible browser do not bind "pay this merchant 40" versus "pay this merchant 4000," or prevent a page script from becoming an instruction.

The sink is BROWSER_CONTROLLER. Each consequential submission is a Candidate Act. Navigation to a new origin is a destination change and MUST invalidate authority issued for the previous origin. Accessibility and screenshot tools that can reconstruct secrets are DATA_DISCLOSURE acts, not INFORMATIONAL ones.

5.8. Contact Center, Voice, and Real-Time Tools

Voice agents invoke the same CRM and payment tools under a latency budget. The hot path in Section 13 exists for that reason. Cached envelopes MAY allow account.lookup and script.play. account.charge, number.port, and recording.export remain cold-path or human-gated classes. Timeout MUST NOT place the charge.

5.9. Multi-Agent Marketplaces and MCP Fleets

Enterprises are connecting many MCP servers and specialist agents. Discovery of a server, a tool name, or a marketplace card is not authority. A planner agent that may call search MUST NOT, by delegation, confer shell or payout tools on a worker. AGENT_DELEGATION is a Candidate Act. Depth, parent_agent_id, and permitted consequence class travel with the worker. MCP/server substitution (T7) is a sink-binding and endpoint-binding check, not a model check.

5.10. What Operators Should Measure

A deployment can treat the profile as live when these are true in production logs: (1) every high-risk tool invoke has a consumed authority_id; (2) argument-digest mismatches are denials, not retries that skip the sink; (3) delegation beyond policy.max_depth never reaches invoke(); (4) a second path (raw HTTP, shell, plugin) cannot complete the same effect without the same bindings. Those four tests are more useful than a slide that says the agent is "policy aligned."

6. Terminology

Agent Candidate Act
A model- or agent-generated operation that has been prepared as a tool call or equivalent but has not been permitted to execute.
Tool-Dispatch Finality Sink
The component that would actually invoke the tool, issue the HTTP request, start the browser action, exec the command, commit the write, or send the message. If that component can be skipped, it is not the sink.
Arguments digest
A hash over the canonical tool arguments. Changing any load-bearing argument MUST change the digest and invalidate previously issued authority.
Instruction provenance
Evidence about whether the act is attributable to a user or developer instruction versus retrieved text, tool output, memory, or another agent.
Delegation depth
The number of agent-to-agent hops from the initiating principal to the actor proposing the Candidate Act.

Candidate Act, Non-Effective State, Protected Enforcement Domain (PED), Protected Validation Evidence, scoped non-bearer finality authority, and Finality Sink are used as in [I-D.das-6g-finality].

7. Architecture

A Candidate Act MUST NOT become effective merely because the model selected a tool, the tool is in the allowlist, a token exists, or an upstream safety model returned ALLOW.

model emits tool_call(name, args)
              |
              v
     AGENT CANDIDATE ACT
              |
              v
        Non-Effective State
              |
              v
   Protected Enforcement Domain
      principal, agent, model
      tool, function, args digest
      purpose, destination
      instruction provenance
      delegation depth
      policy / revocation epochs
      intended dispatch sink
              |
              v
   evidence + scoped authority
              |
              v
   TOOL-DISPATCH FINALITY SINK
              |
      +-- PASS -> invoke once, consume authority
      |
      `-- FAIL -> tool is not invoked
Figure 1: Dispatch-time finality

8. Dispatch Pseudocode

The following procedures are normative in behavior, not in programming language. An implementation MAY collapse PED and sink into one protected service if both roles remain distinguishable: evidence is committed before authority is usable, and the invocation is checked immediately before effect.

8.1. Runtime: Model Output to Candidate Act

function ON_MODEL_TOOL_CALL(model_out, ctx):
    act = AgentCandidateAct{
        candidate_act_id: fresh_id(),
        act_type: map_act_type(model_out),
        agent: ctx.agent,
        tool: {id: model_out.name,
               function_id: model_out.name,
               endpoint: resolve(model_out.name),
               protocol: ctx.protocol},
        arguments_digest: HASH(canonicalize(model_out.arguments)),
        purpose: ctx.declared_purpose,
        destination: resolved_destination(model_out),
        consequence_class: classify(model_out.name),
        instruction_provenance: ctx.provenance,
        delegation_depth: ctx.depth,
        policy_state: current_epochs(),
        freshness: {nonce: fresh_nonce()},
        finality_sink: ctx.dispatch_sink,
        expires_at: now() + short_ttl
    }
    HOLD_NON_EFFECTIVE(act)
    return PED_VALIDATE(act, model_out.arguments)

8.2. PED Validation

function PED_VALIDATE(act, raw_args):
    if malformed(act):
        return DENY(MALFORMED_ACT)
    if not fresh(act.freshness.nonce):
        return DENY(REPLAY_OR_STALE)
    if act.policy_state != current_epochs():
        return DENY(EPOCH_MISMATCH)
    if not allowlisted(act.agent, act.tool):
        return DENY(TOOL_NOT_AUTHORIZED)
    if act.destination unknown or jurisdiction unresolved:
        return ESCALATE_OR_DENY(DESTINATION_UNRESOLVED)
    if act.delegation_depth > policy.max_depth:
        return DENY(DELEGATION_EXCEEDED)
    if provenance_untrusted(act) and
       act.consequence_class in HIGH_RISK:
        return ESCALATE_OR_DENY(INSTRUCTION_PROVENANCE_FAILURE)
    if args_exceed_schema(act.tool, raw_args):
        return DENY(SCOPE_MISMATCH)

    evidence = COMMIT_PROTECTED_EVIDENCE(act)
    authority = ISSUE_SCOPED_AUTHORITY(act, evidence)
    # act remains non-effective
    return ALLOW(authority)

8.3. Sink: Verify Then Invoke

function DISPATCH_SINK_INVOKE(act, authority, raw_args):
    live_digest = HASH(canonicalize(raw_args))

    if authority missing or integrity_fail(authority):
        return DENY(NO_OR_INVALID_AUTHORITY)
    if HASH(act) != authority.candidate_act_digest:
        return DENY(ACT_MISMATCH)
    if live_digest != act.arguments_digest:
        return DENY(ARGS_SUBSTITUTION)
    if authority.sink_id != THIS_SINK:
        return DENY(SINK_MISMATCH)
    if authority.tool_id != act.tool.id or
       authority.function_id != act.tool.function_id:
        return DENY(TOOL_SUBSTITUTION)
    if expired(authority) or consumed(authority):
        return DENY(STALE_OR_USED)
    if authority.epochs != current_epochs():
        return DENY(EPOCH_MISMATCH)
    if act.destination != authority.permitted_destination:
        return DENY(DESTINATION_MISMATCH)

    ATOMICALLY:
        consume(authority)
        advance_replay_state(act.freshness.nonce)
        result = invoke(act.tool, raw_args)
    record_sink_evidence(act, authority, result)
    return result

The required property is that invoke() is unreachable when any check fails. Logging a denial and then calling the tool is non-conforming.

9. Load-Bearing Bindings

Authority issued for maps.search / nearby / digest D1 MUST NOT authorize maps.search / nearby / digest D2, a different function on the same server, a shell action, or the same call at another sink. DISPLAY-equivalent mistakes in this profile are tool substitution and argument substitution.

An authority for TOOL_DISPATCH MUST NOT automatically authorize SHELL_GATEWAY or BROWSER_CONTROLLER. An authority for delegation_depth 0 MUST NOT automatically authorize depth 2. An authority created under revocation epoch N MUST fail when the protected state is at epoch N+1.

10. Prompt Injection and Delegation

The protocol does not require the model to detect injection. It requires that a consequential call influenced by retrieved text, tool output, memory, or another agent still cannot execute unless provenance and consequence-class predicates pass. Where provenance is UNKNOWN and the class is FINANCIAL, PERSISTENT_STATE_CHANGE, PHYSICAL, or NETWORK_CONTROL, the PED SHOULD escalate or deny rather than allow on the hot path.

Discovery of an MCP server, marketplace entry, or advertised tool MUST NOT by itself create dispatch authority. Delegation to a sub-agent is itself a Candidate Act of type AGENT_DELEGATION. Implementations SHOULD track cumulative depth, tool-call velocity, and consequence class across the chain and withhold further authority when the envelope is exceeded.

11. Alternate-Path Closure

If the same protected effect can be produced by MCP, a raw HTTP client, a browser controller, a shell, an IPC helper, or a memory/file write, each path MUST either enforce this profile or be unable to produce the effect. Moving the call from the tool dispatcher to curl MUST NOT remove the requirement.

12. JSON Interoperability Profile

Objects are UTF-8 JSON. A transport MAY be local IPC, an OS broker, HTTPS, or an MCP middleware hook. Transport MUST preserve integrity, sink identity, freshness, and non-bearer semantics. Implementations MUST reject unknown load-bearing fields when additionalProperties is false.

12.1. AgentCandidateAct

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "urn:ietf:params:json-schema:agent-finality:candidate-act:1",
  "title": "AgentCandidateAct",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "version", "object_type", "candidate_act_id", "act_type",
    "created_at", "expires_at", "initiating_principal", "agent",
    "tool", "purpose", "arguments_digest", "consequence_class",
    "policy_state", "freshness", "finality_sink"
  ],
  "properties": {
    "version": { "type": "string", "const": "1.0" },
    "object_type": {
      "type": "string",
      "const": "agent_candidate_act"
    },
    "candidate_act_id": {
      "type": "string",
      "minLength": 16,
      "maxLength": 128
    },
    "act_type": {
      "type": "string",
      "enum": [
        "TOOL_CALL", "FUNCTION_CALL", "API_REQUEST",
        "BROWSER_ACTION", "SHELL_ACTION", "MESSAGE_SEND",
        "FILE_WRITE", "MEMORY_WRITE", "AGENT_DELEGATION",
        "PAYMENT_REQUEST", "OTHER"
      ]
    },
    "created_at": { "type": "string", "format": "date-time" },
    "expires_at": { "type": "string", "format": "date-time" },
    "initiating_principal": {
      "type": "object",
      "required": ["principal_id", "principal_type"],
      "properties": {
        "principal_id": { "type": "string" },
        "principal_type": {
          "type": "string",
          "enum": ["user", "service", "enterprise", "device", "agent"]
        },
        "authorization_context_id": { "type": "string" }
      }
    },
    "agent": {
      "type": "object",
      "required": ["agent_id", "runtime_id"],
      "properties": {
        "agent_id": { "type": "string" },
        "runtime_id": { "type": "string" },
        "model_id": { "type": "string" },
        "model_version": { "type": "string" },
        "alf_digest": { "type": "string" },
        "delegation_depth": { "type": "integer", "minimum": 0 },
        "parent_agent_id": { "type": "string" }
      }
    },
    "tool": {
      "type": "object",
      "required": ["tool_id", "function_id"],
      "properties": {
        "tool_id": { "type": "string" },
        "function_id": { "type": "string" },
        "tool_endpoint": { "type": "string" },
        "tool_protocol": {
          "type": "string",
          "enum": [
            "MCP", "HTTP_API", "LOCAL_FUNCTION",
            "BROWSER", "SHELL", "A2A", "OTHER"
          ]
        }
      }
    },
    "purpose": {
      "type": "object",
      "required": ["purpose_id", "declared_purpose"],
      "properties": {
        "purpose_id": { "type": "string" },
        "declared_purpose": { "type": "string" },
        "user_intent_reference": { "type": "string" },
        "purpose_epoch": { "type": "integer", "minimum": 0 }
      }
    },
    "arguments_digest": {
      "type": "object",
      "required": ["algorithm", "value", "canonicalization"],
      "properties": {
        "algorithm": {
          "type": "string",
          "enum": ["SHA-256", "SHA-384", "SHA-512"]
        },
        "value": { "type": "string" },
        "canonicalization": {
          "type": "string",
          "enum": ["JCS", "implementation-defined"]
        }
      }
    },
    "destination": {
      "type": "object",
      "properties": {
        "destination_id": { "type": "string" },
        "endpoint": { "type": "string" },
        "jurisdiction": { "type": "string" },
        "recipient_id": { "type": "string" }
      }
    },
    "consequence_class": {
      "type": "string",
      "enum": [
        "INFORMATIONAL", "DATA_DISCLOSURE",
        "PERSISTENT_STATE_CHANGE", "FINANCIAL",
        "NETWORK_CONTROL", "PHYSICAL", "COMMUNICATION", "OTHER"
      ]
    },
    "policy_state": {
      "type": "object",
      "required": ["policy_epoch", "authority_epoch", "revocation_epoch"],
      "properties": {
        "policy_epoch": { "type": "integer", "minimum": 0 },
        "authority_epoch": { "type": "integer", "minimum": 0 },
        "revocation_epoch": { "type": "integer", "minimum": 0 },
        "policy_profile_id": { "type": "string" }
      }
    },
    "freshness": {
      "type": "object",
      "required": ["nonce"],
      "properties": {
        "nonce": { "type": "string", "minLength": 16 },
        "sequence": { "type": "integer", "minimum": 0 },
        "session_id": { "type": "string" }
      }
    },
    "instruction_provenance": {
      "type": "object",
      "properties": {
        "instruction_digest": { "type": "string" },
        "source_type": {
          "type": "string",
          "enum": [
            "user", "system", "developer", "tool",
            "retrieval", "memory", "agent"
          ]
        },
        "trusted_chain_digest": { "type": "string" }
      }
    },
    "finality_sink": {
      "type": "object",
      "required": ["sink_id", "sink_type"],
      "properties": {
        "sink_id": { "type": "string" },
        "sink_type": {
          "type": "string",
          "enum": [
            "TOOL_DISPATCH", "API_GATEWAY", "BROWSER_CONTROLLER",
            "SHELL_GATEWAY", "MESSAGE_GATEWAY", "FILE_COMMIT",
            "MEMORY_COMMIT", "OTHER"
          ]
        }
      }
    }
  }
}

12.2. Evidence, Authority, and Sink Verify

{
  "version": "1.0",
  "object_type": "protected_validation_evidence",
  "evidence_id": "pve-6d6ddc91",
  "candidate_act_id": "act-7f39b8b8",
  "decision": "ALLOW",
  "validated_predicates": {
    "principal_authorized": true,
    "agent_identity_valid": true,
    "tool_scope_valid": true,
    "purpose_valid": true,
    "instruction_provenance_valid": true,
    "destination_valid": true,
    "policy_epoch_valid": true,
    "revocation_state_valid": true,
    "freshness_valid": true,
    "sink_binding_valid": true
  },
  "protected_state": {
    "state_reference": "ped-state-901",
    "monotonic_counter": 8481
  },
  "issued_at": "2026-08-26T17:40:01Z",
  "protector": {
    "type": "TEE_SIGNATURE",
    "key_id": "ped-key-12",
    "signature": "base64url-signature"
  }
}
{
  "version": "1.0",
  "object_type": "agent_finality_authority",
  "authority_id": "afa-c7d32d54",
  "candidate_act_id": "act-7f39b8b8",
  "evidence_id": "pve-6d6ddc91",
  "scope": {
    "act_type": "TOOL_CALL",
    "tool_id": "maps.search",
    "function_id": "nearby",
    "permitted_destination": "tool.example",
    "permitted_consequence_class": "DATA_DISCLOSURE"
  },
  "binding": {
    "candidate_act_digest": {
      "algorithm": "SHA-256",
      "value": "base64url-act-digest"
    },
    "nonce": "A81D4F42B779CC21",
    "policy_epoch": 42,
    "revocation_epoch": 7,
    "finality_sink_id": "dispatch-sink-01"
  },
  "lifetime": {
    "issued_at": "2026-08-26T17:40:01Z",
    "expires_at": "2026-08-26T17:40:10Z",
    "single_use": true
  },
  "issuer": {
    "ped_id": "ped-runtime-01",
    "key_id": "ped-key-12",
    "signature": "base64url-signature"
  }
}
{
  "operation": "DispatchSinkVerify",
  "request_id": "req-10aa19",
  "decision": "ALLOW",
  "verification": {
    "authority_signature": "VALID",
    "candidate_act_binding": "MATCH",
    "tool_scope": "MATCH",
    "args_digest": "MATCH",
    "destination": "MATCH",
    "nonce": "FRESH",
    "policy_epoch": "CURRENT",
    "revocation_epoch": "CURRENT",
    "consumption_state": "UNUSED",
    "sink_binding": "MATCH"
  },
  "consumption": {
    "authority_id": "afa-c7d32d54",
    "status": "CONSUMED"
  },
  "effectuation": { "permitted": true, "effect_id": "effect-bf3b5a" }
}
{
  "operation": "DispatchSinkVerify",
  "request_id": "req-10ab00",
  "decision": "DENY",
  "error": {
    "code": "EF_SCOPE_MISMATCH",
    "message": "Requested function is outside authorized tool scope.",
    "retryable": false
  },
  "effectuation": { "permitted": false }
}

12.3. Complete Transaction

{
  "step_1_model": {
    "emitted": "maps.search.nearby",
    "status": "NON_EFFECTIVE"
  },
  "step_2_candidate_act": {
    "candidate_act_id": "act-7f39b8b8",
    "act_type": "TOOL_CALL",
    "agent": {
      "agent_id": "assistant-23",
      "model_id": "model-X",
      "delegation_depth": 0
    },
    "tool": {
      "tool_id": "maps.search",
      "function_id": "nearby",
      "tool_protocol": "MCP"
    },
    "purpose": {
      "purpose_id": "nearby-service-discovery",
      "declared_purpose": "Find nearby pharmacies"
    },
    "arguments_digest": {
      "algorithm": "SHA-256",
      "value": "base64url-args-digest",
      "canonicalization": "JCS"
    },
    "destination": { "destination_id": "tool.example", "jurisdiction": "IN" },
    "consequence_class": "DATA_DISCLOSURE",
    "instruction_provenance": { "source_type": "user" },
    "finality_sink": {
      "sink_id": "dispatch-sink-01",
      "sink_type": "TOOL_DISPATCH"
    }
  },
  "step_3_authority": { "authority_id": "afa-c7d32d54", "single_use": true },
  "step_4_sink": { "decision": "ALLOW", "authority_consumed": true },
  "step_5_effect": "maps.search.nearby invoked once with digest-bound args"
}

13. Hot Path, Escalation, and Failure

Repeated calls inside a fixed envelope — same agent, tool, function, destination, consequence class, and provenance class — MAY use cached policy and short-lived authority. The sink check is still mandatory. New tools, unknown destinations, depth increases, FINANCIAL or PHYSICAL class, provenance UNKNOWN, or runtime anomaly SHOULD escalate. Timeout is not ALLOW.

Illustrative codes, not IANA assignments: EF-002 NO_FINALITY_AUTHORITY, EF-005 AUTHORITY_ALREADY_USED, EF-006 REPLAY_DETECTED, EF-012 SCOPE_MISMATCH, EF-013 PURPOSE_MISMATCH, EF-020 DESTINATION_MISMATCH, EF-040 SINK_MISMATCH, EF-053 INSTRUCTION_PROVENANCE_FAILURE, EF-070 ESCALATION_REQUIRED, EF-080 FAIL_CLOSED.

14. Security Considerations

Threats the sink is intended to make non-completable without current authority include: T1 direct prompt injection, T2 indirect prompt injection, T3 poisoned retrieval, T4 poisoned memory, T5 malicious tool response, T6 tool substitution, T7 MCP/server substitution, T8 unauthorized delegation, T9 recursive escalation, T10 stale user authority, T11 destination substitution, T14 authority replay, T15 cross-sink reuse, and T17 alternate-path effectuation.

The model is not trusted to police these. The property is mechanical: invoke() does not run. Residual risk remains if an unclassified generated argument string is itself a program the tool will interpret, or if a path around the sink exists. Implementations MUST treat those as profile failures, not as acceptable best-effort modes.

15. Privacy Considerations

Candidate Act descriptors can reveal user intent, tool choice, and destination. Implementations SHOULD hash or seal raw arguments and prompts on untrusted paths and SHOULD NOT log full tool arguments when the digest is sufficient for verification.

16. IANA Considerations

This document requests no IANA actions.

17. Intellectual Property Note

Certain concepts are associated with pending applications in the DAS Protocols family, including PCT/IB2026/054453, PCT/IB2026/055615, PCT/IB2026/055760, PCT/IB2026/055870, PCT/IB2026/056058, and PCT/IB2026/053385. IETF disclosure should follow BCP 79 [RFC8179].

18. Conclusion

The model may select a tool. That selection is computation. External execution starts only after the Candidate Act is validated, evidence is committed, scoped authority is issued, and the dispatch sink verifies the live invocation. Tool selection is not execution authority.

19. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8179]
Bradner, S. and J. Contreras, "Intellectual Property Rights in IETF Technology", BCP 79, RFC 8179, , <https://www.rfc-editor.org/info/rfc8179>.

20. Informative References

[I-D.das-6g-finality]
Das, S., "Execution-Finality for AI-Native 5G/6G and O-RAN", Work in Progress, Internet-Draft, draft-das-ai-native-6g-execution-finality-01, , <https://datatracker.ietf.org/doc/html/draft-das-ai-native-6g-execution-finality-01>.
[I-D.das-egress]
Das, S., "Access Is Not Egress: Precision-Bounded Location Release", Work in Progress, Internet-Draft, draft-das-precision-bounded-egress-01, , <https://datatracker.ietf.org/doc/html/draft-das-precision-bounded-egress-01>.

Author's Address

Sangam Das
Independent Inventor
Balasore 756001
Odisha
India