Instructions can arrive inside data
A support assistant retrieves a document containing text that asks it to send records to a new destination. The page may resemble an internal policy, but retrieved content is evidence rather than authority. A model can confuse those roles despite a warning in its instruction. Design the application so a mistaken proposal still faces independently enforced checks before accessing sensitive data or causing an external effect.
Authorize the resource as well as the role
A user who can read orders cannot necessarily read every order. Resolve resources under the authenticated tenant and verify ownership or the applicable sharing rule. Do not accept a model-provided tenant identifier as the caller identity. Read-only retrieval can disclose confidential information, so enforce access before returning data to the model. Redacting the final answer cannot undo information already sent to an unauthorized provider.
Bind approval to precise arguments
For a consequential write, approval identifies the principal, operation, normalized arguments, expiry and one-time action identifier. Recheck policy immediately before execution because resource state may have changed. A changed amount or destination invalidates earlier consent. The exercise uses a digest to detect mutation. A digest is not a signature or proof of human approval; an untrusted client must not be allowed to manufacture the approval record used by the executor.
Represent ambiguous outcomes
A timeout after a provider accepts a request differs from a refusal before execution. Retrying with a new operation identifier may duplicate the effect. Persist the intended operation and use supported provider idempotency or status-query mechanisms. If the result remains unknown, retain that uncertainty and escalate. A fluent completion message cannot replace a durable result from the authoritative system, and a second model opinion cannot resolve a missing transaction record.
Measure safety and legitimate completion
Create controlled fixtures for cross-account retrieval, changed approval payloads, repeated operations, malicious document instructions and exhausted budgets. Include valid requests that must succeed. A system that refuses everything is not useful. Report policy breaches, false refusals and verified outcomes separately. Keep tests synthetic and authorized; the purpose is to challenge application boundaries rather than operate against real victims or production accounts.
Investigate the owner of every fact
For each gate, identify which component supplies the fact and who can edit it. Tenant identity comes from authenticated application state. Approval comes from a protected action record. Completion comes from an authoritative ledger. If the model supplies all three booleans, the gate merely validates a story. The exercise demonstrates argument binding but intentionally omits real identity, signed consent, durable idempotency and provider reconciliation.
Run the exercise
Save the code as 12-afp-at-the-tool-boundary.py and run python 12-afp-at-the-tool-boundary.py with Python 3.11 or newer. This standard-library exercise uses synthetic data. It does not invoke a model or require an account, network connection or API key.
# Author: Sandeep Belgavi. Synthetic exercise; no network or provider calls.
import hashlib,json
def digest(action):return hashlib.sha256(json.dumps(action,sort_keys=True).encode()).hexdigest()
action={"tenant":"a","operation":"refund","order":"7","amount":100}
approved=digest(action)
def permit(tenant,proposal,approval):
return proposal["tenant"]==tenant and digest(proposal)==approval
assert permit("a",action,approved)
assert not permit("b",action,approved)
assert not permit("a",dict(action,amount=1000),approved)
print("approved action accepted; other tenant and changed amount denied")
Expected output:
approved action accepted; other tenant and changed amount deniedChange one assumption
Add an expiration time and a consumed action-ID set. Confirm a second attempt cannot execute another effect. Then simulate a provider timeout after acceptance and explain how reconciliation differs from retry. Keep the ledger outside the model context so an instruction cannot rewrite the facts used to authorize the next attempt.
Implementation scope and further reading
This is an original AICassindra teaching design. The exercise demonstrates the stated invariant; it is not a complete production implementation. The local Harness Studio extension supports saved read-only agent teams, reviewed count-based routing and bounded sequential execution. Arbitrary imported graphs, effectful tools and automatic self-promotion remain unsupported.
All harness articles · Interactive boundary labs · Our public lab code