# Reputation on ChainRender — Complete Capability Guide

ChainRender can build **fully on-chain reputation UI**: apps that render an address's social graph (via EFP), delegated
vouches and flags, credential and attestation status, and identity claims — as `eth_call` renders, honestly graded.
This is the comprehensive reference for what ChainRender can and cannot do with reputation, and the honest boundaries.

## The mental model: read + render reputation, never *become* the authority

ChainRender does two things for reputation, and deliberately not a third:

1. **Render on-chain reputation** — follows/tags/blocks, vouches, credential status, attestations, identity claims —
   as free `view` calls. No server, no indexer for the trustless parts; the data is read from the source's own
   contracts at render time.
2. **Declare reputation actions** — a button can carry a declared action to *write* a vouch or follow (governed by the
   capability envelope + action decoder), just like any other action.
3. **It does NOT become a reputation oracle.** ChainRender never mints a score, never ranks addresses, never blesses an
   attester, and never runs an owned identity registry. A reputation authority with an admin key is exactly the thing
   the platform exists to avoid. Reputation is **read and rendered**, never manufactured.

This is the same separation as [DeFi](./defi-capabilities.md) (render prices, don't become a DEX) and
[RWA](./rwa-capabilities.md) (display compliance, don't become the compliance authority).

## What ChainRender can RENDER (the reputation surface)

Each resolver is immutable, ownerless, **view-only, fail-closed**: a reverting/missing source renders `"unavailable"`
rather than breaking the page. Addresses are always **caller-supplied** — ChainRender blesses no list, attester, or
issuer.

### EFP — the on-chain social graph (Ethereum Follow Protocol)
`EfpResolver` reads EFP list ops on chain and replays them to answer a **forward** question about a caller-named list.

| Kind | Renders |
|---|---|
| `efp-follows` | Does this list currently follow the target? |
| `efp-tag` | Does this list tag the target with a given tag (`friend`, `phisher`, …)? |
| `efp-state` | Compact: `following` / `blocked` / `muted` / `not following` |
| `efp-list-size` | The list's raw op count (a list-size figure, **not** a follower count) |

**Forward reads are Grade A** — a real on-chain read, recomputable by anyone via `eth_call`, bounded to a scan cap (a
larger list renders `"unavailable"`, never a partial). **Follower counts and reverse lookups ("who follows X") are
deliberately not offered on chain** — they need a global reverse index no single contract holds. Those belong to the
EFP indexer/API and must be graded **off-chain (≤ C)** and labeled — never surfaced as an on-chain fact.

### Delegated address vouching (native, ownerless)
`AddressAttestationRegistry` is an ownerless registry where any attester vouches for (or flags) an address under a
caller-chosen topic, with expiry and revocation — `msg.sender` is the attester; no owner, no admin.
`AddressReputationResolver` renders it.

| Kind | Renders |
|---|---|
| `rep-vouch` | One attester's status for a subject+topic: `vouched` / `expired` / `revoked` / `unknown` |
| `rep-tally` | A transparent **k-of-n** over an attester set the *caller* supplies |

Each vouch *record* is an on-chain fact (`READ_CHAIN`), but its *meaning* is delegated to a mutable attester the
consumer chose — so a reputation signal from it grades **≤ C** (the dependency axis, the same as
[ERC-3643](./rwa-capabilities.md)). **There is no global score:** `rep-tally` is "k/n" over *your* chosen attesters —
change the set, change the answer. A topic is neutral to sign (`trusted-builder` or `scammer` both render).

### Cross-source aggregate
`ReputationAggregateResolver` (`rep-aggregate`) composes many sources — EFP, vouches, EAS, ERC-725/735, or a future
source — through a uniform adapter (`IReputationSource`) into a transparent **k-of-n tally whose grade is capped at the
weakest source**. An A-grade EFP follow can never launder a C-grade vouch into trustlessness. Still no opaque number.

### Attestations & credentials (existing)
- **`AttestationAdapter`** reads **EAS**: "subject X holds attestation Y from attester Z". See
  [Data Sources](../reference/data-sources.md).
- **`CredentialStatusRegistry` + `CredentialLifecycleResolver`** — issuer-bound KYC/accreditation lifecycle
  (`VALID / EXPIRED / REVOKED / UNKNOWN`). See [RWA Capabilities](./rwa-capabilities.md).
- **ZK selective-disclosure credentials** (`CredentialResolver`, member-of-set, bound single-use). See
  [Privacy & Credentials](./privacy.md).

### Identity naming (existing)
- **ENS** — `EnsProfileResolver` (forward-verified reverse resolution), records, ENS-v2/CCIP. The anchor most
  reputation UIs hang off. See [ENS Names & Integration](../guides/ens-integration.md).

## ERC-725Y / ERC-735 accounts

ERC-725Y is a generic on-chain key-value store; ERC-735 layers signed claims on top. It's the **standard behind LUKSO
Universal Profiles**, but it is not LUKSO-specific — any EVM chain can host an ERC-725Y/735 account. ChainRender's
stance is the same as everywhere: **read it, don't become it.**

- **Read today (same-chain):** an ERC-725Y data key or an ERC-735 claim is a `view` read — render it now with the
  generic [`staticread`](./rendering-uniswap-hooks.md) resolver (`CallResolver`), pointed at the account address and
  data key. `CallResolver` does a `STATICCALL` against a **co-located** contract (the chain the resolver is deployed
  on), so it reads ERC-725Y/735 accounts that exist **on that same chain** — Sepolia, Robinhood, or Arc today.
- **LUKSO is not integrated as of now.** LUKSO Universal Profiles live on the LUKSO chain (mainnet 42 / testnet 4201).
  An EVM `STATICCALL` is same-chain only, so a resolver on Sepolia/Robinhood/Arc **cannot** read a UP that exists only
  on LUKSO — it fails closed to "unavailable." Reading live LUKSO UPs would require ChainRender **deployed on LUKSO**
  (a clean additive future step, since LUKSO is a standard EVM chain), or an off-chain (≤ C) fetch. Neither ships today.
- **Never deploy our own:** an ERC-725 account is **owner-controlled** by design — deploying one would reinstall the
  admin key the platform refuses. The ownerless `AddressAttestationRegistry` is the on-brand equivalent for vouches.
- **Grade:** an ERC-725Y store / ERC-735 claim is an owned, mutable authority, so a rendered claim grades **≤ C**
  (a faithful render of the owner's current data, not proof it's true) — exactly the ERC-3643 precedent.
- **Planned:** a dedicated `Erc725ClaimResolver` (a thin, read-only reader with LSP2 key vocabulary) is a natural
  additive follow-up; until then `staticread` covers same-chain reads.

## The honest boundaries (read these)

- **Follower counts are off-chain.** The trustless EFP reads are the *forward* relationship and personalized bounded
  reads; global counts come from the indexer and must be graded ≤ C and labeled. A follower count never renders Grade A.
- **Reputation is not truth.** Every non-EFP-record signal rests on a mutable author (an attester, an issuer, an
  ERC-725 owner). A rendered badge is "the current claim of authority Y," never "this is true." Signals fail closed to
  `unknown`/`unavailable`, never a fabricated positive.
- **No global score.** Any aggregate is caller-defined, transparent, and capped by its weakest input. A hidden
  reputation number is off-limits on principle — marketing must never exceed what the code enforces.
- **The source must exist on the target chain.** EFP lives on Ethereum L1 / Base / Optimism; a resolver reads EFP where
  EFP *is* (the caller supplies chain + list), consistent with the caller-supplied-address convention.

## What's NOT built (honest gaps)

- **`Erc725ClaimResolver`** — read ERC-725Y/735 claims with a typed LSP2 vocabulary (today: `staticread`).
- **On-chain follower aggregation** — not possible trustlessly; the EFP indexer path is the honest route (≤ C).
- **A weighted aggregate** — the shipped aggregate is unit k-of-n by design (transparent); weighting would be a later,
  still-caller-visible variant.

## Trust grade for reputation apps

| Signal | Grade | Why |
|---|---|---|
| EFP forward read (`efp-*`) | **A** | real on-chain state, recomputable via `eth_call` |
| EFP follower count / reverse lookup | **≤ C** | off-chain indexer aggregation |
| Vouch / `rep-tally` / `rep-aggregate` | **≤ C** | delegated to a mutable attester the consumer chose |
| EAS attestation / ERC-725 claim read | **≤ C** | mutable authority |
| Aggregate score | **= weakest input** | never exceeds its inputs |

## Built to evolve (immutability-safe)

Reputation is a moving space — EFP and ERC-725 will keep shipping capabilities. The suite is **additive by design**: a
new or upgraded source plugs in as a new `IReputationSource` adapter address (the aggregate needs no change); a new EFP
encoding ships as a new resolver (the shared `EfpOps` decoder is the single place it changes); new vouch semantics are
just new topics (the registry's `bytes32 topic` is opaque). Deployed code is never edited — it is superseded additively.
Full detail in the internal doc `149-reputation-resolvers.md` (§"Extension & versioning").

## Where to go next
- **[Resolvers](./resolvers.md)** — how the resolver mechanism works in general.
- **[RWA Capabilities](./rwa-capabilities.md)** — credential lifecycle, ERC-3643, Proof-of-Reserve.
- **[DeFi Capabilities](./defi-capabilities.md)** — the sibling render+declare guide.
- **[Trust Signals & Lineage](./trust-signals.md)** — attestations (vouch) + advisories (alert) for components.
- **[Privacy & Credentials](./privacy.md)** — ZK selective-disclosure credentials.
- **Reference: [Integrations](../reference/integrations.md)** — every integration + library + SDK/skill/MCP at a glance.
- **Reference: [Resolver Catalog](../reference/resolvers.md)** — every resolver + kind + args.
