Pull request: Add ERC-8468: Agent Safety Framework (ASF) by garyyang-finchip · Pull Request #2113 · ethereum/ERCs · GitHub (ERC-8468, number assigned on 2026-10-27)
Repository: GitHub - garyyang-finchip/agent-safety-framework: AI Agent Safety Framework · GitHub (reference implementation, schemas, vectors, worked examples, two closed-loop consumers, design memo)
Current text: revision 7 (see the revision note below and the replies that introduce each revision). The revision-7 contracts are deployed and verified on Sepolia (second evidence run, 2026-10-27; see “Closing the loop”).
The gap
Agents now hold credentials, operate accounts and move funds for people and organizations, and the mechanisms that bound them are maturing in several places at once: permission grants and delegations in accounts, regulated mandates, action-bound policy verdicts, identity and reputation registries, decision mechanisms, task escrows. What none of them records is the relation between them: in this task, on these resources, in this execution environment, which participants have accepted which safety requirements, in which version, relying on which evidence, enforced by which mechanism, and whether that acceptance can still be relied upon now.
Without that relation a counterparty either trusts a label or asks for nothing; a requirement written into a document cannot be told apart from one enforced at an execution boundary; an accepted requirement is silently reinterpreted when its publisher releases a new version; and when an arrangement is paused or breached there is no shared way to say what stops, what continues, and who was entitled to intervene.
What the draft standardizes
Two objects, one check, one composition rule. Everything else is consumed from the standards that already provide it; the text requires only ERC-165.
Safety Specification. A versioned, content-addressed document: protected interests (five domains — assets and economic position, information and privacy, control and rules, credit and eligibility, human and public interests — each naming whose interest is protected: principal, operator, counterparty, bystander, public), applicability with permitted and prohibited uses, constraints under named profiles (evaluated over an action, a state, a trajectory, a group or a relation between trajectories), who may adopt and enforce and on what external authority, expected evidence and what it binds, enforcement channels with their location (self, account, runtime, custodian, contract, collective), coverage and known bypasses, failure handling for unknown / denied / dependency failure, pre-accepted remedies (reversibility, intervention window, service continuity, incident reporting), and the profiles a consumer must understand. Versions are immutable; publishing v2 changes nothing for adopters of v1; deprecation is a signal.
Safety Binding. The on-chain statement that an adopter (always msg.sender) adopts one pinned specification version for one subject within one scope, under a named external authority basis, with declared enforcement locations, a validity window, named interveners with explicit rights (suspend / resume / terminate) and a lifecycle: Active, Suspended, Terminated. A suspension records who made it, and a suspension recorded by an intervener is not the adopter’s to lift: only an intervener holding the resume right can lift it, while the adopter keeps the right to terminate (a terminated record keeps showing the stop it carried). An intervener’s suspension is also a standing stop against the adopter for the subject and the specification, keyed by the intervener, and the stop is the intervener’s: it outlives the termination of the binding it was recorded through, widens by union when the intervener suspends another binding of the adopter, is lifted only by that intervener or by the one lifter it named (by no right of the adopter, and not by the resume holders of a binding), and no binding of that adopter for that subject and specification satisfies a clause that names the intervener while it stands — a sibling binding held in advance and a fresh adoption are refused alike. A suspension carries a combinable set of response requirements (no new risk, shrink, essential only, de-risk only, full stop; full stop dominates) and the hash of a structured intervention response document that states who started the response and under which right, what it covers, what it prohibits, allows and keeps running, how in-flight actions are handled, how long it lasts and who may end it. The adopter is part of every identifier and index key, so the registry can never attribute an arrangement to an account that did not accept it; whether the adopter was entitled to adopt for the subject is verified by consumers against the permission source the binding references, never by the registry. Bindings can be derived from a parent (same pinned version, validity inside the parent’s, ancestors must hold, parameters never wider under the profile’s declared order).
The check. check(requirement, bindingIds) evaluates a requirement set (clauses with explicit version lists, adopter, subject, scope, required enforcement locations and required interveners — a resource can insist that someone it trusts is able to stop the subject, and a clause that names interveners also closes the resume right to the accounts it names, so the subject cannot lift a stop through an intervener of its own choosing — combined by all-of / any-of / k-of) and returns Satisfied, NotSatisfied or Unknown with a reason and the response set in force per clause. That set is the union over the binding and its suspended ancestors (empty when the chain is terminated or expired), so a parent’s de-risk-only response reaches derived bindings intact and a full stop anywhere in the chain is visible below it. Pure registry logic — existence, state, validity, pin, adopter, subject, scope, enforcement, required interveners, standing stops by the accounts the clause names, ancestors — no policy is evaluated, Unknown never counts as satisfied, and clause verdicts are never combined into a score. The verdicts and reasons are the registry’s own; when a consumer also reads a permission, policy or validation mechanism, that mechanism’s native result is kept as it is, never normalized into the registry’s vocabulary. Which bindings a resource requires is decided by the resource’s own authority rules; a subject cannot substitute a looser one.
Closing the loop
Two reference consumers show that the relation bites at an execution boundary. ASFGuardedAccount: the operator may act only while the principal’s binding is satisfied; a guardian’s suspension with “no new risk” and “de-risk only” set blocks new exposure while repayment and cancellation still go through; once “full stop” is in the set, everything stops; there is no path that skips the check. ASFTaskTenderAdapter: an acceptance authority for token-bound task tenders that admits only fulfillers holding their own binding with the task publisher as a required intervener, rejects an unbound fulfiller and releases the reservation, rejects a fulfiller whose binding the publisher suspended (the fulfiller cannot lift it), and on Unknown neither accepts nor rejects — the kernel’s own judgment clock stays in force. Both are tested against negative scenarios (93 tests, 67 negative), including derived bindings on the wallet path, the closed resume right and the standing stops on both paths.
The evidence run has been executed on Sepolia twice, against the live TASK-KERNEL v3.0 TaskToken: with the revision-5 contracts on 2026-10-26 (36 transactions) and with the revision-7 contracts on 2026-10-27 (blocks 12003345 to 12003478, 43 transactions, all successful, eight contracts verified on Sourcify with a runtime and a creation match). The second run adds the standing-stop loop of Section 8.5 to the phases of the first: the task publisher stops the worker’s binding (StopRecorded); the worker terminates it, adopts a fresh binding, submits and calls judge itself and is rejected with StoppedByIntervener; the publisher lifts its stop through liftStop (StopLifted, the terminated record untouched); the worker submits again and is accepted and paid as the tender’s second completion. The guard loop shows the revision-7 rule from the other side: the guardian’s suspension of the principal’s binding records the guardian’s stop, and the guardian’s own resume lifts it. Revision-7 addresses: ASFSpecificationRegistry 0x9110b622a17F83065f1e9773D961EB10672932e5, ASFBindingRegistry 0x136E2a88e1B518342CD997423BDa69Dd2c68e919 (libraries ASFEvaluation 0x9b12f62D69EAfc9a240b9AB889cC1647Bf9C56db, ASFLifecycle 0x6a6F645eC9F161735Cc22D441aFD1f513f3b143b), ASFGuardedAccount 0xc88A3FdbC5a4934D335b24416cC9fbF4046e88b0, ASFTaskTenderAdapter 0x015393ECe2E3072055A3Fbe8Fc7f2979B7C7F3Ed. The transaction records, the decoded events and the state read back after each run are in docs/sepolia-evidence-rev7.md and docs/sepolia-evidence.md of the repository; the revision-5 deployment (ASFBindingRegistry 0xc3e1A1Cb021Ab96EBBeD3279018840016114A5c4) stays as it was.
What it deliberately does not do
It does not decide whether an action is permitted, does not evaluate policies, does not certify that an agent is aligned, and does not prove that an arrangement is enforced: declared locations are attributable commitments, evidence and the mechanisms carry the verification. Incident reports, claims and labels have no effect of their own in the framework; only the rules of the consumer that reads them give them one, and the text fixes the consumer rules that keep such records from being used as weapons. It records who accepted what, where, in which version, enforced where, and whether that is in force now — and makes that answer available in one call at the moment of effect.
Analysis basis
The design memo in the repository maps the problem space on three axes used as a multi-label index rather than as an exclusive classification: the seven links of an agent system (substrate, identity, authority, information flow, decision, accountability, collective), the five protected domains above, and six sources of failure. Eight requirement families group the profiles. The memo carries the object-and-authority attribution table, a scenario walkthrough against the test suite, and the overlap and adaptation review against the neighbouring proposals (permissions and delegations, policy verdicts, mandates, identity and reputation, validation, swarm charters, task tenders).
Questions for the thread
- Derived bindings: is the split between the on-chain structural rule and the off-chain profile-order rule acceptable, or should profiles with a declared order be checkable on chain?
- Response requirements: are the five combinable bits plus the structured response document the right shape, or should the response document’s
inFlightrule (what happens to actions already authorized or sent) also be reflected on chain? - Protected domains: the fifth domain, human and public interests with the roles principal / operator / counterparty / bystander / public, replaced a narrower “third parties and the public” domain. Does anyone see an interest that falls outside the five?
- Incident reports and claims stay outside the kernel and have effect only through consumer rules (and, if wanted, an optional profile). Is that the right boundary for a first version?
- Standing stops: an intervener’s stop applies to the adopter for the subject and the specification, keyed by the intervener, and is the intervener’s to lift (itself, or the one lifter it names with
setStopLifter). Is one lifter per intervener, for all its stops, the right granularity, or should a lifter be named per stop? And should a “created before” clause member still be offered for the replacement bindings that no stop concerns?
Feedback on the overlap review with the mandate, verdict, delegation and identity proposals is especially welcome.
Revision note
- Revision 1 (initial filing): two objects, one check, five exclusive suspension restrictions, four protected domains plus “third parties and the public”.
- Revision 2: suspension restrictions became a combinable bit set with a structured intervention response document (
responseRef); the fifth protected domain became human and public interests with protected roles; specifications gained permitted and prohibited uses and the remedies reversibility, intervention window, service continuity and incident reporting; the text now states that native results of external mechanisms are preserved rather than normalized, that identity, representation and legitimate use are established separately, and the consumer rules for incident reports, claims and labels; theIASFBindingRegistryinterface identifier changed accordingly (0xb99bdc2a); the design memo with the three-axis map, the attribution table, the scenario walkthrough and the overlap review was added to the repository. - Revision 3 (after the first review in this thread):
checkreturns the response set in force per clause, defined as the union over the binding and its suspended ancestors and empty when the chain is terminated or expired, and the reference account applies it forSuspendedandParentNotSatisfiedalike (a parent’s de-risk-only response no longer becomes a full stop on derived bindings); clauses gained required interveners (IntervenerMismatch); the registry recordssuspendedBy, and a suspension recorded by an intervener can be lifted only by an intervener holding the resume right, never by the adopter; the tender example requires the task publisher as an intervener; theIASFBindingRegistryinterface identifier is now0x1ff33befandrequirementIdvalues changed with the clause encoding; 82 tests, 56 negative. - Revision 4 (after the second review): a clause that names interveners also closes the resume right — the binding must not grant
RIGHT_RESUMEto any account the clause does not name, otherwise the adopter, who chooses the interveners, could lift any intervener’s suspension through an account of its own; the zero-account wildcard was removed for the same reason; additional suspend-only or terminate-only interveners remain allowed. No interface or encoding change; 84 tests, 58 negative. - Revision 5 (Sepolia): the evidence run was executed on Sepolia against the live TASK-KERNEL v3.0
TaskToken(36 transactions, all successful, seven contracts verified on Sourcify) and recorded in the repository. One reference-implementation change, made so that the registry could be deployed under Sepolia’s current gas schedule and its per-transaction gas cap: the binding registry’s check now runs in the externally linked libraryASFEvaluation, called with the registry’s storage. No change to the text’s normative content, the interfaces, the identifiers, the encodings or the test results. The title of the text is Agent Safety Framework (ASF), as in this thread’s title; revisions 2 to 4 of the pull request had carried “Agent Safety and Security Framework”, and the rationale paragraph on the name now explains the broad sense in which “safety” is used. - Revision 6 (after the third review): an intervener’s suspension is recorded as a standing stop against the adopter for the subject and the specification, keyed by the intervener; it outlives the termination of the binding it was recorded through, is lifted only through a
resumeby an account holding the resume right (also on the terminated record), and a clause that names the intervener is met by no binding of that adopter for that subject and specification while it stands (StoppedByIntervener, with the stop’s response set); terminated records keep their suspension fields;stopOfwas added and theIASFBindingRegistryinterface identifier is now0x2db6eb8a(the clause encoding andrequirementIdvalues are unchanged); the tender example names the publisher with the suspend and the resume right; the registry’s writes moved into a second linked library (ASFLifecycle); 90 tests, 64 negative. The Sepolia deployment remains revision 5’s. - Revision 7 (after the fourth review): the standing stop is the intervener’s. It is lifted only by the intervener that recorded it or by the one lifter the intervener named (
setStopLifter), throughliftStopor through that account’s ownresumeof a binding the intervener suspended; a resume holder on a binding reopens the record and nothing more, and aTerminatedrecord accepts noresume. A later suspension by the same intervener widens the stop by union (set, latest binding, latest response document supplied) instead of replacing it.StopRecorded,StopLifterSetandstopLifterOfwere added,StopLiftedis keyed by the stop, and theIASFBindingRegistryinterface identifier is now0xcff7f826(the clause encoding andrequirementIdvalues are unchanged). 93 tests, 67 negative. The evidence run was then executed on Sepolia a second time with the revision-7 contracts (2026-10-27, 43 transactions including the stop loop, all successful, eight contracts verified on Sourcify;docs/sepolia-evidence-rev7.md); the revision-5 deployment stays as it was.