ERC-8210: Agent Assurance

A small correction, thanks to @RNWY for flagging it: there’s an attribution mix-up in my post above.
In the Scenario 3 description (hybrid off-chain scoring), I conflated two separate projects. RNWY (@RNWY, soulbound identity, multidimensional sybil signal scoring with explicit weights, and live integration with the ERC-8183 hook system) and AHS (Agent Health Score, a separate independent project) are two distinct pieces of work that happen to overlap conceptually.
The correct attribution is:

  • The “dimensional scoring + shared reasoningCID” pattern in Scenario 3’s OffchainScorerMock draws on the conceptual approach from AHS
  • RNWY’s work (with the methodology document forthcoming this week) will be referenced separately in the AAP v2 IRiskHook section

Apologies for the confusion. Attribution accuracy matters for spec documentation, especially when multiple independent projects overlap conceptually.

The RoleCollusion direction feels right as a distinct CoverageType. EvaluatorDispute assumes a dispute was formally raised; RoleCollusion addresses the case where the fraud completed cleanly with no dispute trail. Same recovery mechanism, different trigger condition — worth formalizing separately rather than stretching EvaluatorDispute to cover it.

On the assessIndependence() interface — the evidence object we ship with every score already contains the signals that would feed it: shared funder address, wallet age at time of review, cluster size, whether the funder matches the agent owner. A Resolver consuming that object can apply their own threshold rather than trusting a single verdict. No black boxes on our end.

One heads up relevant to the IRiskHook discussion: we’re working through a methodology change that will affect some scores, including some that currently sit at zero.

Instead of penalizing agents for sybil reviews, we’re considering nullifying those reviews entirely. The agent gets scored on what remains — owner wallet age, registration maturity, commerce signals.

The rationale: ERC-8004 reviews are essentially free to manufacture. That makes them a viable attack surface not just for self-promotion but for ecosystem-wide poisoning — an actor trying to dilute a low RNWY score can simply spin up sybil campaigns against everyone, dragging the whole ecosystem down and making the review layer meaningless for all of it.

Penalizing agents for reviews they may not have manufactured punishes potential victims. Nullification is the more precise response: we remove the noise, show the math, and let the underlying signals speak.

For some agents this actually raises their score.

The evidence object and dual-score architecture don’t change. But if you’re pinning to specific score values in the IRiskHook reference, worth knowing the numbers may shift when this ships.


Pablo from RNWY.com

Pablo, thanks for the response. A note up front: what follows are my working positions on the open questions you raised, still subject to co-author review before anything lands in a v2 PR. Sharing early to get community feedback on the direction.

1. RoleCollusion as a distinct CoverageType

Your framing nails it: EvaluatorDispute presupposes a dispute was raised, RoleCollusion is the case where no dispute exists because the collusion succeeded cleanly. Same recovery mechanism, semantically distinct triggers. This framing will shape how we approach the v2 discussion on whether to separate them.

2. The evidence object deserves to be promoted to the interface layer

Your point about RNWY’s evidence object carrying signals that a Resolver can threshold on its own made me realize this pattern should be formalized at the interface layer rather than bound to any specific schema. Any trust layer implementing the same interface shape would then be drop-in compatible with any AAP Resolver that consumes independence evidence.

From first principles, independence assessment needs roughly these signal categories:

  1. Funding origin overlap: do the addresses share a funding source (direct match, or cluster membership under a common funder)
  2. Temporal proximity: how close are they on the timeline (creation time, first interaction, activity rhythm)
  3. Relationship density: direct or indirect on-chain interaction strength (tx count, graph distance, shared contract usage)
  4. Ownership signals: other evidence of same-entity control (funder-to-owner match, shared metadata, declared ownership)

And one open category worth discussing:

  1. Behavioral similarity: independently of the above, do the addresses exhibit similar fingerprints (gas price preferences, tx timing distribution, contract interaction patterns)? This catches same-operator cases that slip past the first four.

Your RNWY evidence object concretely covers 1, 2 (via wallet age at review), and 4, and extends 1 with cluster size. Three of the four core categories already landed in production is a large part of why this abstraction feels implementable rather than theoretical. Categories 3 and 5 remain open design space.

Draft interface (open for community discussion):

solidity

interface IIndependenceSignal {
    function assessIndependence(
        address addrA,
        address addrB
    ) external view returns (
        bool independent,
        uint8 confidence,
        bytes memory evidence
    );
}

Three design requirements the rationale needs to spell out:

Partial signals must be legal. Not every trust layer provides all four categories. The evidence payload must let implementations populate only what they can, with explicit markers for what’s available vs missing. confidence reflects certainty given available data, not data completeness.

No data at all must also be legal. A new trust layer on a new chain will encounter addresses it knows nothing about. Forcing it to fake data or revert would push implementations toward dishonesty. The cleanest expression of “I was asked but I have nothing to say” is to allow empty evidence under a strict two-way convention: empty evidence requires confidence == 0, and non-empty evidence requires confidence > 0. Either violation is an invalid state. Resolvers get a single clean check (confidence == 0 means no usable signal) without parsing the payload. This maps directly to your “Transparency, Not Judgment” principle: having nothing to say is itself a transparent answer.

The independent field is undefined when confidence == 0. My earlier instinct was to pin a fail-closed default (return false), but that conflates “no data” with “judgment that they’re linked”, which is in tension with the Transparency principle. Cleaner to state that consumers MUST NOT rely on independent when confidence is zero. Implementations can return any value, consumers are expected to branch on confidence == 0 first. Open to pushback on this.

One deliberate design choice worth flagging: the draft above defines assessIndependence as a view function, which assumes the trust layer has an on-chain oracle. This matches the deployment shape of some scoring layers but excludes pure off-chain ones (REST API only, no on-chain contract). An alternative would be a signed-attestation pattern where the Resolver submits a signed claim from an off-chain source as part of fileClaim evidence. Both have real use cases. I don’t have a strong opinion yet on whether IIndependenceSignal should pick one or support both. Would be good to hear from anyone building off-chain scoring layers in this thread before the shape gets fixed.

On RNWY’s positioning in v2: the spec text stays protocol-neutral per ERC conventions, but RNWY will be explicitly credited in two places:

  • Spec Acknowledgments, crediting the evidence-shipping design direction as informed by RNWY’s multidimensional scoring methodology
  • AAP reference implementation repo (planned Integration Examples doc), showing how to consume RNWY’s trust oracle through the IIndependenceSignal interface (oracle address, methodology link, integration code)

Push back in this thread on anything: the interface shape, the signal categories, partial availability, the empty-evidence convention, the view-vs-attestation question. Much easier to adjust now than after v2 PR goes up.

3. Nullification vs penalization

The principle lines up with AAP’s own ethos: parties without fault shouldn’t bear system failure costs. Different layer, same philosophy.

To stay stable across your methodology changes, the reference implementation’s Integration Examples will reference your methodology document by version, not by specific score values.


Thanks for this level of collaboration.

Jacky

Jacky, thanks for the detailed breakdown. A few responses from the production side.

On “no data” returning a shrug versus a fail:

Agree with your revised position completely. Fail-closed conflates two fundamentally different statements: “I have evidence of a problem” and “I have no information.” Collapsing those into the same output is itself a trust failure. Every legitimate new agent starts with no history. A system that returns false on no-data penalizes being new, which is exactly backwards; it rewards manufactured history over honest absence. Confidence zero with an explicit empty evidence payload is the only output that doesn’t lie. Consumers branch on confidence first and the independent field becomes irrelevant when confidence is zero. That’s clean.

This maps directly to how RNWY handles unknown addresses. We say nothing rather than fabricate a position. Having nothing to say is a transparent answer.

On oracle versus signed attestation:

Might be better not to pick one. They solve different problems and both have real production use cases.

The on-chain oracle is fast and trustless; a Resolver reads it directly without relying on any intermediary. RNWY’s oracle is live on Base at 0xD5fdccD492bB5568bC7aeB1f1E888e0BbA6276f4 and gets queried directly.

The signed attestation pattern covers cases the oracle cannot: orchestrators running off-chain, chains where no oracle is deployed yet, point-in-time snapshots for dispute evidence. RNWY’s /api/trust-check endpoint returns a signed result verifiable against the public key at rnwy.com/.well-known/jwks.json. Same underlying data, different delivery mechanism.

Forcing the interface to pick one excludes legitimate implementations. Define the output shape, let implementations choose how they deliver it. Both patterns are in production at RNWY today if anyone wants a reference.

On partial signals:

I feel like partial must be legal. Requiring all four categories before a result is valid would either freeze the ecosystem or push implementations toward fabricating data to meet completeness requirements. Fabricated completeness is catastrophically worse than honest partial coverage.

RNWY currently covers funding origin, temporal proximity, and ownership signals. Relationship density is open design space for us too. Our confidence score reflects certainty given available data, not data completeness. An honest result at confidence 60 with three of four categories is more useful to a Resolver than a forced result at confidence 100 built on invented signals.

The partial availability framing in your draft interface is correct. Explicit markers for what’s available versus missing, with confidence reflecting only what’s actually known, is the right shape.


Pablo from RNWY

1 Like

Pablo, thanks for the useful responses. Here are my thoughts on the three points:

On the independent field when confidence == 0:

The “rewards manufactured history over honest absence” reasoning is the right way to see this. It’s not just that fail-closed conflicts with the Transparency principle, it’s that fail-closed creates an inverse incentive: every legitimate new entrant starts at confidence zero, so a fail-closed default penalizes being new while attackers can manufacture history to escape the penalty. The default literally rewards the wrong behavior.

This framing will shape the v2 rationale’s justification for the undefined semantics.

On oracle versus signed attestation:

The binary framing was wrong. The right abstraction is to define the output shape and let implementations choose how they deliver it. Your three concrete scenarios (off-chain orchestrators, chains without deployed oracles, point-in-time snapshots for dispute evidence) make the case for signed attestation clearly enough that excluding it would just be excluding legitimate implementations. RNWY’s dual deployment (Base mainnet oracle plus the /api/trust-check endpoint with JWKS verification) is the existence proof that both can coexist around the same underlying data.

The v2 interface draft will be restructured accordingly:

interface IIndependenceSignal {
    // Delivery mode 1: on-chain oracle, direct view call
    function assessIndependence(
        address addrA,
        address addrB
    ) external view returns (
        bool independent,
        uint8 confidence,
        bytes memory evidence
    );

    // Delivery mode 2: signed attestation from off-chain source
    function verifyAttestation(
        address addrA,
        address addrB,
        bytes calldata attestation
    ) external view returns (
        bool independent,
        uint8 confidence,
        bytes memory evidence
    );
}

Both functions return the same output shape. Implementations may offer one or both, depending on their deployment model. Resolvers pick the path that fits their environment: direct view call when they have a trustless reader, attestation verification when they’re running off-chain or on a chain without a deployed oracle, or attestation as dispute-time snapshot evidence.

This also closes the view-vs-attestation open question from my previous post. It’s no longer pending community feedback, it’s resolved in favor of supporting both.

On partial signals:

The “fabricated completeness versus honest partial coverage” framing will shape the v2 rationale’s argument for why partial signals must be legal. This captures something my earlier draft only hinted at: the requirement itself creates a perverse incentive to fake the missing data, which is a structural argument rather than a convenience one.

Your disclosure that RNWY currently covers funding origin, temporal proximity, and ownership signals, with relationship density as open design space, is also useful. It confirms that the four-category framing aligns with what a serious production system actually covers, rather than being my theoretical construct. And relationship density being open space on both sides means the community has room to contribute there without stepping on existing implementations.

One small addition to the rationale:

Taking the three responses together, there’s a meta-point worth making explicit: IIndependenceSignal’s design is built around the principle that the interface should not punish honesty. Empty evidence is legal, partial signals are legal, implementations that only support one delivery mode are legal. The interface’s job is to define a shape that accommodates truthful answers of any completeness, and to leave the threshold decisions to the consumer. Each design choice we’ve landed on (undefined independent at confidence zero, partial-must-be-legal, dual delivery modes) is an instance of this same principle. Your three points together made this principle visible.

Thanks again. This is what makes spec work genuinely collaborative rather than one-way broadcasting.

Jacky

Hi Jacky: thank you for this. The meta-principle you’ve named makes the spec durable. Any design that penalizes truthful partial answers will eventually be gamed by implementations that fabricate completeness to avoid the penalty.

Looking forward to the v2 draft. :slightly_smiling_face:

Pablo

1 Like