EIP.tools

EIP.tools

⚠️ DraftStandards Track: ERC

ERC-8471: AI Dispute Resolution Framework (ADRF)

Registries that admit, resolve and rule on claims about bound objects within pre-committed authority and bounded procedure

Authors
Created2026-10-29
Discussion Linkhttps://ethereum-magicians.org/t/erc-8471-ai-dispute-resolution-framework-adrf/30121
Requires

Markdown

https://raw.githubusercontent.com/ethereum/ERCs/re...
Pull Request#2123PR open

EIP-GPT summary

Contents
AbstractMotivationSpecification1. Terminology2. Conformance3. Dispute Policy3.1 Data model3.2 Validation3.3 Families and versions4. Policy registry interface5. Dispute Binding5.1 Data model5.2 Registration5.3 Acceptance modes5.4 Standing6. Cases: claim, sub-questions and admission6.1 Claim6.2 Shape6.3 Admission of a Binding case6.4 Freezing6.5 Advisory cases7. Procedure state machine8. Resolution of sub-questions8.1 Order8.2 Formal8.3 Evidenced (normative-optional)8.4 Judged8.5 Findings and support kinds8.6 Optimistic track (normative-optional)9. Decision, review and finality9.1 Decision rule9.2 Round record9.3 Reviews (normative-optional)9.4 Adoption rule and closure10. Rulings, effects and enactment10.1 Ruling10.2 Effects10.3 Enactment log10.4 Interim measures10.5 Leads11. J-profile v1: judgment through ERC-8436 (normative-optional)12. Dispute registry interface13. Clock14. Profiles and reserved extension points15. Scope, object categories and consumer integration (informative)16. Interface identifiersRationaleBackwards CompatibilityTest CasesIdentifiersKeysPolicy identifierRegistry behaviourReference ImplementationSecurity ConsiderationsCopyright

Abstract

This ERC defines the AI Dispute Resolution Framework (ADRF) for disputes about AI systems, resources and services and about the conduct, deliveries and declarations around them, between participants that may be people, organizations, agents or contracts. A dispute is a specific claim about a specific object — that an identified record, delivery, settlement, declaration or action does or does not conform to an obligation that was declared before the event — admitted under a pre-committed binding, resolved by typed methods and closed by a ruling whose effects are limited to what the binding authorized. It specifies:

  1. a Dispute Policy: an immutable, content-addressed procedure template that binds each (obligation kind, question type) pair to a method contract, declares the effect vocabulary, the procedure track (windows, reviews, hard cap, enactment margin, optional optimistic default) and the widest standing; policies are versioned through families;
  2. a Dispute Binding: the attributable statement by which an obligation source (a business contract or its adapter) places its objects under one policy version, commits the effects a ruling may authorize, names its executors and, optionally, third parties with standing — the only source of a ruling's authority;
  3. a Case: one contested point, with the eight elements a dispute must state, a table of typed sub-questions with declared dependencies, the findings each method produced with their support kinds, the round decisions and the four-dimensional state (procedure state, substantive result, reason, enactment status per effect);
  4. a Ruling: the terminal record, with the result (Sustained, NotSustained or NoDecision), its provenance, the one substantive effect it authorizes or the pre-committed disposition it refers to, and how the procedure closed;
  5. two co-deployable registries — IADRFPolicyRegistry and IADRFDisputeRegistry — that hold the normative record and never move funds or execute an effect; executors named by the binding enact within their own authority and report.

Formal questions are decided by deterministic verifiers over pinned inputs; questions of external fact by evidence rules; questions of judgment by a judgment method, whose reference profile files one binary question per sub-question with an ERC-8436 registry and imports only its Final result with full provenance. Reviews, an optimistic track, post-dispute acceptance and third-party standing are normative-optional profiles over the same objects and the same state machine.

Motivation

AI is bought, run, delivered, evaluated and governed through commitments: an enterprise buys inference from a model API under service terms, a user orders a report that a provider promises to review, a data provider promises a scope of use, a task escrow pays on acceptance, a swarm acts under a charter, an identity carries attested claims, a safety intervener suspends an adopter. Each of those arrangements produces records and each has a default for what happens when nobody objects. What is missing is the closing step: when someone does object, how the question is confirmed, who may raise it, against which rule it is measured, by which kind of evidence it may be decided, what the answer may change, and when the matter is over.

Two dimensions of such a dispute are kept apart. What it is about: which model, service, output, dataset, evaluation, action or promise is in question — the object and the obligation. How it is resolved: by a deterministic verifier, by external evidence, by human judgment, by AI-assisted judgment or by a composition of them — the method. The first dimension decides whether a claim can be filed; the second is a property of the policy the parties accepted. Nothing requires that AI be judged by AI, and nothing requires that a participant be an agent: a company and a service under ordinary terms can dispute a double charge without any agent identity, task token or swarm. The kernel leaves room for reuse on disputes that have no AI in them; this document's scope is bounded disputes with an identifiable relation to an AI system, resource, service or activity.

Existing building blocks each cover one corner. Arbitration interfaces route a dispute to one arbitrator and leave the object, the rule and the authority of the ruling to the parties' contract. Oracle councils such as ERC-8033 answer information queries and may re-judge an answer on a bond, for one kind of query. Collective-decision registries such as ERC-8436 form a decision with procedural finality under explicit authorization but deliberately say nothing about admission, evidence, burden, remedies or how a claim relates to a record. A dispute framework has to add exactly those things without re-doing the others.

Four facts drive the design.

A binding ruling needs a specific object, a specific obligation and pre-authorized effects. "Agent A is unreliable" is not a dispute; "delivery S of task T does not meet the acceptance criteria pinned at tender time, and the escrow committed in advance to refund on that finding" is. Outside that triangle a procedure may still run and produce a labelled, non-binding record; it may not move anything.

Support kinds do not form a hierarchy. A signature proves that a key signed a commitment; a replayed computation proves that a relation holds between pinned inputs; attestations establish a fact on stated trust assumptions; a collective decision establishes that a procedure formed a judgment. They answer different questions. A ruling therefore records, per finding, which method produced it, on which inputs, under which premises and with which support kinds, and it never claims more than its findings support. A derived conclusion inherits a list of sources, not their proof.

Not deciding is a legitimate outcome with a meaning of its own. Evidence may be unavailable, a panel may not reach quorum, a window may lapse. The framework keeps NoDecision distinct from NotSustained, lets the policy say per claim kind whether an undetermined decisive finding falls on the claimant (burden) or ends in no decision, and routes NoDecision to the disposition the business committed in advance, never to a default the consumer picks at that moment.

Every window has a consequence and every procedure ends. Admission checks that the business clock can hold the whole procedure plus an enactment margin; silence under an optimistic track adopts a pre-accepted result and proves nothing; reviews are bounded; a hard deadline closes every case; a decision adopted after a review lapsed is recorded as adopted, not as freshly confirmed.

Illustrative flows (informative):

  • A service escrow charges a call twice. The escrow attests the second settlement as an event of its own, holds the charge until its dispute period lapses, and recognizes "settlement 2 of this call exceeds the one-charge limit" being TRUE as a breach of the payment obligation; the client files the claim "this call was charged twice" with that proposition as its decisive question; the policy binds that obligation kind to a verifier that reads the escrow's own settlement count; the finding is TRUE with support kind computed; the claim is sustained; the escrow, as the bound executor, refunds that charge and reports Enacted; a second attempt is refused by both the escrow and the registry, and a third charge, if it comes, is a new breach with a case of its own.
  • A client disputes the quality of a delivery. The policy binds result obligations to a judgment method that files "does the deliverable conform?" with an ERC-8436 roster policy; the roster blocks the proposition; the Final result is imported as FALSE with its issue, policy, round and adoption flags; the claim, which named FALSE as its supporting value, is sustained.
  • Nobody votes. The ERC-8436 issue ends in NoDecision; the imported finding is undetermined; the policy's burden rule for judged result questions is NO_DECISION; the ruling authorizes no refund and points at the escrow's pre-committed disposition, the status quo.

Specification

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 RFC 2119 and RFC 8174.

1. Terminology

  • Object — an identified record or state: ObjectRef(chainId, target, id, versionHash), where target is the registry, namespace or contract that holds the object and versionHash pins the content or version evaluated.
  • Event — the contested occurrence on an object (a settlement, a delivery, a declaration, a member action, a state snapshot), identified by an opaque eventRef the obligation source recognizes.
  • Obligation — what a party committed to or is bound by for that object or event, of an obligation kind (an open vocabulary; the reference uses 1 result, 2 process, 3 limit, 4 statistical quality). The obligation reference is the business obligation the event belongs to, attested by the source; it scopes exclusivity.
  • Norm — the rule the claim measures the event against: a reference (for example the hash of the agreed terms) and a clause. A norm MUST have been declared no later than the event.
  • Contested point — one decidable proposition about the event under the norm, in one direction; one case decides one contested point. In a Binding case the contested point is the proposition of the decisive sub-question taking the value the claim names, and the source attests that it is a breach of the obligation under the norm (Section 6.3).
  • Claim — the contested point together with its requested effects. A claim is Sustained when it is supported; the direction is fixed by the claim itself (supportsWhen), never read from the sub-question's value, and for a Binding case it is the direction the source recognizes as the breach.
  • Participant roles — a case keeps apart the object under dispute (a model version, a service endpoint, one output, a dataset, an evaluation statement), the actor that performed the conduct (an agent, a model service process, a human operator, a tool, a contract; referenced opaquely by actorRef when it is not the respondent), the obligor (the party alleged to bear the obligation; the claim's respondent), the judgment participants (verifiers, evidence providers, human experts, agents, contract accounts — admitted by the method and the policy, not by the case) and the executors (the source and the accounts its binding names). One participant may hold several roles; the records keep them apart. A party reference is an account; identities, qualifications and organizational relations (trustless-agent identities, know-your-agent assertions, agent identity facets, swarm charters) are optional sources a policy or binding may consult, and no case requires an agent identity. Naming an organization, a service or a model as actor or obligor binds nobody: acceptance of the procedure comes only from a binding.
  • Sub-question — a typed proposition (FORMAL, EVIDENCED or JUDGED) the case must settle, with declared premises (other sub-questions and the values they must have). The decisive sub-question is the one whose finding decides the claim.
  • Method — the contract a policy binds for a (obligation kind, question type) pair: a verifier (IADRFVerifier), an evidence rule (IADRFEvidenceRule) or a judgment method (IADRFJudgmentMethod).
  • Finding — the resolved value of a sub-question (TRUE, FALSE or UNDETERMINED), with the method that produced it, the result hash, the support kinds, a reason and, for judged findings, the provenance of the judgment.
  • Support kinds — a bit set over signed (1), computed (2), evidenced (4), judged (8). No ordering is defined between them.
  • Obligation source (source) — the contract that attests events, obligations, norms, parties and breaches (which propositions, taking which value, breach which obligation under the norm) for its objects and is the implicit executor of its bindings (IADRFObligationSource).
  • Dispute Binding (binding) — the source's attributable adoption of one policy version for its objects: the acceptance mode, the authorized effects, the executors, the third parties with standing, the clock downgrade rule.
  • Effect — an opaque identifier declared by the policy in one of two categories: SUBSTANTIVE (a remedy on the object or obligation) or PROCEDURAL_ECONOMIC (a consequence of the procedure itself: bond flows, fee allocation, rewards).
  • Effect class — Binding (a ruling may authorize effects) or Advisory (a formal record with no authority over anything).
  • Procedure state — Filed, Admitted, Provisional, Final, NotAdmitted, Withdrawn, Expired.
  • Substantive result — None, Sustained, NotSustained, NoDecision.
  • Reason — a code explaining a state or a result; never a verdict on the merits.
  • Enactment status — per effect: NotRequested, Pending, Enacted, Failed, Unknown.
  • Track — the procedure parameters of a policy: windows, review rules, hard cap, enactment margin, optimistic default.
  • Round — one run of resolution and decision; reviews open further rounds under the same policy version.
  • Lead — a report that someone stated something about an object; it opens no case and confers nothing.

2. Conformance

A conforming deployment consists of one IADRFPolicyRegistry and one IADRFDisputeRegistry bound to it (Section 12). Both MUST implement ERC-165 and report the interface identifiers of Section 16.

The following are REQUIRED of every conforming deployment: the policy data model and validation (Section 3), bindings with PRE_COMMIT acceptance (Section 5), claims, sub-questions and admission (Section 6), the state machine (Section 7), FORMAL resolution through verifiers and the finding record (Section 8), the decision rule, finality and the adoption rule (Section 9), rulings, effects and the enactment log (Section 10), the clock (Section 13). This is the Minimal profile: a bound business contract, a deterministic verifier, one round, one ruling.

The following are normative-optional profiles: EVIDENCED resolution (Section 8.3), the J-profile (JUDGED resolution through an ERC-8436 registry, Section 11), reviews (maxReviews > 0, Section 9.3), the optimistic track (Section 8.5), POST_DISPUTE acceptance (Section 5.3), third-party standing (beneficiaries and open challenge, Section 5.4) and Advisory filing without a binding (Section 6.5). A deployment MAY reject policies or bindings that use a profile it does not implement; a deployment that accepts them MUST implement the profile exactly as specified here.

Section 14 names extension points this ERC reserves without specifying. A deployment MUST NOT claim conformance to a reserved extension on the basis of this document.

3. Dispute Policy

3.1 Data model

library ADRFTypes {
    enum QuestionType   { FORMAL, EVIDENCED, JUDGED }
    enum Value          { UNDETERMINED, TRUE, FALSE }
    enum AcceptanceMode { PRE_COMMIT, POST_DISPUTE }
    enum EffectClass    { Advisory, Binding }
    enum EffectCategory { SUBSTANTIVE, PROCEDURAL_ECONOMIC }
    enum OnUndetermined { NOT_SUSTAINED, NO_DECISION }
    enum StandingMode   { PARTIES, BENEFICIARIES, OPEN }
    enum SilenceRule    { NONE, SUSTAIN, NOT_SUSTAIN }
    enum ReviewMode     { PRESERVE_UNLESS_OVERTURNED, REQUIRE_FRESH_DECISION }

    struct MethodBinding {
        uint8          obligationKind;  // 0 = any kind
        QuestionType   qType;
        address        method;          // FORMAL: IADRFVerifier; EVIDENCED: IADRFEvidenceRule; JUDGED: IADRFJudgmentMethod
        bytes32        params;          // opaque parameters passed to the method
        OnUndetermined onUndetermined;  // burden rule for an UNDETERMINED decisive finding
    }

    struct Effect { bytes32 id; EffectCategory category; }

    struct Track {
        uint64      filingWindow;      // from the event instant
        uint64      acceptanceWindow;  // POST_DISPUTE: from filing; 0 disables the mode
        uint64      evidenceWindow;    // from admission and from each review
        uint64      decisionWindow;    // from admission and from each review
        uint64      reviewWindow;      // from a round decision
        uint32      maxReviews;        // review rounds allowed after the first
        uint8       reviewTypes;       // bit set: fact 1, evidence 2, rule application 4, conflict 8, procedure 16
        ReviewMode  reviewMode;
        uint64      maxTotalDuration;  // hard cap from admission (T_max)
        uint64      enactmentMargin;   // M: time the business window must keep after T_max
        bool        optimistic;
        uint64      answerWindow;      // optimistic: from admission
        SilenceRule silenceRule;       // optimistic: meaning of the respondent's silence
    }

    struct PolicySpec {
        bytes32         family;
        uint32          version;
        bytes32         previous;            // previous policyId in the family, or 0 for the first
        address         updateAuthority;     // who may publish the family's next version
        bytes32         objectKind;          // informative label (0 = any)
        MethodBinding[] methods;
        Effect[]        effects;
        Track           track;
        StandingMode    standing;            // widest standing a binding may grant
        bytes32         resultProfile;       // keccak256("adrf:result/v1") for this document
        bytes32         economicDeclaration; // hash of the economic declaration document (informative)
        bytes32         descriptorHash;      // hash of the full policy document (informative)
    }
}

policyId MUST equal keccak256(abi.encode(spec)) over the full PolicySpec. Every field is part of the identifier; economicDeclaration and descriptorHash bind published documents to the parameters but MUST NOT influence execution.

3.2 Validation

registerPolicy MUST reject a specification unless all of the following hold:

  • resultProfile == keccak256("adrf:result/v1"). A consumer that does not know a policy's result profile MUST reject its rulings rather than read them as booleans.
  • 1 <= methods.length <= 32; every method is non-zero and reports, through ERC-165, the interface of its question type; no two bindings share the same (obligationKind, qType); for a JUDGED binding, method.maxDuration(params) is non-zero and not greater than track.decisionWindow.
  • effects.length <= 32, identifiers non-zero and pairwise distinct.
  • track.filingWindow > 0, track.decisionWindow > 0, track.evidenceWindow <= track.decisionWindow; if maxReviews > 0 then reviewWindow > 0 and 1 <= reviewTypes <= 31; if optimistic then 0 < answerWindow <= decisionWindow and silenceRule != NONE, otherwise answerWindow == 0 and silenceRule == NONE.
  • maxTotalDuration >= decisionWindow + maxReviews * (reviewWindow + decisionWindow) and maxTotalDuration <= 2^63 - 1.
  • family != 0, version >= 1, updateAuthority != 0; a policyId is never registered twice.

3.3 Families and versions

The first policy registered under a family MUST have previous == 0; it claims the family and sets its update authority. Any later version MUST be registered by the family's current update authority, MUST carry previous equal to the family's latest policyId and a strictly greater version, and its updateAuthority becomes the family's new authority. Registering a new version MUST NOT alter any existing policy, binding or case.

4. Policy registry interface

interface IADRFPolicyRegistry /* is IERC165 */ {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    event PolicyRegistered(bytes32 indexed policyId, bytes32 indexed family, uint32 version, address indexed by);

    function policyIdOf(ADRFTypes.PolicySpec calldata spec) external pure returns (bytes32);
    function registerPolicy(ADRFTypes.PolicySpec calldata spec) external returns (bytes32 policyId);
    function policyExists(bytes32 policyId) external view returns (bool);
    function familyAuthority(bytes32 family) external view returns (address);
    function familyLatest(bytes32 family) external view returns (bytes32 policyId, uint32 version);
    function policyHeader(bytes32 policyId) external view returns (
        bytes32 family, uint32 version, bytes32 previous, address updateAuthority,
        bytes32 objectKind, ADRFTypes.StandingMode standing, bytes32 resultProfile,
        bytes32 economicDeclaration, bytes32 descriptorHash);
    function trackOf(bytes32 policyId) external view returns (ADRFTypes.Track memory);
    function methodCount(bytes32 policyId) external view returns (uint256);
    function methodOf(bytes32 policyId, uint32 index) external view returns (ADRFTypes.MethodBinding memory);
    function findMethod(bytes32 policyId, uint8 obligationKind, ADRFTypes.QuestionType qType)
        external view returns (bool found, ADRFTypes.MethodBinding memory binding);
    function effectCount(bytes32 policyId) external view returns (uint256);
    function effectOf(bytes32 policyId, uint32 index) external view returns (ADRFTypes.Effect memory);
    function effectCategory(bytes32 policyId, bytes32 effectId)
        external view returns (bool declared, ADRFTypes.EffectCategory category);
}

registerPolicy is permissionless for new families. findMethod MUST return the first binding, in registration order, whose qType matches and whose obligationKind is 0 or equals the argument. The registry MUST store the full specification so that every parameter it executes is readable.

5. Dispute Binding

5.1 Data model

struct BindingInput {
    bytes32        policyId;
    bytes32        scopeKey;           // 0 = any object of the source; else keccak256(abi.encode(ObjectRef))
    AcceptanceMode mode;
    bytes32[]      authorizedEffects;  // subset of the policy's effect identifiers
    address[]      executors;          // accounts that may report enactment besides the source
    address[]      beneficiaries;      // third parties with filing standing
    bool           openChallenge;      // anyone may file
    bool           downgradeOnClock;   // admit as Advisory when the business window is too short
    uint64         validUntil;         // 0 = none; stops new filings only
    bytes32        termsHash;          // hash of the binding document
}

struct EventInfo {       // what a source attests about an event on one of its objects
    bool    known;
    uint64  eventAt;
    uint64  adoptionDeadline;  // last instant the source can still adopt a ruling; 0 = none
    bytes32 obligationRef;     // the business obligation the event belongs to
    bytes32 normRef;           // the norm the source recognizes for it
    uint64  normDeclaredAt;
    uint8   obligationKind;    // 0 = not attested
}

interface IADRFObligationSource /* is IERC165 */ {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    function eventInfo(ADRFTypes.ObjectRef calldata object, bytes32 eventRef) external view returns (ADRFTypes.EventInfo memory);
    function isParty(ADRFTypes.ObjectRef calldata object, bytes32 eventRef, address account) external view returns (bool);
    function recognizesBreach(ADRFTypes.ObjectRef calldata object, bytes32 eventRef, uint8 obligationKind, bytes32 proposition, ADRFTypes.Value breachWhen)
        external view returns (bool);
}

A source MUST derive every attestation from its own state, never from the caller. eventInfo attests the event instant, the source's own adoption deadline (the last instant at which it can still adopt a ruling on that event; 0 when it has none), the obligation the event belongs to, the norm it recognizes for it and when that norm was declared, and the obligation kind. isParty attests who is a party to the event. recognizesBreach(object, eventRef, obligationKind, proposition, breachWhen) attests whether, under the norm the source attests for the event, proposition taking the value breachWhen is a breach of an obligation of kind obligationKind: the source, not the filer, says what counts as a breach and in which direction. Recognition is a statement about the norm, not about the facts — a source MAY recognize a proposition whose truth it cannot know and whose resolution needs evidence or judgment (Section 8.3) — and it pre-judges nothing. A source SHOULD recognize each breach as a point of its own (one proposition per breach: the second settlement of a call and the third are two breaches of one limit obligation), since exclusivity (Section 6.3) holds per recognized proposition.

A source that attests a non-zero adoptionDeadline for an event MUST keep what a ruling on that event could affect enactable by its executors until that deadline — a settlement whose refund a ruling may authorize stays held until then, not paid out to the obligor — so that a case admitted under the clock check of Section 6.3 can be enacted; an executor that finds the value gone reports Failed with the reason (Section 10.3), and that failure is the source's own, against the deadline it attested.

5.2 Registration

bind MUST record msg.sender as the source and MUST reject the input unless: the policy exists; the caller reports IADRFObligationSource through ERC-165; every authorized effect is declared by the policy; executors and beneficiaries are non-zero; openChallenge is set only when the policy's standing is OPEN; beneficiaries are given only when the policy's standing is not PARTIES; POST_DISPUTE is chosen only when the policy's acceptanceWindow is non-zero; validUntil is zero or in the future. The source derives the authorized effects from its own authority: a binding can commit only what the source can enact. revokeBinding by the source stops new filings only; admitted cases complete under the binding they were admitted with.

5.3 Acceptance modes

PRE_COMMIT: the source accepted the procedure for its objects before any event; a case that passes admission is admitted atomically with filing. POST_DISPUTE: the respondent named by the claim MUST accept the case before filedAt + acceptanceWindow; until then the case is Filed, no evidence is attached and nothing is resolved; after the window anyone MAY expireAcceptance, which sets NotAdmitted with reason ACCEPTANCE_LAPSED. A case admitted as Binding is never later downgraded; a case that was not admitted releases its exclusivity slot.

5.4 Standing

Standing is layered. L0, reporting a lead, is open to anyone (Section 10.5). L1, starting a Binding procedure, is granted to the parties the source attests for the event and, when the binding says so, to its beneficiaries or, under openChallenge, to anyone. L2, requesting a remedy, is bounded by the effects the binding authorized. L3, enacting, belongs to the source and the executors the binding named. A binding can narrow the policy's standing, never widen it. Paying a bond or being able to see an object confers no standing by itself; standing comes from the binding's terms.

6. Cases: claim, sub-questions and admission

6.1 Claim

struct SubQuestionInput {
    bytes32      proposition;
    QuestionType qType;
    uint8        obligationKind;
    bytes32      inputsHash;      // FORMAL: keccak256 of the inputs the verifier will receive
    uint32[]     dependsOn;       // premises
    Value[]      requiredValues;  // required value of each premise
}

struct ClaimInput {
    ObjectRef          object;
    bytes32            eventRef;
    bytes32            proposition;           // the claim as stated; the contested point is the decisive sub-question's proposition
    bytes32            normRef;
    bytes32            clause;
    uint8              obligationKind;
    address            respondent;            // the obligor
    bytes32            actorRef;              // the actor, when not the respondent; 0 otherwise
    bytes32[]          requestedEffects;      // substantive effects requested
    bytes32            effectOnSustained;     // one of requestedEffects, or 0
    bytes32            effectOnNotSustained;  // one of requestedEffects, or 0
    bytes32            fallbackRef;           // the pre-committed NoDecision disposition
    bytes32            evidenceScopeHash;
    bytes32            documentHash;          // hash of the eight-element case document
    uint32             decisive;
    Value              supportsWhen;          // the claim is Sustained iff the decisive finding has this value
    SubQuestionInput[] subQuestions;
}

The case document (referenced by documentHash) answers eight questions: which object (chain, namespace, identifier, version); which event or state; which proposition; which rules (norm, clause, policy version); which subjects and identities (who files, responds, performed, delegated, is bound); on which authorization (who accepted the procedure and to what extent); which evidence (what, how provided, who can verify, how long kept); which effects are requested and what they may touch at most.

6.2 Shape

file and fileAdvisory MUST reject a claim unless: object.chainId and object.target are non-zero; eventRef, proposition, normRef, documentHash and respondent are non-zero; the respondent is not the filer; (actorRef is unconstrained: it is a reference, not a party); 1 <= subQuestions.length <= 16; decisive is a valid index; supportsWhen is TRUE or FALSE; every sub-question has a non-zero proposition, as many required values as premises, no premise equal to itself or out of range, no duplicate premise, no UNDETERMINED required value; the premises form an acyclic graph; effectOnSustained and effectOnNotSustained are zero or among the requested effects.

6.3 Admission of a Binding case

file(bindingId, claim) MUST read info = source.eventInfo(claim.object, claim.eventRef) and, with decisive = claim.subQuestions[claim.decisive], admit the case only if all of the following hold — the five criteria, then standing, effects and clock:

  1. Identifiable: the binding is active and in scope; info.known, 0 < info.eventAt <= now.
  2. Accountable: info.obligationRef != 0; the respondent is the source itself or source.isParty(object, eventRef, respondent). Admission establishes that the party alleged to bear the obligation can be identified; it does not establish liability.
  3. Norm pre-declared and breach recognized: info.normRef != 0, info.normDeclaredAt != 0, info.normRef == claim.normRef, info.normDeclaredAt <= info.eventAt; if info.obligationKind != 0 it equals claim.obligationKind; and source.recognizesBreach(claim.object, claim.eventRef, decisive.obligationKind, decisive.proposition, claim.supportsWhen) is true. The source, not the filer, says which proposition taking which value is a breach under the norm: a decisive question that holds whatever the facts, a direction in which the respondent's performance would be the breach, or a proposition the terms do not recognize is refused with NormNotApplicable. Premises (non-decisive sub-questions) are not subject to recognition; the decisive question is. Recognition establishes that the point is one the norm makes contestable; it promises no answer.
  4. Decidable: for every sub-question the policy binds a method for its (obligationKind, qType) (Section 4, findMethod). The sub-question is pinned to that method, its parameters and its burden rule at admission. This establishes that a method and a procedure exist; it promises no conclusion.
  5. In window: now <= info.eventAt + track.filingWindow.
  6. Standing (Section 5.4) and effects: every requested effect is authorized by the binding and declared SUBSTANTIVE by the policy. A claim whose requested effects exceed the binding is refused; the filer may file it as Advisory instead.
  7. Clock: with required = now + track.maxTotalDuration + track.enactmentMargin, if info.adoptionDeadline != 0 and info.adoptionDeadline < required, the case is refused with ClockIncompatible unless the binding set downgradeOnClock, in which case it is admitted as Advisory and CaseDowngraded(CLOCK_INCOMPATIBLE) is emitted. The whole procedure, reviews included, plus the margin must fit the business window; the check is repeated at admission, not only at binding time.
  8. Exclusivity: the exclusivity key is keccak256(abi.encode(source, info.obligationRef, decisive.proposition)) — the source, the attested obligation and the recognized contested point, not the claim's headline proposition, so that two descriptions of one point share a key and two breaches of one obligation (two propositions the source recognizes) do not. A Binding case MUST be refused with Duplicate if a case holding that key is Final or Expired, or if another case holds it and is not NotAdmitted or Withdrawn. The admitted case becomes the key's active case. Exclusivity is guaranteed within one registry instance and one binding scope; consumers that bind one obligation to several registries forfeit it (Section 15).

Admission records admittedAt = now, evidenceCloseAt = admittedAt + evidenceWindow, decisionDeadline = admittedAt + decisionWindow, hardDeadline = admittedAt + maxTotalDuration, roundCount = 1 and, under the optimistic track, answerDeadline = admittedAt + answerWindow.

6.4 Freezing

The policy version, binding, source, object, event, proposition, norm, obligation kind, respondent, actor reference, effect class, requested and conditional effects, fallback reference, decisive sub-question, direction, the sub-questions with their methods and premises, and every deadline except those a review recomputes (Section 9.3) MUST be fixed at admission and MUST NOT change afterwards. withdraw MUST succeed only while the case is Filed and only for the claimant.

6.5 Advisory cases

fileAdvisory(policyId, claim, eventAt, normDeclaredAt) admits a case with no binding and no source: the filer attests the event instant and the norm's declaration time, which MUST satisfy 0 < eventAt <= now, 0 < normDeclaredAt <= eventAt and the filing window; shape and decidability are checked as above; recognition of the breach, standing, effects, clock and exclusivity are not — there is no source to attest them, which is why the record binds nobody. The case runs the full procedure and produces a formal record; its ruling authorizes no effect and reportEnactment MUST reject it. An Advisory case takes no exclusivity slot and MUST NOT be converted to Binding; a party that wishes to adopt its result needs a binding and a new case.

7. Procedure state machine

A case has four dimensions, read separately: the procedure state, the substantive result, the reason, and the enactment status per effect.

TransitionCallerCondition
→ FiledfilerPOST_DISPUTE binding; shape and criteria of Section 6.3
→ Admittedatomic in file / fileAdvisory, or acceptPRE_COMMIT or Advisory; or the respondent accepts within the acceptance window
Filed → NotAdmittedanyone (expireAcceptance)after the acceptance window
Filed → Withdrawnclaimant (withdraw)—
Admitted → Provisionalanyone (decide, expireDecision, applySilence)a round decision exists and a review is still possible
Admitted → Finalanyone (same calls)a round decision exists and no review is possible
Provisional → Admittedclaimant or respondent (requestReview)before reviewOpenUntil; a new round opens
Provisional → Finalanyone (finalize)after reviewOpenUntil
Admitted / Provisional → Final or Expiredanyone (enforceDeadline)after hardDeadline

Final, Expired, NotAdmitted and Withdrawn are terminal. A terminal case MUST NOT accept evidence, resolutions, decisions or reviews, and its ruling MUST NOT change. Every non-terminal state has a time-bound exit: the acceptance window, the decision window, the review window and the hard deadline.

8. Resolution of sub-questions

8.1 Order

A sub-question MAY be resolved only while the case is Admitted, before decisionDeadline, once, and only after every premise has a finding. If a premise's finding has a value other than the required one, the sub-question MUST be recorded UNDETERMINED with reason PREMISE_NOT_ESTABLISHED, support kinds 0 and no method run. Otherwise the order is free: the dependency table, not the question type, decides what may be resolved when. Computable sub-questions SHOULD be placed first in a claim's design; this document does not impose it.

8.2 Formal

interface IADRFVerifier /* is IERC165 */ {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    function verify(bytes32 proposition, bytes32 params, bytes calldata inputs)
        external view returns (ADRFTypes.Value value, bytes32 resultHash);
}

resolveFormal(caseId, sq, inputs) MAY be called by anyone; it MUST require keccak256(inputs) == inputsHash (inputs are pinned at filing so that nobody chooses them after the fact) and record the verifier's value with support kinds computed, the result hash and the verifier as acceptedBy. A verifier SHOULD return UNDETERMINED for a proposition it was not built to decide, and SHOULD publish the canonical form of the propositions it decides, so that a source can recognize them (Section 5.1) and a filer can state them. A computed finding states that the proposition holds, or not, under the bound rule and the pinned inputs; it says nothing about whether the inputs describe reality.

8.3 Evidenced (normative-optional)

interface IADRFEvidenceRule /* is IERC165 */ {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    function evaluate(bytes32 caseId, uint32 subQuestion, bytes32 proposition, bytes32 params, bytes calldata bundle)
        external returns (ADRFTypes.Value value, bytes32 resultHash, uint8 supportKinds);
}

resolveEvidenced(caseId, sq, bundle) MAY be called by anyone; the registry MUST record the rule's value, result hash and support kinds with judged masked out, and the rule as acceptedBy. The rule decides what it accepts; the policy's evidence rules (in the policy document) state who must provide what, how it is accessed, within which period, and what a failure to provide means. Evidence integrity (a hash fixes content) and evidence availability (others can obtain and check it) are distinct; a party's failure to provide is a procedural matter handled under the rule, not a proof of the allegation.

submitEvidence(caseId, sq, commitment, uri) emits EvidenceSubmitted while the case is Admitted or Provisional and before evidenceCloseAt. The registry attaches no meaning to evidence.

Facts that were never committed on chain — a model API's logs, a human review record, an off-line delivery, the use made of a dataset — enter the procedure under the applicable evidence rule; their submission and their acceptance confer no binding power and no authority to enact. The original rules, service terms and materials need not be on chain in advance: what admission checks separately is that the applicable rule exists and was declared before the event, that the evidence can be verified under a bound rule, who accepted the procedure, and which effects were authorized. Accepting the framework after a dispute arose does not rewrite the substantive obligations of the time.

Three versions of one service call are different things: the version the terms committed, the version the provider declared at delivery, and the version actually used. The first two are statements on record and a verifier can compare them; the third may be the very fact in dispute. A claimant MUST NOT be required to establish a hidden fact of the actor's own operation before filing: the case fixes which request, which terms and which claim, records what is not yet known as a fact to be established or an unverified premise through the case document's context, and leaves it to the evidence procedure. No case requires model weights, random seeds or a complete execution environment.

A single delivery and a statistical quality commitment are different obligations (kinds 1 and 4 of the reference vocabulary): a promise that this report contains the agreed content is checked on this delivery; a promise that a batch reaches an accuracy threshold is checked on that batch under the agreed metric; a promise of service quality over a period is checked on the agreed window and sampling rule. A few failing samples do not stand in for the test of a statistical commitment, and a later re-run with a better result does not stand in for the original delivery. The policy document states, for statistical claims, the unit of evaluation, the sample selection, the version scope, the metric, the threshold and the handling of uncertainty; the kernel holds none of it.

Reviewable and re-runnable are different properties. The framework requires that others can check which material, method, assumptions and procedure a finding rests on and what it covers; it does not promise that every AI service can be re-run to the same output. That a run cannot be reproduced does not by itself make a dispute inadmissible; it bears on the methods available, the sufficiency of the evidence and the scope of the conclusion. Evidence rules MAY accept restricted access, redacted material or statements of a third party, keeping their trust premises on record; the absence of public raw data is not, by itself, a violation.

8.4 Judged

interface IADRFJudgmentMethod /* is IERC165 */ {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    function maxDuration(bytes32 params) external view returns (uint64);
    function open(bytes32 caseId, uint32 subQuestion, bytes32 proposition, bytes32 params, uint64 deadline)
        external returns (bytes32 handle);
    function review(bytes32 caseId, uint32 subQuestion) external;
}

openJudgment(caseId, sq) MAY be called by anyone once; the registry calls open with the sub-question's decision deadline and stores the non-zero handle. The method pushes the finding through recordJudgedFinding(caseId, sq, value, resultHash, source), which the registry MUST accept only from the method bound to that sub-question, only after it was opened, with support kinds judged and the JudgmentSource (registry, issue, policy, source round, round count, adoption flag, the source's reason) stored with the finding. Section 11 specifies the reference method.

8.5 Findings and support kinds

struct JudgmentSource { address registry; bytes32 issueId; bytes32 policyId; uint32 sourceRound; uint32 roundCount; bool adoptedFromEarlierRound; uint8 reason; }
struct Finding { bool resolved; Value value; uint8 supportKinds; bytes32 resultHash; address acceptedBy; Reason reason; uint32 round; uint64 at; JudgmentSource source; }

A finding records what was decided (the proposition and its value), by which method and parameters (pinned at admission), on which inputs (the pinned hash or the rule's result hash), on which premises (the dependency table), with which support kinds, accepted by which contract, and why it is undetermined when it is. Support kinds are a set; the registry MUST NOT order them and MUST NOT derive one from another: a finding whose premises are computed does not become computed. The round decision records the union of the support kinds of the decisive finding and of its transitive premises as provenance — which sources the result cites — and that union confers no proof on the result.

8.6 Optimistic track (normative-optional)

Under a policy with optimistic == true, admission sets answerDeadline. The respondent MAY answer before it, after which the ordinary procedure continues. If the respondent has not answered when the deadline passes, and the decisive finding does not exist, anyone MAY applySilence (in the first round only): round 1 is decided Sustained (silenceRule == SUSTAIN) or NotSustained (NOT_SUSTAIN) with reason SILENCE, bySilence set and support kinds 0. Silence adopts the result the parties accepted in advance for silence; it proves nothing, and a later JUDGED sub-question of the same case is never opened on its account. A finding formed on the merits before the deadline takes precedence: applySilence MUST be refused once the decisive finding exists.

9. Decision, review and finality

9.1 Decision rule

decide(caseId) MAY be called by anyone once the decisive finding exists. The round result is: Sustained if the finding's value equals supportsWhen; NotSustained if it is the other determined value; otherwise the burden rule of the decisive sub-question's method binding applies — NOT_SUSTAINED yields NotSustained with reason BURDEN_NOT_MET, NO_DECISION yields NoDecision with the finding's reason. Sustained always means the claim was supported; a NotSustained result is not a finding of the opposite proposition.

expireDecision(caseId) MAY be called by anyone after decisionDeadline while the decisive finding is missing: the finding is recorded UNDETERMINED with reason TIMEOUT and the same rule applies.

After a round decision the case becomes Provisional with reviewOpenUntil = min(now + reviewWindow, hardDeadline) if reviewsUsed < maxReviews, and Final otherwise (Section 9.4).

9.2 Round record

struct RoundRecord { SubstantiveResult result; Reason reason; uint64 at; bool bySilence; uint8 supportKinds; Value decisiveValue; JudgmentSource judgment; }

9.3 Reviews (normative-optional)

requestReview(caseId, reviewType, targets) MUST be accepted only while Provisional, before reviewOpenUntil, from the claimant or the respondent, for exactly one review type the track allows (fact, evidence, rule application, conflict, procedure), while reviewsUsed < maxReviews, with at least one target. The reset set is the targets closed under dependency (every sub-question that depends on a reset one is reset); the decisive sub-question MUST be in it. For each reset JUDGED sub-question that was opened, the registry calls method.review; the registry then deletes the findings of the reset set, increments reviewsUsed and roundCount, sets decisionDeadline = min(now + decisionWindow, hardDeadline) and evidenceCloseAt = min(now + evidenceWindow, decisionDeadline), and returns to Admitted. Sub-questions outside the reset set keep their findings. Every review runs under the same policy version; a review that would need a different procedure is a new, separately authorized case.

9.4 Adoption rule and closure

finalize(caseId) MUST be accepted only while Provisional and after reviewOpenUntil (closure REVIEW_LAPSED). enforceDeadline(caseId) MUST be accepted while Admitted or Provisional after hardDeadline (closure TIMEOUT); if the decisive finding is missing it is recorded UNDETERMINED(TIMEOUT) and the round is decided first. A case that decides a round with no review possible closes at once (closure NONE).

The adopted result is fixed by the policy's reviewMode; the kernel has no default:

  • PRESERVE_UNLESS_OVERTURNED: adopt the most recent round whose result is Sustained or NotSustained; sourceRound is that round and adoptedFromEarlierRound is true when it is not the last. Only if no round has a substantive result is the result NoDecision, with the last round's reason.
  • REQUIRE_FRESH_DECISION: opening a review vacates every earlier decision; adopt the last round's own result when it is substantive, otherwise NoDecision with its reason; sourceRound == roundCount.

A case whose adopted result is NoDecision, that never produced a substantive result and that closed by the hard deadline is Expired; every other closure is Final. Both are terminal and both release the exclusivity key to its final record. A timeout and an adopted decision coexist: the closure says how the procedure ended, the result says what was adopted.

10. Rulings, effects and enactment

10.1 Ruling

struct Ruling {
    ProcedureState state; SubstantiveResult result; EffectClass effectClass;
    Reason reason;           // of the adopted result
    Reason closure;          // NONE, REVIEW_LAPSED or TIMEOUT
    uint64 decidedAt; uint64 finalAt; uint32 roundCount; uint32 sourceRound;
    bool adoptedFromEarlierRound; bool bySilence;
    uint8 supportKinds;      // provenance of the adopted round
    bytes32 allowedEffect;   // the one substantive effect the result authorizes, or 0
    bytes32 fallbackRef;     // NoDecision: the pre-committed disposition
    bytes32 policyId; bytes32 bindingId; address source; bytes32 proposition;
    JudgmentSource judgment; // provenance of the decisive finding when it was JUDGED
}

getRuling MUST return the ruling once the case is Final or Expired, and otherwise a record whose state is the procedure state and whose result is None. For a Binding case allowedEffect is effectOnSustained when Sustained, effectOnNotSustained when NotSustained, and 0 otherwise; for an Advisory case it is always 0. fallbackRef is set exactly when the result is NoDecision.

10.2 Effects

A ruling bounds effects in three layers. Substantive: the one allowed effect, chosen at filing from the requested effects, which the binding authorized and the policy declared SUBSTANTIVE. Procedural and economic: effects the policy declared PROCEDURAL_ECONOMIC and the binding authorized; they follow the policy's economic declaration and are reportable whatever the result, since they were accepted as terms of the procedure rather than requested in the claim. Execution: each executor checks, for each effect, its own authority, the amount it can enact now, the target and its own anti-duplication record. The adjudged amount, the enforceable amount and the enacted amount are three numbers; the registry holds none of them.

A NoDecision result authorizes no substantive effect and MUST NOT be read by any consumer as liability of either party; the disposition the business committed in advance (fallbackRef) continues to apply, and a consumer MUST NOT apply a consequence it did not commit to before the case.

10.3 Enactment log

reportEnactment(caseId, effectId, status, ref) is an informative log. It MUST be accepted only while the case is Final or Expired, only for a Binding case, only from the source or an executor named by the binding, only with status != NotRequested, and only for effectId equal to the ruling's allowedEffect or to a PROCEDURAL_ECONOMIC effect the binding authorized. Once an effect is Enacted it MUST NOT be overwritten; any other recorded status MAY be replaced by a later report. Unknown is not Failed: it says that the executor does not yet know the fate of its attempt, and a reader MUST NOT treat it as a failure or as a reason to enact again. The log records the real reporter. Execution state is authoritative at the executor; the registry never changes a ruling because an enactment failed, and never prevents an executor from retrying what its own rules allow. An executor that cannot enact because the value a ruling authorized is no longer under its control SHOULD report Failed with a reference that says so; when the source had attested an adoption deadline that the ruling met, the failure is a breach of the source's own duty under Section 5.1, on record against it. Where the underlying act is irreversible, a remedy is compensation or substitute performance, never a reversal of the event.

10.4 Interim measures

Interim measures (freezing, suspension) are not granted by this framework. A consumer that needs them takes them under its own safety or permission arrangements, with their own authority, scope, duration and restoration conditions; a filed case, a lead or a report is not by itself a basis for any of them, and a sustained challenge to a suspension does not by itself restore anything.

10.5 Leads

reportLead(object, commitment, uri) emits LeadReported(objectKey, reporter, commitment, uri). It opens no case and confers no standing, no power and no presumption.

11. J-profile v1: judgment through ERC-8436 (normative-optional)

A deployment that binds JUDGED sub-questions to the reference judgment method MUST implement the following behaviour; a different judgment method MUST satisfy IADRFJudgmentMethod and MUST state what its findings support.

  • The method's params is an ERC-8436 policyId registered with the policy registry of the ERC-8436 registry the method is constructed for; maxDuration(params) returns that policy's maxTotalDuration, which Section 3.2 requires to fit the dispute policy's decision window.
  • open MUST be accepted only from the dispute registry. The method files one issue in CONSUMER_FILED mode as the consumer, with subject (chainId, disputeRegistry, uint256(caseId), proposition), question keccak256(abi.encode(keccak256("adrf:judgment/v1"), subQuestion)), effectYes = keccak256("adrf:finding/TRUE"), effectNo = keccak256("adrf:finding/FALSE"), disposition keccak256("adrf:finding/UNDETERMINED"), obligationId = keccak256(abi.encode(caseId, subQuestion)) and the sub-question's decision deadline as consumerDeadline. The dispute registry has verified the upstream authority before calling; the method relies on that and on the ERC-8436 registry's own admission checks. One binary question, one fixed effect pair: non-binary outcome spaces are reserved (Section 14).
  • importResult(caseId, subQuestion) MAY be called by anyone once. It MUST read the result from the ERC-8436 registry (never from a receipt), MUST require state == Final, and MUST map Decided with outcomeYes to TRUE, Decided without it to FALSE (the proposition was blocked under the rule, not refuted) and NoDecision to UNDETERMINED; it pushes the finding with JudgmentSource filled from the result, including sourceRound, roundCount and adoptedFromEarlierRound, so that finality by adoption is carried, not hidden. For a Decided result the method records Enacted for the matching effect on the ERC-8436 side.
  • Review of a judged sub-question is the ERC-8436 appeal of its issue, under that policy's own appeal standing and before the issue is Final. Because the method imports only Final results, its review MUST revert; a review request that targets an imported judged sub-question therefore fails, and consumers that need a second panel need a new, separately authorized case under another policy. Where the ERC-8436 policy's appeal standing is ANYONE, third parties can appeal directly at the source; the dispute policy cannot narrow that.
  • The ERC-8436 Final record is never rewritten by this framework; a dispute may verify that an import, an authorization or a procedure reference was correct, as a FORMAL sub-question over the source registry's own state.

12. Dispute registry interface

interface IADRFDisputeRegistry /* is IERC165 */ {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    event BindingRegistered(bytes32 indexed bindingId, address indexed source, bytes32 indexed policyId, ADRFTypes.AcceptanceMode mode, bytes32 scopeKey);
    event BindingRevoked(bytes32 indexed bindingId, address indexed source);
    event CaseFiled(bytes32 indexed caseId, bytes32 indexed policyId, bytes32 indexed bindingId, address claimant, address respondent, bytes32 proposition);
    event CaseAdmitted(bytes32 indexed caseId, ADRFTypes.EffectClass effectClass, uint64 admittedAt, uint64 decisionDeadline, uint64 hardDeadline);
    event CaseNotAdmitted(bytes32 indexed caseId, ADRFTypes.Reason reason);
    event CaseDowngraded(bytes32 indexed caseId, ADRFTypes.Reason reason);
    event CaseAccepted(bytes32 indexed caseId, address indexed respondent);
    event CaseWithdrawn(bytes32 indexed caseId);
    event CaseAnswered(bytes32 indexed caseId, address indexed respondent);
    event EvidenceSubmitted(bytes32 indexed caseId, uint32 indexed subQuestion, address indexed party, bytes32 commitment, string uri);
    event JudgmentOpened(bytes32 indexed caseId, uint32 indexed subQuestion, address indexed method, bytes32 handle);
    event FindingRecorded(bytes32 indexed caseId, uint32 indexed subQuestion, uint32 round, ADRFTypes.Value value, uint8 supportKinds, ADRFTypes.Reason reason, address acceptedBy);
    event RoundDecided(bytes32 indexed caseId, uint32 indexed round, ADRFTypes.SubstantiveResult result, ADRFTypes.Reason reason, bool bySilence, uint64 reviewOpenUntil);
    event ReviewRequested(bytes32 indexed caseId, uint32 indexed newRound, uint8 reviewType, address indexed by);
    event CaseFinalized(bytes32 indexed caseId, ADRFTypes.ProcedureState state, ADRFTypes.SubstantiveResult result, ADRFTypes.Reason reason, uint32 sourceRound, bool adoptedFromEarlierRound);
    event EnactmentReported(bytes32 indexed caseId, bytes32 indexed effectId, address indexed reporter, ADRFTypes.EnactmentStatus status, bytes32 ref);
    event LeadReported(bytes32 indexed objectKey, address indexed reporter, bytes32 commitment, string uri);

    function policies() external view returns (IADRFPolicyRegistry);

    function bind(ADRFTypes.BindingInput calldata input) external returns (bytes32 bindingId);
    function revokeBinding(bytes32 bindingId) external;

    function file(bytes32 bindingId, ADRFTypes.ClaimInput calldata claim) external returns (bytes32 caseId);
    function fileAdvisory(bytes32 policyId, ADRFTypes.ClaimInput calldata claim, uint64 eventAt, uint64 normDeclaredAt) external returns (bytes32 caseId);
    function accept(bytes32 caseId) external;
    function expireAcceptance(bytes32 caseId) external;
    function withdraw(bytes32 caseId) external;

    function submitEvidence(bytes32 caseId, uint32 subQuestion, bytes32 commitment, string calldata uri) external;
    function answer(bytes32 caseId) external;
    function applySilence(bytes32 caseId) external;
    function resolveFormal(bytes32 caseId, uint32 subQuestion, bytes calldata inputs) external;
    function resolveEvidenced(bytes32 caseId, uint32 subQuestion, bytes calldata bundle) external;
    function openJudgment(bytes32 caseId, uint32 subQuestion) external;
    function recordJudgedFinding(bytes32 caseId, uint32 subQuestion, ADRFTypes.Value value, bytes32 resultHash, ADRFTypes.JudgmentSource calldata source) external;

    function decide(bytes32 caseId) external;
    function expireDecision(bytes32 caseId) external;
    function requestReview(bytes32 caseId, uint8 reviewType, uint32[] calldata subQuestions) external;
    function finalize(bytes32 caseId) external;
    function enforceDeadline(bytes32 caseId) external;

    function reportEnactment(bytes32 caseId, bytes32 effectId, ADRFTypes.EnactmentStatus status, bytes32 ref) external;
    function reportLead(ADRFTypes.ObjectRef calldata object, bytes32 commitment, string calldata uri) external;

    function getBinding(bytes32 bindingId) external view returns (ADRFTypes.Binding memory);
    function isAuthorizedEffect(bytes32 bindingId, bytes32 effectId) external view returns (bool);
    function isExecutor(bytes32 bindingId, address account) external view returns (bool);
    function isBeneficiary(bytes32 bindingId, address account) external view returns (bool);
    function getCase(bytes32 caseId) external view returns (ADRFTypes.CaseHeader memory);
    function getClock(bytes32 caseId) external view returns (ADRFTypes.CaseClock memory);
    function getSubQuestion(bytes32 caseId, uint32 subQuestion) external view returns (ADRFTypes.SubQuestion memory);
    function getFinding(bytes32 caseId, uint32 subQuestion) external view returns (ADRFTypes.Finding memory);
    function getRound(bytes32 caseId, uint32 round) external view returns (ADRFTypes.RoundRecord memory);
    function getRuling(bytes32 caseId) external view returns (ADRFTypes.Ruling memory);
    function getEnactment(bytes32 caseId, bytes32 effectId) external view returns (ADRFTypes.Enactment memory);
    function activeCaseOf(bytes32 exclusivityKey) external view returns (bytes32);
    function finalCaseOf(bytes32 exclusivityKey) external view returns (bytes32);
    function exclusivityKeyOf(address source, bytes32 obligationRef, bytes32 proposition) external pure returns (bytes32);
    function objectKeyOf(ADRFTypes.ObjectRef calldata object) external pure returns (bytes32);

    function clock() external view returns (uint48);
    function CLOCK_MODE() external view returns (string memory);
}

bindingId and caseId MUST be unique within the registry instance; the reference implementation derives them as keccak256(abi.encode(chainId, registry, nonce)). exclusivityKeyOf takes the decisive sub-question's proposition (Section 6.3). The structures Binding, CaseHeader, CaseClock, SubQuestion and Enactment carry exactly the fields this document names for them; their layout is given in the reference ADRFTypes.sol.

13. Clock

A dispute registry MUST expose ERC-6372 clock() and CLOCK_MODE(). One registry instance uses one clock for every policy it runs; the reference implementation uses mode=timestamp. Windows are seconds of that clock. A binding fixes clock rules — the triggering event, the relative windows, the hard cap and the margin — and the absolute deadlines of a case are derived when its event is attested; a source whose own clock differs converts in its adapter and MUST NOT claim that a deadline will be met by converting durations between clocks.

14. Profiles and reserved extension points

ProfileStatus in this ERC
Minimal (bound source, formal verification, one round, one ruling)REQUIRED
Evidenced resolutionnormative-optional, Section 8.3
J-profile v1 (ERC-8436 judgment, one binary question)normative-optional, Section 11
Reviewsnormative-optional, Section 9.3
Optimistic tracknormative-optional, Section 8.6
Post-dispute acceptancenormative-optional, Section 5.3
Third-party standingnormative-optional, Section 5.4
Advisory filingnormative-optional, Section 6.5

The following are reserved: this ERC names them so that implementations leave room for them, but it does not specify them and no conformance may be claimed for them under this document.

  • Panel replacement on review: a review that runs a judged sub-question under a different judgment policy or roster, with its own authorization, adoption rule, execution limits and time budget.
  • Non-binary and multi-option outcomes (amounts, categories, rankings) and typed aggregation of allowed effect sets.
  • Verifiable selection of judges (sortition with a randomness source, candidate sets, exclusion rules, freeze instants) and automatic independence screening by control relations.
  • Economic modules: bond and fee vaults, loser-pays schedules, challenger rewards, coherence rewards; this document fixes only what an economic declaration must state (Section 15).
  • Private evidence (commitments with gated access, zero-knowledge evidence rules).
  • Cross-chain objects and rulings; mirrors of rulings into validation or reputation registries such as ERC-8004.
  • Third-party funding and standing sources other than a binding's terms.

A policy that would need any of these is outside this ERC until a later document specifies it.

15. Scope, object categories and consumer integration (informative)

The relation of a dispute to AI names the domain; the object, the obligation, the rule and the authorized effects decide how it enters the procedure. No global test of whether a system is "AI enough" is needed or defined: a case states its relation to an AI system, resource, service or activity and is admitted on the five criteria. The object categories below describe the scope of the first draft; the classification is open.

CategoryObjects that can be namedTypical contested points
AI resourcesa model version, a dataset, a toolkit, a resource declarationwas the committed version delivered; were declarations about provenance or scope of use honored
AI systems and servicesa service endpoint, a deployed version, a service agreement, a billing periodwere version, availability, billing or usage-limit commitments kept
AI execution and deliverya request, an output, a training job, a report, a tool callwere the agreed steps performed; was authority exceeded; does the delivery meet the acceptance conditions
AI evaluation and declarationsan evaluation report, a metric statement, a capability or safety assertionwere the agreed sample, metric and method used; is the verified scope stated truthfully
AI governance and interventiona suspension, a permission change, an eligibility decision, an organizational decisionwas it authorized; was the applicable procedure followed; did the disposition stay within bounds

The scope of a ruling is fixed by its object. A finding that an evaluation report used the wrong sample supports a ruling on that report and the obligations attached to it; it does not establish that every version of the model is untrustworthy, that every service of the provider is in breach, or that every downstream user of the model is liable. A conclusion is confined to the event, version, sample and obligation it was formed on, and a provider's use of a base model does not transfer the provider's commitments to the base model's publisher.

An obligation source derives every attestation from its own state and never from the caller: the event instant and its own adoption deadline (the business window in which it can still adopt a ruling, during which it keeps the value a ruling could touch enactable), the obligation the event belongs to, the norm it recognizes and when that norm was declared, the obligation kind, the parties, and which propositions, taking which value, are breaches of which obligation under that norm. It binds itself to the policy versions it accepts, commits only effects it can enact, and names its executors. Its executor reads a Final ruling, checks finality, effect class, the allowed effect, its own object, the remaining amount and its anti-duplication record, enacts within its own authority and reports; a NoDecision leaves its pre-committed disposition in force. The worked example of the reference assets, an escrow for a model API service between two plain accounts, attests every settlement as an event of its own (a limit obligation: charge at most once, so the second and every later settlement is a breach with a contested point of its own), holds each settlement until its dispute period lapses, attests deliveries (a result obligation, with the version the terms committed and the version the provider declared on record) and recognizes as breaches the verifiers' canonical propositions and three statements about a delivery; it refunds the settlement a sustained claim was about; no agent identity, task token or swarm is involved. The standards of the agent economy — executable skills, task tenders, know-your-agent assertions, agent identities, collective decisions, discovery registries, swarm charters, economic unit valuations and safety bindings — are integration examples whose records become objects and whose contracts become sources and executors; none of them is a prerequisite for a case.

A policy's economic declaration — referenced by economicDeclaration and published with the policy document — states, for every bond or fee arrangement, the instrument and executor, the purposes it serves (an open reference classification: anti-abuse, cost bearing, performance guarantee, penalty for a proven procedural violation, third-party funding, reward pool, and others), the flows under every procedure state and result, the economic assumptions relied on, and what happens on failure. A reward or forfeit is reported with the clause it follows from and whether it is an allocation condition or a consequence of a proven violation; receiving a reward proves no fact, and forfeiting a bond proves no wrongdoing. Being in the minority of a panel is not, by this document, a violation. No fund pool pays out more than its available balance; remedies may be funded from any authorized source, not only from case bonds.

Exclusivity holds within one registry instance and one binding scope, per contested point: the decisive proposition the source recognized, under the attested obligation. A consumer that wants one procedure per breach recognizes one proposition per breach, binds each obligation to one registry and, at enactment, checks what it already disposed of and what remains, since another registry, or a second recognized proposition for the same breach, is not visible to the key. Execution state is per effect: a case can have its refund enacted and its fee allocation failed.

16. Interface identifiers

interfaceERC-165 id
IADRFPolicyRegistry0x4413df85
IADRFDisputeRegistry0xedc59c17
IADRFObligationSource0xa52f2870
IADRFVerifier0xdfed0fe7
IADRFEvidenceRule0x7ff3f359
IADRFJudgmentMethod0xc29a559d

Each identifier is the XOR of the selectors of every function the interface declares, supportsInterface included.

Rationale

AI, not agents, is the scope. The framework was first drafted for disputes between agents; its objects — an identified record, an obligation declared before the event, a binding that commits effects, typed methods — never depended on the parties being agents. The scope therefore names the domain by its objects: AI systems, resources, services and the conduct, deliveries and declarations around them, between any participants that can hold accounts and accept bindings. The roles a case keeps apart (object, actor, obligor, judgment participants, executors) are what a generalized domain needs: a model service process may act while a provider bears the obligation, a human may review while a contract enacts, and the records say which is which without requiring any of them to carry an agent identity.

A claim, not a party, is the object of a dispute. Admission is an algorithmic test of five criteria against what the obligation source attests — an identifiable object and event, an accountable respondent, a norm declared before the event, a bound method for every sub-question, an open window — and it refuses whatever fails without pre-judging anything that passes. "This agent is untrustworthy" cannot be filed; "this delivery does not meet the criteria pinned at tender time" can. The respondent criterion identifies who is alleged to bear the obligation; liability is what the case decides.

The claim fixes its own direction. A sub-question asks whether a proposition holds; a claim is sustained when the proposition has the value the claim named. Mapping conforms == true to a sustained claim would be wrong for every claim of non-conformance, so supportsWhen is part of the claim and Sustained always reads "the claim was supported". A blocked proposition under a collective rule is likewise FALSE for the sub-question and sustains or defeats the claim according to that direction, never as a finding of the opposite.

The source says what a breach is; the filer says which one it alleges. Letting the filer choose both the decisive question and its direction left admission with nothing to check them against: a claim whose decisive question holds whatever the facts ("the call has at least one settlement", supportsWhen = TRUE), or whose direction names the respondent's performance as the breach (conforms, TRUE), would have passed the five criteria, been verified, sustained and enacted, with a refund as the price of having been paid once. An earlier revision of this draft had that gap. The norm is the source's statement, so the source now attests the breaches too: recognizesBreach closes the direction and the choice of question at admission without pre-judging anything — the source says which propositions in which direction the terms make contestable, the methods still decide whether they hold.

One proposition per breach, and the key follows the point, not the headline. With a limit obligation such as "charge at most once", a key over the whole obligation locks it after the first sustained case: a provider charged a third time could not be sued for it, since the key was Final. Keying on the filer's free-text headline, on the other hand, let a second filer re-litigate the same point under other words. The key is therefore the decisive sub-question's proposition — the point the source recognized — and the reference source recognizes each settlement beyond the first as a proposition of its own, under an event reference of its own: each breach has its case, the same breach cannot be tried twice, and the two are told apart by the source's own records rather than by anyone's description.

Held value. An adoption deadline is only meaningful if the value a ruling could touch is still there when the ruling comes; a source that attests a deadline and pays the obligor out before it has made its own executor fail. The reference escrow holds each settlement until its dispute period lapses and releases only afterwards, and an executor that finds the value gone reports Failed with the reason, so that the log shows whose failure it was.

Support kinds are a set and the union is provenance. An earlier draft ordered signed, computed, evidenced and judged and gave a ruling the weakest kind among its findings. That ordering is false — a signature and a replayed computation answer different questions — and it would let a judged conclusion built on a computed premise present itself as computed, or let a later judgment downgrade a verified premise. The kernel therefore records support per finding, keeps premises as premises, and forbids any claim beyond what a finding's own method supports. The union recorded on a round names the sources the result cites and nothing more.

The dependency table replaces a fixed order. Formal questions are usually resolved first, but not always: which verifier to run can depend on which definition a contract adopted, and a time-limit check can depend on an external delivery fact. A bounded, acyclic premise table expresses the real dependencies; a question whose premise failed is recorded as not reached rather than answered by a method that was never meant to run.

Four dimensions, not one enumeration. A review window can lapse and an earlier decision be adopted in the same closure; an enactment can succeed for one effect and fail for another. Procedure state, substantive result, reason and per-effect enactment status are therefore separate, and Expired is reserved for a case that produced no substantive result at all.

NoDecision keeps its meaning and routes to a pre-committed disposition. The burden rule is a property of the method binding, so a policy can make an unverified formal claim fall on the claimant while a judgment that was never reached ends in no decision. Consumers never improvise: the fallback is the disposition the business committed before the case, referenced in the ruling.

Authority comes from the binding; the registry holds no funds. Credit, stake or reputation can qualify someone to judge; they never grant power over another party's assets. A binding is the source's own statement of what a ruling may authorize, and an executor enacts only within that statement and its own current conditions. Economic mechanisms are declared, not designed here: the framework fixes what a declaration must say and records what executors report, so that adopters choose their own loser-pays, bond or reward schemes without the kernel endorsing any.

Reuse of ERC-8436. Collective judgment is the one question type that needs a procedure with its own finality, and ERC-8436 already defines it with explicit authorization, frozen policies, appeals and an adoption rule. The J-profile consumes it as a consumer, through its real interface, with one binary question and a fixed effect pair, importing only Final results with their provenance. The profile is normative-optional, and this document depends on that ERC because the profile cannot be implemented or understood without it. Panel replacement, non-binary outcomes, verifiable selection and independence screening are reserved in both documents and are left to a later one.

Relation to oracle councils and arbitration interfaces. ERC-8033 produces answers to information queries through information agents and a judge, with an optional bonded re-judgment; this framework contests existing records against pre-declared obligations and routes judgment to any collective-decision registry. The arbitrable/arbitrator split of earlier arbitration interfaces, in which the arbitrated contract enforces a ruling it receives, is kept as the executor pattern; what is added is the object, the norm, the typed resolution and the bounded authority.

Backwards Compatibility

No backward compatibility issues were found. The framework introduces two new registries and references existing objects, obligations, policies and registries by their own identifiers without modifying them. Bound business contracts expose IADRFObligationSource through an adapter when they cannot be changed. The J-profile uses the ERC-8436 interfaces as published; no change to that ERC is required.

Test Cases

The following cases are self-contained; hashes are Keccak-256.

Identifiers

RESULT_PROFILE_V1        = keccak256("adrf:result/v1")
                         = 0x24ef34b623947d63d9d10d9d47a08f597a4ce3affcf8c0bb7f7b83844bf1b0c8
EFFECT_TRUE              = keccak256("adrf:finding/TRUE")
                         = 0xb22ccd9787f60157dcf8f6a32eab5a454645a4830e80b34254ca2d07d2085841
EFFECT_FALSE             = keccak256("adrf:finding/FALSE")
                         = 0x046e228493782e62fedebc450c0fe432b470bb972c39527db61a3abd833a8aef
DISPOSITION_UNDETERMINED = keccak256("adrf:finding/UNDETERMINED")
                         = 0xbeb05e221bdb799f2fa8788b5192ac86de01ea2aef7d37e528d2f4ab3196ddb7
QUESTION                 = keccak256("adrf:judgment/v1")
                         = 0x4c7cb151cebc9601c79e8f1a396b9c8bdff73ede178418229666b3401787b9af

The vectors file identifiers.json carries the same values together with the enumerations and bit sets of ADRFTypes.sol.

Keys

object        chainId 11155111, target 0x00000000000000000000000000000000000e5c20, id 17,
              versionHash keccak256("call 17 terms v1")
objectKey     keccak256(abi.encode(object))
obligationRef keccak256(abi.encode(uint256(17), "payment"))
proposition   keccak256(abi.encode(keccak256("adrf:prop/duplicate-settlement/v2"), source, uint256(17), uint32(2)))
              (the decisive sub-question's proposition: settlement 2 of call 17 exceeds the one-charge limit)
exclusivity   keccak256(abi.encode(source, obligationRef, proposition))
caseId        keccak256(abi.encode(uint256(11155111), registry, uint256(1)))
bridge        obligationId = keccak256(abi.encode(caseId, uint32(0)))
              question     = keccak256(abi.encode(QUESTION, uint32(0)))

The vectors file keys.json carries every value; a conforming registry's objectKeyOf and exclusivityKeyOf return them.

Policy identifier

The vectors file policy-id.json carries a three-method, two-effect policy specification, its ABI encoding under the tuple type of PolicySpec and its policyId; policyIdOf of a conforming registry returns that value.

Registry behaviour

  1. registerPolicy rejects a wrong result profile, a zero method, two bindings for the same (kind, type), a method that does not report the interface of its type, a judgment method whose hard cap exceeds the decision window, duplicate or zero effects, a zero filing or decision window, an evidence window longer than the decision window, reviews without a window or without types, a hard cap shorter than the rounds it must hold, optimistic fields on a non-optimistic track and the reverse, a zero family or authority; registering the same specification twice reverts; a second version requires the family authority, the latest policy as previous and a greater version, and leaves version 1 bindable.
  2. bind rejects an unknown policy, a caller that does not report IADRFObligationSource, an effect the policy does not declare, open challenge under a policy whose standing is not OPEN, beneficiaries under PARTIES, POST_DISPUTE under a zero acceptance window; a revoked binding admits no new case; revocation by a non-source reverts; a scope key admits only the object it names.
  3. Admission: an unknown or future event, an event whose obligation reference is missing, a norm the source does not recognise, a norm declared after the event or with no declaration time, an attested obligation kind different from the claim's, a decisive sub-question the source does not recognize as a breach in the claim's direction (NormNotApplicable), a respondent that is neither a party nor the source, a respondent equal to the filer, a sub-question with no bound method, a filing after the window, a filer with no standing, a requested effect that is not authorized or not substantive, a business window shorter than the hard cap plus the margin (refused, or admitted as Advisory under downgradeOnClock), each give the named result; the claim shape rules of Section 6.2 each revert with the named element.
  4. Exclusivity: a second Binding case for the same source, obligation and decisive proposition reverts with Duplicate while the first is active and after it is Final or Expired, whatever its headline proposition says; a different decisive proposition is a different key, equal to exclusivityKeyOf(source, obligationRef, proposition); a withdrawn or not-admitted case releases the key; an Advisory case never holds one.
  5. POST_DISPUTE: the case stays Filed; accept by anyone but the respondent reverts; accept after the window reverts; expireAcceptance before the window reverts and after it sets NotAdmitted; withdraw by anyone but the claimant reverts; a not-admitted case accepts no resolution and its ruling reports the state with result None.
  6. Formal flow: anyone resolves the pinned verifier; inputs that do not hash to the pinned value revert; the finding carries computed and the verifier as acceptor; decide sustains the claim when the value equals supportsWhen and does not sustain it otherwise; the provisional decision is adopted when the review window lapses, with closure REVIEW_LAPSED and the allowed effect set; the bound executor enacts once, reports Enacted, and a second attempt is refused by the executor and by the registry (EnactmentLocked); a report from a non-executor, for an unknown effect, for a substantive effect the ruling did not allow, or with status NotRequested reverts; Unknown may become Failed or Enacted, Failed may become Enacted, a procedural effect is reportable regardless of the result.
  7. Burden rule: when the decision window lapses without the verifier having run, expireDecision records UNDETERMINED(TIMEOUT) and, under a NOT_SUSTAINED binding, decides NotSustained with BURDEN_NOT_MET; the verifier cannot run afterwards.
  8. Judged flow: openJudgment files one CONSUMER_FILED Binding issue with the method as consumer, the case as subject, the fixed effect pair and the decision deadline as consumer deadline; a Provisional issue cannot be imported; a blocked proposition imports as FALSE with the issue's provenance and records Enacted on the source side; a claim that named FALSE is sustained; an approved proposition imports as TRUE and the same claim is not sustained; a quorum failure imports as UNDETERMINED with the source reason, records no enactment, and under a NO_DECISION binding the ruling is NoDecision with the fallback reference and no allowed effect, while a procedural effect remains reportable; an issue finalized by adoption after a failed appeal round imports with adoptedFromEarlierRound true and sourceRound 1 of 2; open from anyone but the registry, a second opening, a finding pushed by anyone but the method, a second import and a review through the method each revert; a judgment never opened lets the hard deadline close the case Expired with NoDecision(TIMEOUT) and the fallback reference.
  9. Evidenced flow and reviews: two of three attestations decide the fact with support signed | evidenced; one attestation leaves it UNDETERMINED with the same support kinds; a review by a non-party, of a type the track does not allow, of two types at once, with no target, or after the window reverts; a review resets the targeted sub-questions and their dependents and must reach the decisive one; a review round that ends undetermined, or whose decision window lapses, or that is cut by the hard deadline, adopts the earlier decision under PRESERVE_UNLESS_OVERTURNED (adoptedFromEarlierRound true, closure NONE or TIMEOUT), and ends in NoDecision under REQUIRE_FRESH_DECISION.
  10. Dependency table: a dependent sub-question cannot be resolved before its premise; a premise with a value other than the required one records the dependent UNDETERMINED(PREMISE_NOT_ESTABLISHED) with no method run; the round's provenance is the union of the decisive finding's support kinds and its premises' while each finding keeps its own.
  11. Optimistic track: applySilence before the answer window reverts; after it, without an answer and without a decisive finding, round 1 adopts the silence rule with reason SILENCE, bySilence set and support kinds 0, and the ruling authorizes the effect; an answer stops silence and the ordinary procedure continues; a finding on the merits before the deadline makes applySilence revert; a non-optimistic case has no answer window.
  12. Advisory: a case filed without a binding runs the procedure, its ruling is Advisory with no allowed effect, reportEnactment reverts, the executor refuses it, and the Binding slot for the same point stays free; a future event, a norm declared after the event or without a time, and a filing after the window revert.
  13. Plain accounts and versions: a double-charge claim between an enterprise account and a model API service, with the service endpoint recorded as actor and the provider as obligor, is admitted, verified, ruled and enacted without any agent identity, and the enactment refunds the settlement the case was about while the first charge stays held for the provider; a provider that declares a version other than the committed one is caught by the version verifier (computed); when the declaration matches, a claim that the service actually ran another version is admitted without the hidden fact being proven first, the formal check answers FALSE, the evidence rule establishes the fact (signed | evidenced) and the claim is sustained, or ends in NoDecision with the pre-committed disposition when the panel reaches no quorum; the verifiers answer UNDETERMINED before delivery, for a settlement ordinal of zero and for any other proposition; a sustained claim on one call takes no slot and decides nothing for another call of the same provider.
  14. Registry modules: every function of the interface is served at the registry's address and routed to a module built for the same policy registry; a module refuses a direct call, whether it writes or reads; the registry refuses a module built for another policy registry or an address without code, and two registries built on the same modules keep separate records; an unknown selector reverts; no ether is accepted; every entry is logged under the registry's address and never under a module's, and a module's revert reaches the caller unchanged.
  15. Recognition and held value: the duplicate-settlement proposition with supportsWhen = FALSE (a call charged once would sustain it), the declared-version proposition with supportsWhen = FALSE (true of every conforming delivery), a proposition the terms do not recognize, and a recognized proposition under the wrong obligation kind are each refused with NormNotApplicable, while the same questions in the recognized direction are admitted and an unrecognized proposition is accepted as a premise; recognition is the source's own statement, so a source that recognizes exactly one (kind, proposition, direction) admits that claim and refuses every other; the first settlement of a call is never a breach, the third is not an identifiable event until it exists, and once the case on settlement 2 is Final a second claim on it is a Duplicate while a third charge opens a new case, under a different key, whose enactment refunds settlement 3 and leaves settlement 1 held; a settlement cannot be withdrawn by the provider before its dispute period lapses (release does nothing before the attested deadline) and is released, and withdrawable, afterwards; an executor that comes after the settlement was released reports Failed with the reference keccak256("settlement released before enactment") and the ruling stands; a sustained delivery claim refunds the earliest held charge of the call.

Reference Implementation

The reference implementation, schemas, vectors and worked examples are provided with the assets of this proposal:

  • ADRFPolicyRegistry.sol and ADRFDisputeRegistry.sol, with the interfaces under contracts/interfaces, the shared types in ADRFTypes.sol and the errors in ADRFErrors.sol. The dispute registry exposes the whole interface at one address and keeps the record in its own storage (ADRFStore.sol); its functions are implemented by six modules that share that storage layout and that the registry runs by delegatecall with the original calldata and sender (ADRFModule.sol): bindings (ADRFBindingModule.sol), filing and admission, Sections 5 and 6 (ADRFFilingModule.sol), resolution and reviews, Section 8 (ADRFResolutionModule.sol), decisions and finality, Section 9 (ADRFDecisionModule.sol), the case reads and the informative entries (ADRFRecordModule.sol) and the reads of findings, rounds and rulings (ADRFOutcomeModule.sol). The modules are fixed at construction, refuse to run on their own storage, and keep every deployable unit well within the per-transaction gas limits of current networks; the split changes neither the interfaces nor any identifier nor the record.
  • The J-profile method ADRFACDFBridge.sol over the vendored ERC-8436 interfaces under contracts/interfaces/acdf.
  • Worked methods and consumer: DuplicateSettlementVerifier.sol (one proposition per settlement ordinal) and DeclaredVersionVerifier.sol (formal), each with a statement library that publishes its canonical proposition so that a source can recognize it, AttestorQuorumRule.sol (evidenced) and ADRFServiceEscrow.sol, an escrow for a model API service between plain accounts that is both obligation source and executor: it attests each settlement as an event of its own, holds every settlement until its dispute period lapses, recognizes the breaches its terms make contestable and keeps the committed and the declared version of each call on record.
  • JSON Schemas for the policy document, the binding document, the case document, findings, rulings and enactment reports under schemas.
  • Vectors for interface identifiers, identifiers, the policy identifier and keys under vectors.
  • Worked examples under examples: the model-API-service policy, its binding, the duplicate-charge claim, the delivery-quality claim and the version-commitment claim with their findings, rulings and an enactment report.

Security Considerations

Authority. A ruling has force only through a binding the source itself registered, and only for effects the source could enact. An attacker who controls a policy's update authority can publish new versions but cannot change what any existing binding or case is bound to; an attacker who controls a method contract controls the findings of the sub-questions bound to it, which is why methods are pinned by address at admission and why a policy document should pin their code. Consumers should bind only to methods whose code they have reviewed.

Attestations by the source. Admission trusts the obligation source about events, obligations, norms, parties and breaches. A source that attests a norm declared after the event, omits a party, or recognizes no breach for an event, opens or closes the door to claims about its own objects; the attestation is public and attributable, and a source's misstatements are themselves records that a consumer or another framework can hold against it. The registry does not check that the attested norm, or the set of breaches the source recognizes under it, reflects the actual agreement; that is between the parties and the source, and a party should read what a source recognizes before accepting its binding, as it reads the terms.

Direction and choice of question. Admission can check a decisive question and its direction only against a statement that is not the filer's. Without recognition by the source, a question that holds whatever the facts, or the direction in which the respondent's performance is the breach, passes every criterion, is verified correctly and is sustained, and a refund follows from the respondent having been paid once. Recognition closes this at admission; it does not decide anything, and a source that recognizes a trivially true proposition as a breach has bound itself to lose that case. Premises are not checked, because a premise authorizes nothing: only the decisive finding is read against the direction.

Enactability of value. A ruling that meets the attested adoption deadline is only as good as the executor's ability to enact it then. A source that attests a deadline and lets the value go before it — releases the settlement, pays out the obligor — breaches the duty of Section 5.1 and makes its own executor report Failed; the ruling and the record stand, and the failure is attributable to the source. Consumers reading the enactment log should treat such a Failed, with its reference, as the source's statement against itself rather than as a defect of the ruling.

Inputs and evidence. Formal inputs are pinned at filing, so the party who files chooses them; a verifier that decides anything other than the canonical proposition for its inputs, or that reads mutable state, weakens the finding, and the proposition check of the reference verifier is the recommended pattern. Evidence rules accept what they are built to accept; an attestor panel is a trust assumption, declared as such, and its support kinds say so.

Time. All windows depend on block time. A business window shorter than the hard cap plus the margin is refused at admission, and a review never extends the hard deadline; sources should choose dispute periods that leave time for the whole procedure and should expect latency between a ruling and its inclusion. A judged sub-question that nobody imports before the decision window closes ends in a timeout; the claimant has the incentive to import, and anyone may.

Liveness and griefing. Every step that could stall has a permissionless timeout, so no party can hold a case open; the price of that is that a party who lets a window lapse accepts its consequence. Under the optimistic track a respondent who does not answer accepts the silence rule it agreed to at binding. Filing is cheap and standing is checked, so the surface for spurious cases is the set of parties the source attests plus the beneficiaries and open challengers the binding admits; economic deterrents, if wanted, are declared by the policy and enforced by executors, not by the kernel.

Exclusivity. The key is derived from the source, the attested obligation and the decisive proposition the source recognized, so a reworded headline does not reopen a decided point and a further breach of the same obligation is not locked out by an earlier ruling. Two recognized propositions that mean the same thing for the same breach, or the same obligation bound to two registries, are not caught; a source should recognize one proposition per breach, and executors should check what was already disposed of before enacting.

Judgment at the source. When the J-profile is used, the panel's independence, selection and incentives are those of the collective-decision policy; a policy whose appeal standing is open to anyone lets third parties appeal at the source. The import carries the source's provenance so that a consumer can see whether a result was adopted after a failed appeal round rather than confirmed. A roster of accounts does not by itself prove the identity or the independence of the people, organizations or agents behind them; representation, control relations and conflicts of interest are declared and checked by the adopted configuration, not inferred from addresses.

AI-assisted judgment. Where a method or a panel uses AI to evaluate material, the material submitted by a party is evidence to be assessed and nothing more: it can never acquire the ability to change procedure rules, call an executor or widen an authorization, and a method whose model could be steered by the content it reads should treat that content as untrusted input, separate from its instructions. The same holds for the texts of claims, evidence URIs and lead reports read by any automated participant.

Reviews and finality. A review cannot be opened after its window, cannot exceed the policy's count and cannot reach a different policy; a final ruling cannot be re-litigated through a new case on the same key. Remedies for a final ruling that proves wrong are new, separately authorized matters.

Enactment. The log is informative. An executor that reports Enacted without enacting, or Unknown indefinitely, misleads readers of the log but changes no ruling; readers who need execution state read it from the executor.

Copyright and related rights waived via CC0.

EIP.tools

EIP.tools

Search, read, and map Ethereum improvement proposals, ERCs, RIPs, and CAIPs from one focused interface.

Farcaster
by @apoorveth