Repository navigation
Execution-outcome semantics after an ALLOW decision #128
Replies: 2 comments
|
A released host-containment example may add one distinction here: the requested control, the observed effect, and durable evidence of that effect are separate facts. In That implementation suggests wording along these lines:
One limitation is important: Eggcracker's Would a small conformance case that separates "effect not confirmed" from "effect confirmed but durable evidence unavailable" be useful for #128, or is that distinction intentionally deployment-specific? |
|
A data point from a small public lab that tested these states against a real service (GitHub issue comments via the official GitHub MCP server). I'm an independent researcher working from a phone, and my work is developed with substantial LLM assistance. I have not run ACS itself. Repo: github.com/gokuljayaprakash8/kalpang-effect-boundary-lab An authorization was bound by SHA-256 to the exact add_issue_comment request (similar to the action_digest idea in point 3). Three cases, each checked by an independent GitHub REST read:
Case 2 raises a question for #128: if effect_id is derived from the target (here, the issue), a different body could still look like "committed". Is content or value divergence meant to be in scope for effect_outcome, or left to deployments? Also, whose claim is effect_outcome: the tool's own, or an independent observer's? If useful, I can contribute these three cases as conformance vectors. Limits: one platform, unsigned authorization, shared credential domain, simulated substitution. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
steps/toolCallResultgives a Guardianexit_status: success | failure | timeout | blocked,which describes the call. It does not describe the effect. For a tool with a side effect —
a payment, a message, a deletion — the question a control layer has to answer is not "did the
call return?" but "did the thing happen?", and v0.1.0 has no field that carries the difference.
The consequence is concrete, and it is the failure mode most likely to bite a production
deployment that has otherwise done everything ACS asks.
The concrete failure
create_refund(payment_id="txn_1", amount=2000).allowatsteps/toolCallRequest.dropped connection, a load-balancer 502.
steps/toolCallResultwithexit_status: "timeout".treats a non-
successstatus as a failure; a reasonable agent retries.steps/toolCallRequestwith a freshrequest_id. There is nofield linking it to the first call's effect, so it answers
allow.Every step is conformant. The gap is that
timeoutandfailureare statuses of a call, andthe decision that matters is about an effect.
Where the gap sits in the current schemas
hooks/tool-call-result.json—exit_statushas four values, none of which asserts whethera side effect landed.
request_id_refcorrelates a result to its request, which is adifferent relation from identifying the effect both concern.
hooks/tool-call-request.json—tool,operation,capability,arguments,raw_command,intent. Nothing names the effect the call intends, so two calls intending thesame effect are indistinguishable from two calls intending different ones.
intentis aboutwhy the call is being made, which is a different question from which effect it would produce.
ask-details.json— anaskcarries a question and an approver, andintent_extensioncanwiden a capability for
this_requestorsession. Nothing binds the returned decision to acanonical form of the arguments that were asked about, so an approval obtained for
refund(2000)does not, by the schema, refuserefund(5000).specification.md§6 — five dispositions,ALLOW,DENY,MODIFY,ASKandDEFER,all about whether a call proceeds.
DEFERis the nearest thing and it is the Guardian sayingI cannot decide yet, with a resolution method and a timeout. There is no way to record that
an effect's outcome is unresolved, and that further calls against it must be refused until
a human resolves it: that is a fact about the world, not about the Guardian's confidence.
Proposed extension shape
Offered as a shape, not a patch — the exact spelling belongs to the working group.
1. An optional effect identifier on
toolCallRequest.Optional, because plenty of tools are reads. Where present, it lets any Guardian recognise a
repeat without knowing anything about the tool's semantics.
2. A three-state effect outcome on
toolCallResult, besideexit_status.The asymmetry is the point:
committedandnot_executedare claims a tool can make aboutitself, and
unknownis the honest default for everything else — includingtimeout. Aschema that defaults to
unknownin the absence of an explicit claim is fail-closed; one thatdefaults to
not_executedproduces the duplicate above.3. A canonical action digest on
ask_details, echoed by the approval.This closes the mutation path without ACS having to define an authority model: the approver's
answer is bound to what they were shown.
Why this is worth specifying rather than leaving to implementers
Every Guardian that fronts a consequential tool has to answer these questions, and each will
answer them differently and privately. Effect identity in particular is not something an
implementer can add on their own side without cooperation, because the agent is what retries
and the platform is what mints
request_ids. If ACS does not name the concept, twoconformant Guardians in one system will disagree about whether a retry is a repeat.
Not the same as #119
#119 asks the
hooks documentation to state that
exit_statusis a four-value classification and not a numericprocess exit code, with normalization examples. That is worth doing and it is a different point.
This one is that no value of that field, however well documented, answers whether the side
effect landed:
timeoutis a statement about the call, and a committed-then-timed-out refundand a refund that never ran produce the same one.
Prior art / reference implementation
CTRLRun implements all three concepts today — an effect
key derived from a policy template, a three-state outcome with
AMBIGUOUSas a terminal stateonly a human or a reconciliation hook can leave, and approvals bound to a hash covering the
principal, arguments, resource and environment. Its ACS adapter is written against the v0.1.0
schemas and documents this gap at
docs/ACS.md.It is offered as one reference implementation, not as the shape the standard should take.
Idempotency keys in payments APIs (Stripe, Adyen), exactly-once semantics in message brokers,
and two-phase commit all solve the same problem with different vocabulary, and the working
group should draw on whichever fits ACS's model best. The concepts matter; the spelling does
not have to be ours.
Happy to help
I can open a PR against the schemas with a concrete diff, write the conformance cases, or just
leave this as a discussion. Whichever is most useful.
All reactions