<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<rfc category="info" docName="draft-das-agentic-tool-binding-03"
     ipr="trust200902" submissionType="IETF" xml:lang="en" version="3"
     tocInclude="true" tocDepth="3" symRefs="true" sortRefs="true">
  <front>
    <title abbrev="Tool-Use Binding">tool_use Is Not invoke(): Binding Execution-Finality to Agentic Tool-Call Interfaces and MCP</title>
    <seriesInfo name="Internet-Draft" value="draft-das-agentic-tool-binding-03"/>
    <author fullname="Sangam Das" initials="S." surname="Das">
      <organization>Independent Inventor</organization>
      <address>
        <postal>
          <city>Balasore</city>
          <region>Odisha</region>
          <code>756001</code>
          <country>India</country>
        </postal>
        <email>info@sangamdas.com</email>
      </address>
    </author>
    <date year="2026" month="September" day="5"/>
    <area>Security</area>
    <keyword>MCP</keyword>
    <keyword>Anthropic</keyword>
    <keyword>OpenAI</keyword>
    <keyword>tool use</keyword>
    <keyword>execution finality</keyword>
    <abstract>
      <t>Frontier runtimes already standardized the dangerous
      moment. A model emits a tool_use block, a tool_calls
      array, or an MCP tools/call payload. The host then
      invokes whatever name and arguments the model printed.
      Alignment, allowlists, and OAuth sit around that
      moment. They do not sit on it.</t>
      <t>The consequence of this gap is no longer confined to
      email or payment demos. In defense, energy, grid
      control, industrial process control, and other
      critical-infrastructure deployments, the same tool_use
      block already reaches actuation-class systems --
      logistics and targeting-adjacent decision support,
      SCADA and PLC interfaces, medical devices, autonomous
      platforms. In these environments, detection after the
      fact is not mitigation; it is an incident report written
      after the effect has already occurred. An agent that can
      act at machine speed but cannot be halted at machine
      speed is a system running without brakes: the first
      uncontrolled invocation is not a warning sign, it is the
      accident. Command authority, human oversight, and legal
      review all operate on human time. An unbound tool_use
      block operates on machine time. When those two clocks
      diverge, the gap belongs to whichever side reaches the
      effect first -- and today, nothing structurally
      guarantees that side is authorization.</t>
      <t>This document does not invent another assistant API.
      It binds the Agent Candidate Act profile
      <xref target="I-D.das-agentic"/> onto the three
      interface families those runtimes and their customers
      already ship: tool_use / computer_use style
      interfaces, function-calling and structured
      tool-response interfaces, and Model Context Protocol
      tools/call. The model may emit the
      block. The block remains non-effective. A local
      enforcer builds the act, binds the argument digest,
      and refuses invoke() until scoped authority is
      verified and consumed at the dispatch sink.</t>
      <t>For consequence classes above a defined threshold --
      FINANCIAL, PHYSICAL, NETWORK_CONTROL, and any act
      reaching defense or critical-infrastructure actuation --
      this binding treats fail-closed as the only conforming
      behavior: absent successfully verified, current,
      act-bound authority, the candidate act stays
      non-effective regardless of model confidence, prior
      session trust, or upstream alignment signal. Each
      enforcement decision, allow or deny, commits a
      Ledger-Anchored Validation Receipt (LAVR) -- a signed,
      hash-chained enforcement artifact bound to the specific
      candidate act and its argument digest at the moment of
      decision. An LAVR is not a log entry assembled
      afterward for audit; it is the proof that the finality
      boundary actually gated this act before any effect
      could occur, and its absence is itself a fail-closed
      condition.</t>
      <t>The implementation target is a middleware function
      that a host loop can call without changing the model
      vendor. tool_use is not invoke().</t>
    </abstract>
  </front>
  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>Every hosted agent product converged on the same
      wire shape:</t>
      <artwork><![CDATA[
model output
  tool_use block:   content[type=tool_use] {id, name, input}
  tool call array:  tool_calls[] {id, function.name, function.arguments}
  MCP call:         tools/call {name, arguments}
        |
        v
host.invoke(name, arguments)
        |
        v
tool_result / function output / MCP result
]]></artwork>
      <t>This document inserts a gate on the middle arrow
      without asking model providers to change model
      cards. The gate is the profile in
      <xref target="I-D.das-agentic"/>: wrap the block as
      an AgentCandidateAct, hold it non-effective, validate,
      commit evidence, issue scoped authority, verify at
      the dispatch sink, consume, then invoke.</t>
      <t>Vendor names are deployment classes. Field names
      below follow public tool-use and MCP shapes as of
      this writing and are informative where those APIs
      evolve. The load-bearing contract is the act
      object, not a trademark.</t>
    </section>

    <section anchor="why">
      <name>Why This Binding Is the Lab-Facing Draft</name>
      <t>The agentic profile is the architecture. This
      document is the thing a runtime engineer can
      implement on Monday. Labs lose enterprise deals
      on a specific sentence: "what happens when the
      model is injected and still emits a tool block."
      Answers that are only "we train refusal" or "we
      log the block" are weaker than "invoke() is
      unreachable without a consumed authority_id bound
      to this argument digest."</t>
      <t>That sentence maps onto products customers already
      buy: Claude for Work with tools and computer use,
      ChatGPT Enterprise with actions and an Agents
      runtime, and MCP servers wired into both. The
      binding is how isolation of action
      <xref target="DAS-ISOLATION"/> lands in the loop
      those products run thousands of times per minute.</t>
      <t>For an Anthropic reliability or safety engineer
      the claim is mechanical: a tool_use block can
      exist, be shown in the transcript, and still
      leave the world unchanged. Refusal training
      reduces how often the block appears. This
      binding reduces what the block can do when it
      appears anyway — including when the model is
      following a retrieved instruction it treated as
      a user turn.</t>
      <t>For an OpenAI platform or Agents engineer the
      claim is the same on tool_calls[] and on
      Actions HTTP. Schema-valid arguments are not
      a capability. Parallel calls are not one
      capability. An Agents SDK that owns the loop
      MUST expose the hook or wrap the tool objects;
      otherwise the safest model still has an
      unguarded invoke.</t>
    </section>

    <section anchor="rfc2119">
      <name>Requirements Language</name>
      <t>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 <xref target="RFC2119"/>
      <xref target="RFC8174"/> when, and only when, they
      appear in all capitals, as shown here.</t>
      <t>A host that executes a tool block without current
      dispatch authority is non-conforming with this
      binding even if the model vendor's SDK performed
      the HTTP call.</t>
    </section>

    <section anchor="problem">
      <name>Problem Space</name>
      <t>The host loop is short and trusted by default:</t>
      <artwork><![CDATA[
for block in model_output.tool_uses:
    result = tools[block.name](**block.input)
    append_tool_result(block.id, result)
]]></artwork>
      <t>That loop is correct only if the block is a
      capability. It is not. Failures this binding
      treats as first-class:</t>
      <ul>
        <li>Injected page or ticket text causes
        tool_use name=email.send to a new recipient.</li>
        <li>OpenAI function.arguments JSON is valid
        against the schema and still pays the wrong
        vendor (see <xref target="I-D.das-payment"/>).</li>
        <li>MCP server with the same tool name is
        swapped (T7 in the agentic profile).</li>
        <li>Computer-use screenshot policy allows
        clicks; a submit posts a form the model
        narrated incorrectly.</li>
        <li>Memory or project write persists a
        prohibited join for the next turn
        <xref target="I-D.das-enterprise"/>.</li>
        <li>The host retries invoke() after a timeout
        and double-executes a side-effecting tool.</li>
      </ul>
    </section>

    <section anchor="existing">
      <name>What Labs Already Ship and What They Do Not Bind</name>
      <section>
        <name>Anthropic tool_use and Computer Use</name>
        <t>tool_use binds a name and an input object to a
        content block id. Computer use binds screen
        actions. System prompts, tool schemas, and
        constitutional or policy trained refusal try to
        stop bad blocks before they appear. They do
        not consume single-use authority at invoke, and
        they do not hash arguments so an approved
        search cannot become a send.</t>
      </section>
      <section>
        <name>OpenAI function calling, Responses tools, GPTs</name>
        <t>tool_calls bind a function name and a JSON
        argument string. GPTs Actions add OpenAPI
        backends. The Agents runtime adds loops.
        Schema validation answers "is this JSON
        shaped." It does not answer "may this digest
        run now at this sink."</t>
      </section>
      <section>
        <name>MCP tools/list and tools/call</name>
        <t>MCP authenticates a client to a server and
        names tools. tools/call is still bearer-like
        with respect to every call that server will
        accept under the session. Server discovery
        is not act authority <xref target="I-D.das-agentic"/>.</t>
      </section>
      <section>
        <name>What This Binding Adds</name>
        <t>A deterministic mapping from those three
        envelopes to AgentCandidateAct, a host-local
        enforce() that MUST wrap invoke, and an error
        mapping back into tool_result / function output
        / MCP error so the model sees a deny rather
        than a successful side effect.</t>
      </section>
    </section>

    <section anchor="map-anthropic">
      <name>Binding: Anthropic tool_use</name>
      <t>Informative source shape:</t>
      <sourcecode type="json"><![CDATA[
{
  "type": "tool_use",
  "id": "toolu_01A",
  "name": "email_send",
  "input": {
    "to": "alice@example.com",
    "subject": "Invoice",
    "body": "..."
  }
}
]]></sourcecode>
      <t>Mapping MUST be:</t>
      <ul>
        <li>candidate_act_id — host-generated, MUST NOT
        equal toolu_* alone if that id can be replayed
        across sessions; MAY incorporate it.</li>
        <li>act_type — TOOL_CALL, or BROWSER_ACTION /
        COMPUTER_USE when name is in the computer-use
        family.</li>
        <li>tool.tool_id and function_id — name.</li>
        <li>tool.tool_protocol — LOCAL_FUNCTION or MCP.</li>
        <li>arguments_digest — hash of JCS(input) or
        documented canonical JSON.</li>
        <li>instruction_provenance.source_type — user,
        retrieval, tool, or unknown as the host can
        attest.</li>
        <li>finality_sink.sink_type — TOOL_DISPATCH or
        BROWSER_CONTROLLER.</li>
      </ul>
      <t>On deny, the host MUST append a tool_result for
      that id whose content is an error object, not a
      successful send. On allow, invoke then append
      the real result. The model is allowed to
      recover. The world is not allowed to change on
      deny.</t>
      <section>
        <name>Computer Use</name>
        <t>Each consequential action (click, type-submit,
        file download) is its own Candidate Act.
        screenshot and cursor moves MAY be
        INFORMATIONAL if they cannot exfiltrate.
        A submit that posts a form MUST bind a digest
        over the live form values, not over the
        model's text description of the click.
        Origin change MUST invalidate prior
        authority.</t>
        <t>Informative computer-use action names vary by
        preview API. Treat left_click, type, and
        key(Enter) on a focused form as potential
        COMMUNICATION or FINANCIAL if the focused
        origin is a mail, bank, or admin host.
        Treat screenshot as DATA_DISCLOSURE when
        the frame can contain secrets (password
        managers, MFA QR, customer PII). A single
        "computer use session allow" MUST NOT
        authorize every later action in the
        session.</t>
        <t>The live digest SHOULD include origin,
        destination URL if known, and a
        stable serialization of the filled
        fields. If the controller cannot read
        those fields, it MUST escalate or deny
        rather than click on narration alone.
        This is the computer-use form of
        argument substitution.</t>
      </section>
    </section>

    <section anchor="map-openai">
      <name>Binding: OpenAI tool_calls and Responses</name>
      <t>Informative source shape:</t>
      <sourcecode type="json"><![CDATA[
{
  "id": "call_8f3",
  "type": "function",
  "function": {
    "name": "payout_create",
    "arguments": "{\"amount\":\"150.00\",\"currency\":\"EUR\",\"beneficiary\":\"vendor-441\"}"
  }
}
]]></sourcecode>
      <t>Mapping MUST parse arguments as JSON, then
      canonicalize the object, then hash. Hashing the
      raw string is allowed only if the host guarantees
      one serialization. Two equivalent JSON strings
      MUST NOT produce two different authorities that
      both can run.</t>
      <t>function.name maps to tool_id and function_id.
      Parallel tool_calls[] are parallel Candidate
      Acts. Each MUST be enforced separately. A
      single ALLOW for the message MUST NOT authorize
      every call in the array.</t>
      <t>Responses API tool outputs and Assistants
      tool-output submits are the same sink moment:
      before the host runs the function map. GPT
      Actions that HTTP POST to a customer API are
      API_REQUEST acts; destination is the Action
      server URL.</t>
    </section>

    <section anchor="map-mcp">
      <name>Binding: MCP tools/call</name>
      <t>Informative request:</t>
      <sourcecode type="json"><![CDATA[
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "repo_deploy",
    "arguments": { "env": "prod", "ref": "main" }
  }
}
]]></sourcecode>
      <t>The conforming placement is the MCP *client*
      dispatcher, not each server. One enforcer sees
      every server the agent can reach. Server
      identity MUST enter destination or
      tool.tool_endpoint so a swapped server with the
      same tool name fails sink or destination
      match.</t>
      <t>On deny the client MUST NOT send tools/call, or
      MUST send it only to a server that is itself a
      cooperating sink and will refuse. Returning an
      MCP error to the model is required so the loop
      does not treat silence as success.</t>
      <t>tools/list remains discovery. list results MUST
      NOT issue AgentFinalityAuthority.</t>
    </section>

    <section anchor="streaming">
      <name>Streaming, Partial Blocks, and Parallel Calls</name>
      <t>Both labs stream tokens. A partial tool_use or
      partial function.arguments string MUST remain
      non-effective. enforce() MUST run only on the
      finalized block. Invoking on a partial JSON
      object is non-conforming.</t>
      <t>Parallel tool_calls and multiple tool_use blocks
      in one assistant message are independent acts.
      The host MAY validate them concurrently. It
      MUST NOT treat one ALLOW as covering siblings.
      If one call is FINANCIAL and one is
      INFORMATIONAL, only the FINANCIAL call escalates.
      A deny on one call MUST NOT be "fixed" by
      invoking the others first and hoping the model
      forgets.</t>
      <t>Retries after transport failure MUST reuse the
      same candidate_act_id only when the consume bit
      is unread and the digest is unchanged. If
      consume already happened, retry is a new act or
      a fetch of the original tool_result, never a
      second invoke.</t>
    </section>

    <section anchor="schema">
      <name>AgentCandidateAct Schema Recalled for Implementers</name>
      <t>The normative schema lives in
      <xref target="I-D.das-agentic"/>. It is repeated
      here so this binding can be implemented from one
      document on a first reading.</t>
      <sourcecode type="json"><![CDATA[
{
  "$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": {
    "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", "COMPUTER_USE", "OTHER"
      ]
    },
    "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",
            "ANTHROPIC_TOOL_USE", "OPENAI_TOOL_CALL", "OTHER"
          ]
        }
      }
    },
    "consequence_class": {
      "type": "string",
      "enum": [
        "INFORMATIONAL", "DATA_DISCLOSURE",
        "PERSISTENT_STATE_CHANGE", "FINANCIAL",
        "NETWORK_CONTROL", "PHYSICAL", "COMMUNICATION", "OTHER"
      ]
    }
  }
}
]]></sourcecode>
    </section>

    <section anchor="fieldmap">
      <name>Field-by-Field Mapping Tables</name>
      <section>
        <name>Anthropic tool_use to AgentCandidateAct</name>
        <t>type=tool_use → act_type TOOL_CALL.
        id → incorporated into candidate_act_id.
        name → tool_id and function_id.
        input → canonicalized into arguments_digest.
        Host session id → freshness.session_id.
        Workspace org → initiating_principal.
        Model name from the request → agent.model_id.
        computer_2025xxxx tools → act_type COMPUTER_USE
        and sink BROWSER_CONTROLLER.</t>
      </section>
      <section>
        <name>OpenAI tool_calls to AgentCandidateAct</name>
        <t>id call_* → incorporated into
        candidate_act_id. type=function → TOOL_CALL.
        function.name → tool_id. function.arguments
        parsed object → arguments_digest.
        Parallel index is not authority; each id is
        an act. Responses API function_call items
        use the same map. Custom GPT Action
        operationId MAY populate function_id when
        name is generic.</t>
      </section>
      <section>
        <name>MCP tools/call to AgentCandidateAct</name>
        <t>params.name → tool_id. params.arguments →
        digest. jsonrpc id is not candidate_act_id
        (it can collide across servers). Server
        URL or server name → tool_endpoint and
        destination. Protocol MCP. A
        notifications/message that asks the host to
        call a tool is the same map if the host
        would invoke.</t>
      </section>
    </section>

    <section anchor="denies">
      <name>Worked Denies the Labs Will Recognize</name>
      <sourcecode type="json"><![CDATA[
{
  "scenario": "INJECTED_EMAIL_SEND",
  "vendor": "anthropic",
  "block": { "name": "email_send", "input": { "to": "attacker@ex.com" } },
  "reason": "provenance=retrieval and consequence=COMMUNICATION",
  "enforce": { "allow": false, "code": "EF_INSTRUCTION_PROVENANCE_FAILURE" },
  "invoked": false,
  "tool_result": { "is_error": true }
}
]]></sourcecode>
      <sourcecode type="json"><![CDATA[
{
  "scenario": "PARALLEL_PAY_AND_SEARCH",
  "vendor": "openai",
  "tool_calls": [
    { "name": "search", "result": "enforce_hot_allow" },
    { "name": "payout_create", "result": "enforce_deny_envelope" }
  ],
  "rule": "search invoke does not authorize payout invoke"
}
]]></sourcecode>
      <sourcecode type="json"><![CDATA[
{
  "scenario": "MCP_SERVER_SWAP",
  "name": "repo_deploy",
  "authorized_endpoint": "mcp://git.example/prod",
  "live_endpoint": "mcp://git.attacker/prod",
  "enforce": { "allow": false, "code": "EF_DESTINATION_MISMATCH" }
}
]]></sourcecode>
      <sourcecode type="json"><![CDATA[
{
  "scenario": "COMPUTER_USE_ORIGIN_CHANGE",
  "authorized_origin": "https://pay.example/checkout",
  "live_origin": "https://pay.example-evil/checkout",
  "enforce": { "allow": false, "code": "EF_DESTINATION_MISMATCH" }
}
]]></sourcecode>
    </section>

    <section anchor="hooks">
      <name>Where to Put the Hook in Shipping Runtimes</name>
      <t>Anthropic Messages API: after the application
      assembles content blocks, before the developer
      function table runs. Computer-use beta: inside
      the controller that turns action items into OS
      events, before the event is sent.</t>
      <t>OpenAI Chat Completions: after tool_calls is
      parsed, before the function map. Assistants
      API: before submitting tool outputs that the
      host computed by running code. Responses API:
      before executing function_call items.
      Agents SDK: a before_tool_call callback if
      present; otherwise wrap the tool implementation
      objects the SDK receives.</t>
      <t>MCP TypeScript and Python reference clients:
      wrap Client.callTool. IDE agents that embed
      MCP (desktop hosts) wrap the same method so
      every server inherits the gate.</t>
    </section>

    <section anchor="workflow">
      <name>Host-Loop Workflow</name>
      <ol>
        <li>Receive model output or MCP request.</li>
        <li>For each tool block, parse name and
        arguments.</li>
        <li>Canonicalize arguments. Compute
        arguments_digest.</li>
        <li>Build AgentCandidateAct
        <xref target="I-D.das-agentic"/>.</li>
        <li>HOLD_NON_EFFECTIVE.</li>
        <li>PED_VALIDATE (local hot path or escalate).</li>
        <li>Commit evidence. Issue authority.</li>
        <li>DISPATCH_SINK_INVOKE: verify live digest,
        sink, epochs, consume.</li>
        <li>Only then call the vendor SDK, local
        function, or MCP transport.</li>
        <li>Map deny to the vendor error shape. Do
        not invoke on timeout.</li>
      </ol>
    </section>

    <section anchor="pseudocode">
      <name>Reference Host Loop</name>
      <sourcecode type="pseudocode"><![CDATA[
function HANDLE_ANTHROPIC_MESSAGE(msg, ctx):
    for block in msg.content where block.type == "tool_use":
        act = map_tool_use(block, ctx)
        decision = enforce(act, block.input)
        if decision.allow:
            raw = invoke(block.name, block.input)
            append_tool_result(block.id, raw)
        else:
            append_tool_result(block.id, {
              "error": decision.code,
              "message": decision.message
            })

function HANDLE_OPENAI_MESSAGE(msg, ctx):
    for call in msg.tool_calls:
        args = parse_json(call.function.arguments)
        act = map_tool_call(call, args, ctx)
        decision = enforce(act, args)
        if decision.allow:
            raw = invoke(call.function.name, args)
            append_tool_output(call.id, raw)
        else:
            append_tool_output(call.id, error_payload(decision))

function HANDLE_MCP_TOOLS_CALL(req, ctx):
    act = map_mcp(req, ctx)
    decision = enforce(act, req.params.arguments)
    if not decision.allow:
        return mcp_error(decision)
    return transport_tools_call(req)
]]></sourcecode>
    </section>

    <section anchor="enforce">
      <name>enforce() Contract</name>
      <t>A library advertised as implementing this
      binding MUST expose a function with this
      behavior, regardless of language:</t>
      <sourcecode type="pseudocode"><![CDATA[
enforce(act: AgentCandidateAct, live_args: object) ->
    { allow: bool, authority_id?: string, code?: string, message?: string }

# MUST:
# 1. hash live_args with the same canonicalization as act.arguments_digest
# 2. refuse if hashes differ
# 3. refuse if authority missing, expired, consumed, or sink-mismatched
# 4. consume single-use authority before returning allow=true
# 5. never return allow=true on timeout or uncertain epoch
]]></sourcecode>
      <t>Returning allow=true and then failing to
      consume is non-conforming. Logging a deny and
      invoking anyway is non-conforming.</t>
    </section>

    <section anchor="json">
      <name>JSON Objects Used on the Wire</name>
      <t>The Candidate Act schema is
      <xref target="I-D.das-agentic"/>. This binding
      adds only mapped examples and the host error
      object.</t>
      <section>
        <name>Mapped Claude Block</name>
        <sourcecode type="json"><![CDATA[
{
  "version": "1.0",
  "object_type": "agent_candidate_act",
  "candidate_act_id": "act-toolu-01A-sess55",
  "act_type": "TOOL_CALL",
  "agent": {
    "agent_id": "claude-work-seat-12",
    "runtime_id": "anthropic-host-loop",
    "model_id": "claude-family",
    "delegation_depth": 0
  },
  "tool": {
    "tool_id": "email_send",
    "function_id": "email_send",
    "tool_protocol": "LOCAL_FUNCTION"
  },
  "purpose": {
    "purpose_id": "user-turn",
    "declared_purpose": "send invoice email"
  },
  "arguments_digest": {
    "algorithm": "SHA-256",
    "value": "base64url-args",
    "canonicalization": "JCS"
  },
  "destination": { "destination_id": "smtp-gw-1" },
  "consequence_class": "COMMUNICATION",
  "policy_state": {
    "policy_epoch": 9,
    "authority_epoch": 3,
    "revocation_epoch": 1
  },
  "freshness": { "nonce": "C0FFEE11DEADBEEF" },
  "instruction_provenance": { "source_type": "user" },
  "finality_sink": {
    "sink_id": "host-dispatch-1",
    "sink_type": "TOOL_DISPATCH"
  }
}
]]></sourcecode>
      </section>
      <section>
        <name>Mapped OpenAI Payout Call</name>
        <sourcecode type="json"><![CDATA[
{
  "object_type": "agent_candidate_act",
  "act_type": "TOOL_CALL",
  "tool": {
    "tool_id": "payout_create",
    "function_id": "payout_create",
    "tool_protocol": "HTTP_API"
  },
  "arguments_digest": {
    "algorithm": "SHA-256",
    "value": "base64url-args",
    "canonicalization": "JCS"
  },
  "consequence_class": "FINANCIAL",
  "destination": { "destination_id": "psp.example" },
  "finality_sink": {
    "sink_id": "host-dispatch-1",
    "sink_type": "TOOL_DISPATCH"
  }
}
]]></sourcecode>
        <t>If the handler would move funds, a
        PaymentCandidateAct from
        <xref target="I-D.das-payment"/> MUST also be
        enforced before the PSP SDK.</t>
      </section>
      <section>
        <name>Host Deny Payload Back to the Model</name>
        <sourcecode type="json"><![CDATA[
{
  "error": {
    "code": "EF_SCOPE_MISMATCH",
    "message": "Live arguments are not the authorized digest.",
    "retryable": false,
    "invoked": false
  }
}
]]></sourcecode>
      </section>
      <section>
        <name>Complete Claude Turn</name>
        <sourcecode type="json"><![CDATA[
{
  "step_1_block": {
    "type": "tool_use",
    "name": "maps_search",
    "status": "NON_EFFECTIVE"
  },
  "step_2_enforce": {
    "allow": true,
    "authority_id": "afa-c7d32d54",
    "consumed": true
  },
  "step_3_invoke": { "tool": "maps_search", "once": true },
  "step_4_tool_result": { "id": "toolu_01A", "ok": true }
}
]]></sourcecode>
      </section>
    </section>

    <section anchor="feasibility">
      <name>Practical Feasibility: Latency and Legacy Loops</name>
      <section>
        <name>Do Not Change the Model</name>
        <t>The binding is host-side. No tokenizer change,
        no tool-schema change, no fine-tune is required
        for v1. That is why a lab can trial this on
        one enterprise workspace without a model
        release.</t>
      </section>
      <section>
        <name>Latency Budget</name>
        <t>Tool loops are already dominated by the model
        forward pass and the tool I/O. enforce() on
        the hot path is: canonicalize JSON, SHA-256,
        MAC or signature verify, compare-and-swap on a
        consume row. Representative added cost is
        sub-millisecond to a few milliseconds on the
        same host — negligible next to a 200-2000 ms
        model call. Cold path (new tool, unknown
        destination, FINANCIAL class, unknown
        provenance) MAY add a policy fetch. Timeout
        of that fetch MUST deny, not invoke.</t>
      </section>
      <section>
        <name>Legacy Host Loops</name>
        <t>Existing OpenAI and Anthropic examples are
        ten-line for-loops. The feasible change is
        wrapping invoke, not rewriting the product.
        A feature flag "enforce_tools=true" on a
        workspace is a conforming pilot. Workspaces
        left on false are known alternate paths and
        MUST be listed if they can reach the same
        side-effecting tools.</t>
        <t>SDKs that invoke tools internally (some
        Agents runtimes) MUST expose a pre-invoke
        hook or MUST be wrapped at the HTTP client
        that talks to the tool backend. If neither
        hook exists, the deployment cannot claim this
        binding for those tools.</t>
      </section>
      <section>
        <name>MCP Without Server Changes</name>
        <t>Servers can stay unmodified if the client
        enforcer is in-line. Cooperating servers MAY
        later verify the authority object themselves.
        That is an enhancement, not a v1 requirement.
        Flag-day replacement of every MCP server is
        not required and not recommended.</t>
      </section>
      <section>
        <name>Computer Use Without a New Browser</name>
        <t>The sink is the existing controller process
        that issues clicks. Digest the live DOM or
        form state you already read to click. If you
        cannot digest the live values, those submits
        MUST be treated as cold path or denied. Do
        not invent a second browser.</t>
      </section>
      <section>
        <name>What This Binding Does Not Require</name>
        <t>It does not require a TEE on day one. It
        does not require vaults from
        <xref target="I-D.das-enterprise"/> on day
        one. It does not require Anthropic or OpenAI
        to accept a patch. It requires the host that
        already runs the loop to stop treating the
        block as a capability.</t>
      </section>
    </section>

    <section anchor="industry">
      <name>How Labs and Customers Use It</name>
      <section>
        <name>Anthropic-Class Workspace</name>
        <t>Enable enforce() on tools marked
        COMMUNICATION, FINANCIAL,
        PERSISTENT_STATE_CHANGE, or computer-use
        submit. Leave maps.search on a hot envelope.
        Measure denies that would have been sends.
        That metric is the procurement answer.</t>
      </section>
      <section>
        <name>OpenAI-Class Workspace</name>
        <t>Same split for Actions and function tools.
        Memory writes go through enforce() as
        MEMORY_WRITE. Share-chat and file export are
        Output Release Boundaries under
        <xref target="I-D.das-enterprise"/> when the
        content is a reconstructed view; they are
        still tool-shaped if implemented as tools.</t>
      </section>
      <section>
        <name>Platform Customers</name>
        <t>A bank or hospital that cannot wait for a
        vendor-native hook wraps the tool handlers
        they wrote. That is enough for tools they
        own. Tools the vendor invokes inside a
        black box remain an alternate path until the
        vendor exposes the hook.</t>
      </section>
    </section>

    <section anchor="classes">
      <name>Default Consequence Classes for Common Tools</name>
      <t>Hosts SHOULD assign consequence_class before
      enforce(), not after the model names the tool.
      Informative defaults:</t>
      <ul>
        <li>search, retrieve, get_weather —
        INFORMATIONAL</li>
        <li>email_send, slack_post, tweet —
        COMMUNICATION</li>
        <li>file_write, db_update, memory_write,
        ticket_create — PERSISTENT_STATE_CHANGE</li>
        <li>payout, refund, capture, wire —
        FINANCIAL (also
        <xref target="I-D.das-payment"/>)</li>
        <li>deploy, kubectl, iam_attach —
        PERSISTENT_STATE_CHANGE or
        NETWORK_CONTROL</li>
        <li>computer_use submit, browser_navigate
        to new origin — DATA_DISCLOSURE or
        COMMUNICATION depending on the form</li>
        <li>shell / bash — at least
        PERSISTENT_STATE_CHANGE; treat as cold
        path unless the envelope names the exact
        binary</li>
      </ul>
      <t>Misclassifying payout as INFORMATIONAL is a
      profile failure, not a model failure.</t>
    </section>

    <section anchor="memory">
      <name>Memory, Projects, and Persistent Notes</name>
      <t>Claude projects and ChatGPT memory are tool-
      shaped even when they are not named tools.
      A host that writes extracted facts into a
      memory store MUST treat that write as
      MEMORY_WRITE. Otherwise an injected turn
      stores a join that later turns treat as
      user provenance. That is how present theft
      becomes future mapping without another
      tool_use <xref target="DAS-ISOLATION"/>.</t>
    </section>

    <section anchor="tests">
      <name>Conformance Tests a Lab Can Run Overnight</name>
      <t>T-A: emit tool_use email_send to an address
      not in the user turn; expect invoke=false.
      T-B: two OpenAI tool_calls, search and
      payout; expect payout denied when above
      envelope. T-C: replay the same authority_id
      on a second invoke; expect deny. T-D: MCP
      call with swapped server URL; expect
      destination deny. T-E: computer-use submit
      after origin change; expect deny. T-F:
      measure enforce() p99 under 10 ms on hot
      search. T-G: kill the host after consume
      and before invoke; on restart do not
      invoke again.</t>
      <t>A workspace that passes T-A through T-G
      can be shown to an enterprise security
      review without a new model checkpoint.</t>
    </section>

    <section anchor="errors">
      <name>Error Mapping</name>
      <t>EF codes from <xref target="I-D.das-agentic"/>
      SHOULD be copied into the vendor error payload
      as machine-readable strings. retryable=true
      only for EF-060 timeout where policy allows a
      bounded retry of *validation*, never a retry
      that skips enforce(). Models that respond to
      deny by emitting a different tool_use are
      starting a new Candidate Act. That is
      expected.</t>
    </section>

    <section anchor="threats">
      <name>Threats This Binding Makes Local</name>
      <ul>
        <li>T1 Direct prompt injection → extra
        tool_use</li>
        <li>T2 Indirect injection in retrieved
        files</li>
        <li>T6 Tool name confusion / substitution</li>
        <li>T7 MCP server substitution</li>
        <li>T14 Replay of a previous tool block
        id</li>
        <li>T17 Alternate path: raw HTTP next to
        the SDK</li>
        <li>T18 Computer-use submit around API
        tools</li>
      </ul>
      <t>Threats that need the enterprise profile
      (join of identity and content) are out of
      scope here except as provenance=unknown plus
      high consequence_class → escalate.</t>
    </section>


    <section anchor="technical-concerns">
      <name>Addressing Potential Technical Concerns</name>

      <section anchor="middleware-distinction">
        <name>Distinction from Conventional Middleware and Zero-Trust Authorization</name>
        <t>The architecture should not be understood merely as intercepting an untrusted AI-generated string and checking permissions before a software function executes.</t>
        <t>Conventional middleware, API gateways, reference monitors, policy-enforcement points, and zero-trust systems can already perform authorization before an API call or resource access.</t>
        <t>The execution-finality model addresses a different architectural problem: generation of an action is separated from authority to make that action externally effective.</t>
        <t>A model, agent, application, or tool-orchestration layer may compute or propose an action, but that proposed action is represented as a Candidate Act and remains in a Non-Effective State until the required validation conditions are satisfied.</t>
        <t>Validation establishes protected evidence or authorization state associated with the load-bearing attributes of that Candidate Act, which may include the requested operation, arguments, destination, execution context, authorization scope, policy state, and other relevant parameters.</t>
        <t>The important point is that approval at an upstream middleware layer does not itself constitute final authority for the external effect.</t>
        <t>Before the requested consequence becomes externally effective, the relevant Finality Sink or effectuation boundary verifies the required authorization state for the Candidate Act being presented for effectuation.</t>
        <t>The security model is therefore not simply:</t>
        <artwork><![CDATA[
check permission -> execute tool
]]></artwork>
        <t>but rather:</t>
        <artwork><![CDATA[
Candidate Act
    -> Non-Effective State
    -> protected validation and act-specific binding
    -> scoped execution authority
    -> Finality Sink verification
    -> externally effective consequence
]]></artwork>
        <t>The technical distinction is therefore the separation between computation, authorization, and effectuation, together with verification at the boundary where the external effect would actually occur.</t>
      </section>

      <section anchor="alternate-path-closure">
        <name>Closure of Alternative and Legacy Execution Paths</name>
        <t>An execution-finality architecture is only meaningful if the protected consequence cannot be reached through an ungoverned alternative path.</t>
        <t>An application-level <tt>enforce()</tt> function may therefore be one implementation interface, but it should not itself be treated as the ultimate security boundary.</t>
        <t>For protected operations, execution paths capable of producing the same externally effective consequence should converge upon, or otherwise remain subordinate to, the protected finality-enforcement boundary.</t>
        <t>Relevant paths may include:</t>
        <ul>
          <li>direct API or SDK invocation;</li>
          <li>legacy interfaces;</li>
          <li>plugin or tool-router paths;</li>
          <li>inter-process communication;</li>
          <li>subprocess execution;</li>
          <li>cached or delegated credentials;</li>
          <li>agent-to-agent delegation;</li>
          <li>operating-system service calls;</li>
          <li>alternate network interfaces;</li>
          <li>retries or replay paths; and</li>
          <li>other implementation-specific mechanisms capable of reaching the same protected resource or external effect.</li>
        </ul>
        <t>If the required authorization or validation state cannot be verified at the relevant effectuation boundary, the operation remains non-effective and the system fails closed.</t>
        <t>The resulting security invariant is:</t>
        <blockquote>
          <t>No protected externally effective consequence should occur through an alternate execution path merely because that path bypassed the original middleware or orchestration layer.</t>
        </blockquote>
        <t>This anti-bypass property is a core requirement of the execution-finality model rather than an optional application-level policy convention.</t>
      </section>

      <section anchor="deterministic-binding">
        <name>Deterministic Binding of Dynamic Action Arguments</name>
        <t>The architecture does not require hashing the literal JSON string emitted by an AI system.</t>
        <t>Raw serialization is unsuitable for action binding because equivalent structured data can have different byte representations due to property order, whitespace, encoding choices, or other formatting differences.</t>
        <t>Instead, the system can derive an <tt>arguments_digest</tt>, commitment, or equivalent binding value from a deterministic representation of the load-bearing attributes of the Candidate Act.</t>
        <t>Depending upon the protocol and schema, this process may include:</t>
        <ul>
          <li>deterministic field ordering;</li>
          <li>defined representation of numbers and Boolean values;</li>
          <li>deterministic character encoding;</li>
          <li>defined treatment of absent, empty, and null values;</li>
          <li>exclusion of non-semantic formatting;</li>
          <li>explicit field typing;</li>
          <li>schema-defined normalization rules; and</li>
          <li>deterministic encoding before digest generation.</li>
        </ul>
        <t>For example, the following two JSON serializations may represent the same Candidate Act:</t>
        <sourcecode type="json"><![CDATA[
{"amount":100,"currency":"USD"}
]]></sourcecode>
        <sourcecode type="json"><![CDATA[
{"currency":"USD","amount":100}
]]></sourcecode>
        <t>A deterministic representation allows both forms to produce the same Candidate-Act commitment where their semantics are equivalent.</t>
        <t>At the same time, normalization must remain semantics-preserving.</t>
        <t>Values should not be collapsed merely because they appear superficially similar. For example, a string value and a numeric value should only be treated as equivalent where the applicable schema explicitly defines that equivalence.</t>
        <t>The architectural requirement is therefore broader than any particular JSON representation:</t>
        <artwork><![CDATA[
load-bearing Candidate Act attributes
    -> deterministic representation
    -> Candidate-Act commitment
]]></artwork>
        <t>This approach can be applied to JSON, CBOR, Protocol Buffers, MCP messages, operating-system calls, payment instructions, database operations, robotic commands, or other structured action representations.</t>
        <t>The purpose of the commitment is not merely transport-integrity checking. It is to ensure that the action presented at the effectuation boundary corresponds to the action state that was actually validated.</t>
      </section>

      <section anchor="technical-concerns-summary">
        <name>Summary</name>
        <t>The execution-finality model is not intended to replace conventional authentication, authorization, zero-trust policy, or middleware controls.</t>
        <t>Those mechanisms may remain upstream inputs to the decision process.</t>
        <t>The additional architectural property is that computation does not itself create effectuation authority; a Candidate Act remains non-effective until validated; the validated action state is bound to the relevant execution authority; and the Finality Sink verifies that state before permitting the externally effective consequence.</t>
        <t>This provides a distinct system-level enforcement boundary for AI agents, tool-use systems, autonomous software, and other environments in which generating or approving an action should not automatically make that action externally effective.</t>
      </section>
    </section>

    <section anchor="das-protocols-framing">
      <name>Relationship to the DAS Protocols Architecture</name>
      <t>This document is a protocol-facing profile of a broader execution-finality architecture developed in the DAS Protocols work. The broader architecture describes a recurring separation between computation of a proposed act, protected validation of the act, issuance or establishment of scoped finality authority, and verification at a Finality Sink before an external consequence becomes effective.</t>
      <t>The large foundational disclosure referred to by the author as the DAS Protocols "Mothership" is PCT/IB2026/055615, published as WO 2026/150382. That disclosure covers a substantially wider set of execution-finality embodiments, including AI infrastructure, telecommunications, device and operating-system enforcement, protected execution, and other externally effective systems. This Internet-Draft intentionally addresses a much narrower interoperability problem: binding existing AI tool-use and MCP-style dispatch interfaces to an execution-finality boundary.</t>
      <t>The terminology used here, including Candidate Act, Non-Effective State, protected validation, scoped execution authority, and Finality Sink, should therefore be read as a compact protocol profile rather than as an attempt to reproduce the full DAS Protocols disclosure.</t>
      <t>This background statement is informative. It does not make implementation of unrelated DAS Protocols embodiments a requirement for conformance with this Internet-Draft. Any IETF intellectual-property disclosure obligations are handled separately under BCP 79 <xref target="RFC8179"/>.</t>
    </section>

    <section anchor="checklist">
      <name>Implementation Checklist</name>
      <ol>
        <li>Every side-effecting tool handler is
        reachable only through enforce() or an equivalent
        protected finality-enforcement boundary.</li>
        <li>arguments_digest or equivalent commitment is
        over a deterministic representation of the
        load-bearing Candidate Act attributes, not over
        the model's prose.</li>
        <li>Parallel tool_calls are separate
        acts.</li>
        <li>Deny returns an error block; invoked
        is false.</li>
        <li>Timeout does not invoke.</li>
        <li>MCP client, not only servers, runs
        enforce().</li>
        <li>Computer-use submit has a live-value
        digest.</li>
        <li>p99 added latency of enforce() is
        measured.</li>
        <li>Tools the vendor invokes without a
        hook are listed as open alternate
        paths.</li>
      </ol>
    </section>

    <section anchor="security">
      <name>Security Considerations</name>
      <t>If enforce() runs in the same process as a
      fully compromised host that can also call the
      tool backend directly, the binding is only as
      strong as alternate-path closure. Production
      hosts SHOULD block raw credentials from
      application code paths that skip enforce(), or
      SHOULD put the sink in a sidecar that owns
      the tool credentials.</t>
      <t>Model-visible deny messages MUST NOT leak
      other users' data. They MAY name the EF
      code.</t>
    </section>

    <section anchor="privacy">
      <name>Privacy Considerations</name>
      <t>Argument objects often contain recipients and
      PII. Logs SHOULD store digests, not raw
      arguments, once enforce() has run. Mapping
      layers MUST NOT write full tool input to a
      shared debug bus by default.</t>
    </section>

    <section anchor="code">
      <name>Informative Host Wrappers</name>
      <t>The following sketches are informative. They
      exist so a lab or customer engineer can see
      that the binding is a wrap of invoke, not a
      new assistant protocol.</t>
      <section>
        <name>Python</name>
        <sourcecode type="python"><![CDATA[
def enforce(act, live_args, store, sink_id):
    live = digest(canonicalize(live_args))
    if live != act["arguments_digest"]["value"]:
        return Deny("EF_SCOPE_MISMATCH")
    auth = store.get(act["candidate_act_id"])
    if not auth or auth.consumed or auth.expired():
        return Deny("EF_002")
    if auth.sink_id != sink_id:
        return Deny("EF_040")
    if not store.consume_cas(auth.authority_id):
        return Deny("EF_005")
    return Allow(auth.authority_id)

def handle_tool_use(block, ctx):
    act = map_tool_use(block, ctx)
    decision = enforce(act, block["input"], ctx.store, ctx.sink_id)
    if not decision.allow:
        return {"error": decision.code, "invoked": False}
    return invoke(block["name"], block["input"])
]]></sourcecode>
      </section>
      <section>
        <name>TypeScript</name>
        <sourcecode type="typescript"><![CDATA[
async function enforce(act: Act, live: object, store: Store, sink: string) {
  const d = digest(canonicalize(live));
  if (d !== act.arguments_digest.value) return deny("EF_SCOPE_MISMATCH");
  const auth = await store.get(act.candidate_act_id);
  if (!auth || auth.consumed || auth.expired()) return deny("EF_002");
  if (auth.sink_id !== sink) return deny("EF_040");
  const ok = await store.consumeCAS(auth.authority_id);
  if (!ok) return deny("EF_005");
  return allow(auth.authority_id);
}

async function onOpenAIToolCalls(calls: ToolCall[], ctx: Ctx) {
  const out = [];
  for (const c of calls) {
    const args = JSON.parse(c.function.arguments);
    const act = mapToolCall(c, args, ctx);
    const d = await enforce(act, args, ctx.store, ctx.sink);
    out.push(d.allow
      ? await invoke(c.function.name, args)
      : { error: d.code, invoked: false });
  }
  return out;
}
]]></sourcecode>
        <t>These functions are the entire v1 product
        surface. Vaults, TEEs, and RAOs can wrap
        later. If invoke is reachable without
        enforce, the sketches are documentation,
        not a binding.</t>
      </section>
    </section>

    <section anchor="refimpl">
      <name>Reference Implementation, Reproducibility, and Measurement Scope</name>
      <t>A public reference implementation of the execution-finality binding described in this document is available at:</t>
      <t><eref target="https://github.com/sangmdas/tool_use-Is-Not-invoke-Binding-Execution-Finality-to-Agentic-Tool-Call-Interfaces-and-MCP"/></t>
      <t>The implementation is intended to make the protocol mechanics independently inspectable and executable. It is not a simulation expressed only as pseudocode or architectural prose. It provides executable Python components for mapping representative agentic tool-call envelopes into Candidate Acts, validating those Candidate Acts, issuing act-bound authority, verifying workload proof-of-possession, enforcing single-use consumption, and preventing invoke() from being reached until the Finality Sink accepts the live act.</t>
      <t>The implementation is deliberately small enough that an independent reviewer can inspect the complete enforcement path.</t>
      <t>Conceptually, the implemented path is:</t>
      <artwork><![CDATA[
model / agent output
        |
        v
tool_use / tool_calls / tools/call
        |
        v
AgentCandidateAct
        |
        v
NON-EFFECTIVE STATE
        |
        v
configured validation
        |
        v
act-bound scoped authority
        |
        v
workload proof-of-possession
        |
        v
Finality Sink verification
        |
        v
single-use authority consumption
        |
        v
invoke()
]]></artwork>
      <t>The important property demonstrated by the implementation is that generation of a syntactically valid tool request is not itself authority for the requested operation to become externally effective.</t>

      <section anchor="refimpl-profiles">
        <name>Implemented Interface Profiles</name>
        <t>Version 0.1.0 contains representative adapters for:</t>
        <ul>
          <li>Anthropic-style tool_use;</li>
          <li>OpenAI-style function/tool-call envelopes;</li>
          <li>MCP tools/call; and</li>
          <li>computer-use actions in which the live origin and action state are included in the Candidate-Act binding.</li>
        </ul>
        <t>These adapters do not depend upon access to a live commercial model or vendor account. They model the relevant public message shapes and place the execution-finality enforcement point in the host-side dispatch path.</t>
        <t>For example, an OpenAI-style function argument object is parsed into structured data before the Candidate-Act digest is calculated. An MCP Candidate Act additionally binds the intended server endpoint so that an otherwise identical tools/call presented to another MCP server can be rejected at the effectuation boundary.</t>
        <t>The implementation therefore tests the protocol-facing invariant rather than the behaviour of any particular model vendor.</t>
      </section>

      <section anchor="refimpl-components">
        <name>Reference Implementation Components</name>
        <t>The implementation contains separate components for:</t>
        <artwork><![CDATA[
adapters.py
    mapping tool-call envelopes into Candidate Acts

canonical.py
    deterministic serialization and SHA-256 argument binding

policy.py
    configured validation predicates

authority.py
    issuance of scoped Candidate-Act authority

crypto.py
    authority authentication and workload proof-of-possession

replay_store.py
    atomic local single-use authority consumption

sink.py
    independent Finality Sink verification

dispatcher.py
    host-loop sequencing and guarded invoke()

demo.py
    reproducible synthetic execution examples

test_agentic_binding.py
    automated conformance-oriented tests

benchmark.py
    local execution-overhead measurements
]]></artwork>
        <t>The decomposition is intentional. It allows an implementer to replace individual mechanisms without changing the architectural requirement.</t>
        <t>For example, HMAC is used in this reference package because it makes the implementation compact and reproducible. HMAC is not a protocol requirement. A production implementation could instead use asymmetric signatures, hardware-protected keys, a TEE, an HSM, a protected operating-system service, a workload identity mechanism, or another suitable cryptographic construction.</t>
        <t>Likewise, the local SQLite replay store is an implementation mechanism for demonstrating atomic single-use consumption. SQLite is not a protocol requirement.</t>
      </section>

      <section anchor="refimpl-archive">
        <name>Versioned Archive</name>
        <t>For reproducibility, the same implementation is packaged as the versioned archive:</t>
        <artwork><![CDATA[
agentic-tool-binding-reference-v0.1.0-final.tar.gz
]]></artwork>
        <t>The SHA-256 digest of the generated archive is:</t>
        <artwork><![CDATA[
ad6acf51d17a9c22168f62f547f0be9888a5b7f94f278d67e23a05584fcb07b3
]]></artwork>
        <t>The archive was created directly from the reference-implementation source tree after removing generated Python cache material.</t>
        <t>In particular, the archive excludes:</t>
        <artwork><![CDATA[
__pycache__/
*.pyc
.pytest_cache/
]]></artwork>
        <t>and includes the source code, tests, test vectors, benchmark, README, notice, license, package metadata, and .gitignore.</t>
        <t>The tar archive is therefore a convenience snapshot of the source tree, rather than a separate implementation.</t>
        <t>Its purpose is to allow a reviewer to retain or cite a fixed set of bytes even if the GitHub main branch subsequently evolves.</t>
        <t>The SHA-256 value is a digest of the compressed .tar.gz archive itself. It is not an execution-finality authorization value, Candidate-Act digest, security proof, or patent identifier. Its only purpose is archive-integrity and reproducibility.</t>
        <t>A reviewer downloading the same archive can independently calculate:</t>
        <artwork><![CDATA[
SHA-256(
  agentic-tool-binding-reference-v0.1.0-final.tar.gz
)
]]></artwork>
        <t>and compare the result with the published value above.</t>
      </section>

      <section anchor="refimpl-reproduction">
        <name>Reproduction</name>
        <t>A reviewer may reproduce the implementation directly from GitHub.</t>
        <t>For example:</t>
        <artwork><![CDATA[
git clone https://github.com/sangmdas/tool_use-Is-Not-invoke-Binding-Execution-Finality-to-Agentic-Tool-Call-Interfaces-and-MCP.git
]]></artwork>
        <t>The supplied test suite can then be executed with pytest, the demonstration can be executed through the package's demo module, and the local benchmark can be executed separately.</t>
        <t>The implementation does not require:</t>
        <ul>
          <li>a GPU;</li>
          <li>a CUDA environment;</li>
          <li>a hosted AI model;</li>
          <li>an Anthropic API key;</li>
          <li>an OpenAI API key;</li>
          <li>a production MCP server;</li>
          <li>a payment service;</li>
          <li>a production database;</li>
          <li>real customer data; or</li>
          <li>access to the author's computer.</li>
        </ul>
        <t>All example data are synthetic.</t>
      </section>

      <section anchor="refimpl-tests">
        <name>Automated Test Coverage</name>
        <t>The supplied v0.1.0 suite contains ten tests.</t>
        <t>They exercise, among other cases:</t>
        <ol>
          <li>an authorized Anthropic-style email operation that reaches invoke() exactly once;</li>
          <li>modification of the arguments after authority issuance;</li>
          <li>reuse of an already consumed authority;</li>
          <li>substitution of an MCP server endpoint;</li>
          <li>presentation at the wrong Finality Sink;</li>
          <li>independent treatment of parallel search and payment Candidate Acts;</li>
          <li>a communication act originating from retrieved/injected content;</li>
          <li>deterministic digesting of semantically equivalent JSON objects having different property order;</li>
          <li>computer-use submission after a change of origin; and</li>
          <li>invalidation caused by a change of policy epoch.</li>
        </ol>
        <t>A verification run of the final archive produced:</t>
        <artwork><![CDATA[
10 passed
]]></artwork>
        <t>The important test property is not merely that the enforcer emits a DENY result. In the negative cases the supplied fake effect function is not invoked.</t>
        <t>This distinguishes:</t>
        <artwork><![CDATA[
log violation -> execute anyway
]]></artwork>
        <t>from:</t>
        <artwork><![CDATA[
validation failure -> no effect
]]></artwork>
      </section>

      <section anchor="refimpl-demo">
        <name>Demonstration Behaviour</name>
        <t>The included demonstration exercises representative Anthropic-style, OpenAI-style, and MCP-style messages.</t>
        <t>Representative outcomes include:</t>
        <artwork><![CDATA[
ANTHROPIC_ALLOWED_EMAIL
    -> ALLOW
    -> invoke()

INJECTED_EMAIL_DENIED
    -> DENY
    -> invoked = false

OPENAI_ALLOWED_PAYOUT
    -> ALLOW for configured synthetic beneficiary
    -> invoke()

MCP_ALLOWED_ENDPOINT
    -> ALLOW for the bound synthetic endpoint
    -> invoke()
]]></artwork>
        <t>These are synthetic test cases. No email is actually sent, no money is transferred, no repository is deployed, and no external MCP server is contacted.</t>
        <t>The synthetic invoke() function records or returns a local result so that the control-flow property can be observed without creating a real-world consequence.</t>
      </section>

      <section anchor="refimpl-benchmark-method">
        <name>How the Latency Values Are Produced</name>
        <t>The repository also contains a local benchmark:</t>
        <artwork><![CDATA[
bench/benchmark.py
]]></artwork>
        <t>The benchmark performs 500 iterations by default.</t>
        <t>Each iteration constructs a fresh local reference stack and measures two principal intervals using Python's high-resolution time.perf_counter_ns() clock.</t>
        <t>The first interval measures the local authorization operation:</t>
        <artwork><![CDATA[
start
  |
  v
verify live argument digest
  |
  v
configured policy validation
  |
  v
construct act-bound authority
  |
  v
authenticate authority
  |
  v
end
]]></artwork>
        <t>The second interval measures:</t>
        <artwork><![CDATA[
Finality Sink entry
  |
  v
recalculate live argument digest
  |
  v
expiry checks
  |
  v
Candidate-Act binding check
  |
  v
tool binding
  |
  v
sink binding
  |
  v
destination binding
  |
  v
policy / authority / revocation epoch checks
  |
  v
authority authentication
  |
  v
workload proof-of-possession verification
  |
  v
atomic single-use consumption
  |
  v
local synthetic invoke()
]]></artwork>
        <t>The benchmark records each measured duration in nanoseconds, converts the observations into microseconds, orders the collected measurements, and reports median, p95, and p99.</t>
        <t>The median represents the midpoint of the observed local measurements.</t>
        <t>The p95 value represents approximately the point below which 95 percent of the measured iterations fall.</t>
        <t>The p99 value represents approximately the point below which 99 percent of the measured iterations fall.</t>
        <t>These values are therefore calculated from observed execution times; they are not configured constants and are not predicted values.</t>
      </section>

      <section anchor="refimpl-benchmark-example">
        <name>Example Verification Measurement</name>
        <t>One verification run of the final v0.1.0 archive in a Linux environment using Python 3.13.5 produced:</t>
        <artwork><![CDATA[
iterations = 500

authorization:
    median = 23.14 microseconds
    p95    = 32.68 microseconds
    p99    = 91.98 microseconds

Finality Sink verification +
single-use consumption +
local synthetic invoke:
    median = 41.41 microseconds
    p95    = 70.65 microseconds
    p99    = 125.37 microseconds

combined measured local path:
    median = 64.92 microseconds
    p95    = 111.44 microseconds
    p99    = 176.74 microseconds
]]></artwork>
        <t>These figures should be treated only as one reproducible reference-code observation.</t>
        <t>They do not mean that an execution-finality deployment universally adds approximately 65 microseconds.</t>
        <t>Another machine, operating system, Python runtime, cryptographic implementation, database, concurrency level, storage subsystem, or deployment topology can produce materially different results.</t>
        <t>Independent reviewers are therefore encouraged to run the supplied benchmark on their own systems and report their own environment together with p50/median, p95, and p99 values.</t>
      </section>

      <section anchor="refimpl-boundary">
        <name>Important Measurement Boundary</name>
        <t>The benchmark deliberately measures only a local enforcement path.</t>
        <t>It does not include:</t>
        <ul>
          <li>AI-model inference time;</li>
          <li>network round trips;</li>
          <li>actual HTTP tool execution;</li>
          <li>MCP network transport;</li>
          <li>real email transmission;</li>
          <li>real payment settlement;</li>
          <li>remote policy retrieval;</li>
          <li>remote attestation;</li>
          <li>remote HSM access;</li>
          <li>cross-region communication;</li>
          <li>human approval;</li>
          <li>distributed consensus;</li>
          <li>database replication;</li>
          <li>production logging;</li>
          <li>production service queues; or</li>
          <li>external destination acknowledgement.</li>
        </ul>
        <t>The initial vendor-envelope-to-Candidate-Act mapping is also performed before the principal benchmark timer begins.</t>
        <t>The reported combined hot-path value therefore characterizes the supplied local enforcement operations, not an end-to-end AI-agent transaction.</t>
        <t>In particular, the synthetic invoke() used by the benchmark is deliberately trivial. It does not model the latency of the actual external tool.</t>
        <t>Accordingly:</t>
        <artwork><![CDATA[
measured local finality overhead
             !=
end-to-end tool latency
]]></artwork>
        <t>and:</t>
        <artwork><![CDATA[
one-machine microbenchmark
             !=
protocol-wide performance guarantee
]]></artwork>
      </section>

      <section anchor="refimpl-hotcold">
        <name>Hot Path and Cold Path</name>
        <t>The reference implementation also illustrates why execution-finality need not place every governance operation on every tool invocation.</t>
        <t>A deployment may perform relatively stable operations on a cold path, including:</t>
        <ul>
          <li>policy definition;</li>
          <li>tool registration;</li>
          <li>destination registration;</li>
          <li>identity enrollment;</li>
          <li>workload enrollment;</li>
          <li>key establishment;</li>
          <li>attestation establishment;</li>
          <li>risk classification; and</li>
          <li>trust configuration.</li>
        </ul>
        <t>The effectuation hot path may then be limited to load-bearing current state, for example:</t>
        <ul>
          <li>Candidate-Act digest;</li>
          <li>live arguments;</li>
          <li>destination;</li>
          <li>sink identity;</li>
          <li>policy epoch;</li>
          <li>revocation epoch;</li>
          <li>expiry;</li>
          <li>nonce;</li>
          <li>workload proof; and</li>
          <li>single-use consumption.</li>
        </ul>
        <t>This separation is an implementation technique rather than a protocol requirement, but it allows expensive configuration and trust-establishment operations to remain outside ordinary tool dispatch where appropriate.</t>
      </section>

      <section anchor="refimpl-legacy">
        <name>Legacy Integration</name>
        <t>The reference implementation does not require modification of model weights, tokenizers, or model training.</t>
        <t>It models the enforcement component as a wrapper around the dispatch boundary already present in an agent host.</t>
        <t>A legacy deployment can therefore resemble:</t>
        <artwork><![CDATA[
existing AI model
       |
       v
existing tool-call envelope
       |
       v
execution-finality wrapper
       |
       v
existing tool / SDK / MCP transport
]]></artwork>
        <t>Potential enforcement placements include:</t>
        <ul>
          <li>host tool dispatcher;</li>
          <li>MCP client dispatcher;</li>
          <li>API gateway;</li>
          <li>sidecar;</li>
          <li>reverse proxy;</li>
          <li>service mesh;</li>
          <li>database commit proxy;</li>
          <li>payment gateway;</li>
          <li>message gateway;</li>
          <li>browser controller;</li>
          <li>operating-system mediator; or</li>
          <li>network egress boundary.</li>
        </ul>
        <t>The implementation is therefore intended to demonstrate that an initial pilot does not necessarily require replacing the model or rewriting every downstream server.</t>
      </section>

      <section anchor="refimpl-altpath">
        <name>Alternate-Path Limitation</name>
        <t>Legacy compatibility does not eliminate the requirement to close bypass paths.</t>
        <t>For example:</t>
        <artwork><![CDATA[
                 +-----> direct tool credential -----> effect
                 |
agent host ------+
                 |
                 +-----> Finality Sink -------------> effect
]]></artwork>
        <t>does not establish execution-finality for that effect.</t>
        <t>If the host can reach the same protected backend through raw credentials, direct HTTP, another SDK, an unwrapped plugin, a subprocess, an alternate MCP client, browser automation, or another route that bypasses the Finality Sink, the security property is limited by that alternate path.</t>
        <t>Production deployment therefore requires the relevant consequential paths to converge upon, or remain subordinate to, the effectuation boundary.</t>
        <t>The reference implementation demonstrates the guarded path. It does not prove that every possible path in an arbitrary production environment has been closed.</t>
      </section>

      <section anchor="refimpl-atomicity">
        <name>Local Atomicity Limitation</name>
        <t>The included SQLite store atomically records consumption of the local authority identifier.</t>
        <t>This demonstrates:</t>
        <artwork><![CDATA[
authority not consumed
        |
        v
atomic consume
        |
        v
second use rejected
]]></artwork>
        <t>It does not make the local database transaction atomic with an arbitrary remote consequence.</t>
        <t>For example:</t>
        <artwork><![CDATA[
consume local authority
        |
        X process/network failure
        |
remote payment or HTTP effect
]]></artwork>
        <t>requires additional production engineering.</t>
        <t>Depending upon the protected consequence, a deployment may require mechanisms such as:</t>
        <ul>
          <li>destination-side Finality Sink verification;</li>
          <li>idempotency keys;</li>
          <li>transactional outbox;</li>
          <li>release credentials;</li>
          <li>two-phase or coordinated commit;</li>
          <li>effect receipts;</li>
          <li>protected delivery acknowledgements; or</li>
          <li>application-specific recovery semantics.</li>
        </ul>
        <t>Those mechanisms are outside the minimal v0.1.0 reference implementation.</t>
      </section>

      <section anchor="refimpl-security-limits">
        <name>Security and Implementation Limitations</name>
        <t>Version 0.1.0 should be understood as a protocol reference implementation, not a production security product.</t>
        <t>It does not claim to provide:</t>
        <ul>
          <li>TEE isolation;</li>
          <li>HSM-protected production keys;</li>
          <li>hardware-rooted attestation;</li>
          <li>production PKI;</li>
          <li>production secret management;</li>
          <li>formal verification;</li>
          <li>side-channel resistance;</li>
          <li>distributed high availability;</li>
          <li>universal bypass prevention;</li>
          <li>production network isolation;</li>
          <li>production vendor integrations;</li>
          <li>penetration-test certification; or</li>
          <li>Internet-scale performance.</li>
        </ul>
        <t>The HMAC authority mechanism, deterministic JSON representation, Python runtime, and SQLite store are implementation choices used to make the architecture executable and independently reviewable.</t>
        <t>They are not normative requirements of the execution-finality architecture.</t>
      </section>

      <section anchor="refimpl-data-limit">
        <name>Data Limitation</name>
        <t>All data in the implementation are synthetic.</t>
        <t>The package does not use:</t>
        <ul>
          <li>real customer records;</li>
          <li>real enterprise credentials;</li>
          <li>real payment accounts;</li>
          <li>real user email;</li>
          <li>production OpenAI data;</li>
          <li>production Anthropic data;</li>
          <li>production MCP data;</li>
          <li>government data; or</li>
          <li>live confidential information.</li>
        </ul>
        <t>A successful test therefore demonstrates deterministic software behaviour against the supplied fixtures.</t>
        <t>It does not constitute production validation using an enterprise dataset.</t>
      </section>

      <section anchor="refimpl-legal-limit">
        <name>Legal and Standards Limitation</name>
        <t>The reference implementation does not determine whether an operation is legally permitted.</t>
        <t>The policy layer receives configured constraints and technically enforces those constraints.</t>
        <t>It therefore demonstrates a machine-enforceable configured constraint rather than an automatic legal determination.</t>
        <t>The repository also does not establish IETF adoption, IETF endorsement, standards conformance, GDPR compliance, EU AI Act compliance, patent validity, patent infringement, standards essentiality, or production certification.</t>
        <t>Any applicable IETF intellectual-property disclosure obligations remain governed separately by the IETF IPR process.</t>
      </section>

      <section anchor="refimpl-privacy-relation">
        <name>Relationship to the Privacy Finality Reference Implementation</name>
        <t>A related public implementation applies the same underlying execution-finality separation to privacy and data-protection constraints:</t>
        <t><eref target="https://github.com/sangmdas/privacy-finality-reference"/></t>
        <t>The privacy implementation and the agentic tool-binding implementation share the underlying sequence:</t>
        <artwork><![CDATA[
Candidate Act
    ->
Non-Effective State
    ->
protected validation
    ->
act-bound authority
    ->
Finality Sink
    ->
external effect
]]></artwork>
        <t>but they exercise different profiles.</t>
        <t>The privacy repository focuses on such properties as purpose binding, minimum-data enforcement, recipient restrictions, destination restrictions, logical data separation, replay protection, and privacy-oriented Finality Sink release.</t>
        <t>The repository referenced by this document focuses instead on tool_use, tool_calls, MCP tools/call, computer-use dispatch, argument substitution, endpoint substitution, single-use tool authority, and the boundary immediately preceding invoke().</t>
        <t>The privacy repository is therefore a related implementation of the common execution-finality substrate, not a substitute for the agentic adapters in this repository.</t>
      </section>

      <section anchor="refimpl-summary">
        <name>What the Reference Implementation Demonstrates</name>
        <t>Within its stated scope, the implementation demonstrates that:</t>
        <ul>
          <li>a tool call can exist without executing;</li>
          <li>a generated tool request can be represented as a Candidate Act;</li>
          <li>live action arguments can be cryptographically bound to the validated Candidate Act;</li>
          <li>authorization can be scoped to a particular act, workload, destination, and sink;</li>
          <li>possession of an authority object alone can be made insufficient through workload proof-of-possession;</li>
          <li>argument mutation can be rejected;</li>
          <li>authority replay can be rejected;</li>
          <li>MCP endpoint substitution can be rejected;</li>
          <li>computer-use origin substitution can be rejected;</li>
          <li>stale policy state can invalidate previously issued authority; and</li>
          <li>invoke() can remain unreachable until the Finality Sink has verified and consumed the required authority.</li>
        </ul>
        <t>The implementation does not demonstrate that every AI safety problem is solved, that every production bypass has been closed, or that every external effect can be made transactionally atomic using the supplied local code.</t>
        <t>Its narrower purpose is to make the architectural proposition executable:</t>
        <blockquote>
          <t>A model may generate a consequential act, but generation of that act does not itself provide the authority required for the act to become externally effective.</t>
        </blockquote>
      </section>
    </section>

    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document requests no IANA actions.</t>
    </section>

    <section anchor="ipr-note">
      <name>Intellectual Property Note</name>
      <t>Related execution-finality concepts appear in the DAS Protocols family, including PCT/IB2026/055615, published as <xref target="DAS-MOTHERSHIP"/>. This statement is provided for technical transparency and does not substitute for any disclosure required through the IETF IPR process. Applicable IETF disclosure obligations are governed by BCP 79 <xref target="RFC8179"/>.</t>
      <t>The broader digital-sovereignty, data-protection, and AI-governance rationale for the execution-finality architecture underlying this binding has also been submitted for public community review to the European Commission's Apply AI Alliance Futurium platform <xref target="DAS-EU-FUTURIUM"/>, and is presented in narrative form in an accompanying public technical disclosure <xref target="DAS-ZENODO-AUTHORITY"/>.</t>
    </section>

    <section anchor="conclusion">
      <name>Conclusion</name>
      <t>Claude will keep emitting tool_use. ChatGPT
      will keep emitting tool_calls. MCP will keep
      emitting tools/call. None of those blocks is
      permission to touch the world. Bind them to
      an AgentCandidateAct, consume authority at
      the host sink, then invoke. The model vendor
      does not have to change. The host loop
      does.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>Normative References</name>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author initials="S." surname="Bradner" fullname="S. Bradner"/>
          <date year="1997" month="March"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author initials="B." surname="Leiba" fullname="B. Leiba"/>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
      </reference>
      <reference anchor="RFC8179" target="https://www.rfc-editor.org/info/rfc8179">
        <front>
          <title>Intellectual Property Rights in IETF Technology</title>
          <author initials="S." surname="Bradner" fullname="S. Bradner"/>
          <author initials="J." surname="Contreras" fullname="J. Contreras"/>
          <date year="2017" month="May"/>
        </front>
        <seriesInfo name="BCP" value="79"/>
        <seriesInfo name="RFC" value="8179"/>
      </reference>
    </references>
    <references>
      <name>Informative References</name>
      <reference anchor="I-D.das-agentic">
        <front>
          <title>Tool Selection Is Not Execution: Finality for Agentic Tool Dispatch</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026" month="August"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-das-agentic-execution-finality-01"/>
      </reference>
      <reference anchor="I-D.das-payment">
        <front>
          <title>A Signed Instruction Is Not Settlement: Finality for Agentic and API Payments</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026" month="August"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-das-payment-execution-finality-00"/>
      </reference>
      <reference anchor="I-D.das-enterprise">
        <front>
          <title>A Compromised AI Server Must Not Become a Map of the Enterprise</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026" month="August"/>
        </front>
        <seriesInfo name="Internet-Draft" value="draft-das-enterprise-ai-output-finality-00"/>
      </reference>
      <reference anchor="DAS-MOTHERSHIP" target="https://patentscope2.wipo.int/search/en/detail.jsf?docId=WO2026150382">
        <front>
          <title>Hardware-Rooted Execution-Finality System for Sovereign Artificial Intelligence Infrastructure, AI-Native Telecommunications and Satellites</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026"/>
        </front>
        <seriesInfo name="WIPO Publication" value="WO 2026/150382"/>
        <seriesInfo name="PCT Application" value="PCT/IB2026/055615"/>
      </reference>
      <reference anchor="DAS-EU-FUTURIUM" target="https://futurium.ec.europa.eu/en/apply-ai-alliance/community-content/protecting-europe-technical-foundation-digital-sovereignty-data-protection-and-ai-governance">
        <front>
          <title>Protecting Europe: A Technical Foundation for Digital Sovereignty, Data Protection, and AI Governance</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026" month="August" day="7"/>
        </front>
        <refcontent>European Commission, Apply AI Alliance, Futurium Community Exchange Platform</refcontent>
      </reference>
      <reference anchor="DAS-ZENODO-AUTHORITY" target="https://doi.org/10.5281/zenodo.22082995">
        <front>
          <title>The Internet Solved Communication. It Never Solved Authority</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026" month="August"/>
        </front>
        <seriesInfo name="DOI" value="10.5281/zenodo.22082995"/>
      </reference>
      <reference anchor="DAS-ISOLATION" target="https://doi.org/10.5281/zenodo.22082925">
        <front>
          <title>Why the Next AI War Will Be Won on Isolation, Not Intelligence</title>
          <author fullname="Sangam Das" initials="S." surname="Das"/>
          <date year="2026"/>
        </front>
        <seriesInfo name="DOI" value="10.5281/zenodo.22082925"/>
      </reference>
    </references>

    <section anchor="appendix-a">
      <name>Appendix A. Execution-Finality Binding in Compact Form</name>
      <t>This appendix is informative. It summarizes the minimum conceptual separation used throughout this document.</t>
      <artwork><![CDATA[
             MODEL / AGENT / APPLICATION
                       |
                       | proposes
                       v
                +---------------+
                | Candidate Act |
                +-------+-------+
                        |
                        | remains non-effective
                        v
              +-------------------+
              | Non-Effective     |
              | State             |
              +---------+---------+
                        |
                        | validate load-bearing state
                        v
              +-------------------+
              | Protected         |
              | Validation        |
              +---------+---------+
                        |
                        | bind scoped authority/evidence
                        v
              +-------------------+
              | Finality Sink     |
              | Verification      |
              +---------+---------+
                        |
                allow   |   deny -> no effect
                        v
              +-------------------+
              | External Effect   |
              +-------------------+
]]></artwork>
      <t>The Candidate Act may be represented using an existing vendor or protocol envelope, but the envelope itself is not treated as effectuation authority. Implementations may use different cryptographic, operating-system, service-side, or hardware mechanisms to realize the protected validation and Finality Sink functions, provided the required security properties of this profile are preserved.</t>

      <section anchor="appendix-a-invariants">
        <name>Core Invariants</name>
        <ol>
          <li>Model or agent output is not, by itself, authority to create an external effect.</li>
          <li>A protected Candidate Act remains non-effective until required validation succeeds.</li>
          <li>Authorization state is associated with the validated act and relevant scope rather than merely with the existence of a model session.</li>
          <li>The effectuation boundary verifies the required state before permitting the consequence.</li>
          <li>Alternate paths capable of producing the same protected effect remain subordinate to the finality boundary or an equivalent protected enforcement mechanism.</li>
          <li>Failure, mismatch, expiration, replay, or unverifiable state results in fail-closed behavior for the protected effect.</li>
        </ol>
      </section>

      <section anchor="appendix-a-mothership">
        <name>DAS Protocols Mothership Context</name>
        <t>The DAS Protocols Mothership <xref target="DAS-MOTHERSHIP"/> is broader than this Internet-Draft. This draft extracts only the tool-dispatch binding needed to express the execution-finality property across contemporary AI tool-use interfaces and MCP-style calls. It should therefore be possible to evaluate, implement, criticize, or standardize this profile independently of the larger disclosure.</t>
        <t>In this profile, the central invariant can be stated compactly as:</t>
        <blockquote>
          <t>Computation is not authority, and authorization is not finality until the effectuation boundary verifies the act-bound state required for the external consequence.</t>
        </blockquote>
      </section>
    </section>
  </back>
</rfc>
