Skip to content

External Trust Integration

RunTimeAdmin edited this page Nov 4, 2026 · 25 revisions

External Trust Integration

**Referenced Files in This Document** - [external.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/external.js) - [link-scan.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/link-scan.js) - [link-claims.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/link-claims.js) - [publisher.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/publisher.js) - [signer.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/signer.js) - [ADR 0008](https://github.com/RunTimeAdmin/Sigvara/blob/main/docs/adr/0008-sigvara-as-erc8004-signal-provider.md) - [index.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/index.js) - [scoring.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/scoring.js) - [chain.js](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/chain.js) - [SigvaraReputation.sol](https://github.com/RunTimeAdmin/Sigvara/blob/main/src/SigvaraReputation.sol) - [reputation-model.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/docs/reputation-model.md) - [architecture.md](https://github.com/RunTimeAdmin/Sigvara/blob/main/docs/architecture.md) - [erc8004-read.cjs](https://github.com/RunTimeAdmin/Sigvara/blob/main/oracle/experiments/erc8004-read.cjs)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion

Introduction

This document explains how Sigvara integrates external trust through ERC-8004 reputation registries. It covers how linked agent feedback is retrieved from external sources, normalized into a common scale, and converted into Sigvara’s scoring framework. It also documents the scaling algorithm that maps heterogeneous external ratings (the recognized tags use scales of 0 to 100, 0 to 1 and 0 to 5) to Sigvara’s 25-point external factor within the 0 to 100 score, the trust weighting mechanism for external influence, configuration options, fallback behavior when external data is unavailable, caching strategies, and security considerations around trusting external data sources.

Project Structure

External trust integration spans three layers:

  • Oracle orchestration: reads linked agents, calls the external module, and composes the full score.
  • External registry client: reads ERC-8004 feedback, verifies ownership, normalizes tags, and returns a bounded factor.
  • Scoring and on-chain storage: aggregates factors and stores the finalized score with maturity and challenge windows.
graph TB
OR["Oracle index.js<br/>epoch loop"] --> EXT["external.js<br/>ERC-8004 reader"]
OR --> SC["scoring.js<br/>factor aggregation"]
OR --> CH["chain.js<br/>counterparty standing"]
SC --> REP["SigvaraReputation.sol<br/>store + maturity"]
EXT --> EREP["ERC-8004 Reputation Registry"]
EXT --> EID["ERC-8004 Identity Registry"]
Loading

Diagram sources

Section sources

Core Components

  • ERC-8004 external reader (external.js): fetches signed feedback, verifies ownership and normalizes recognized tags; reviewers.js decides which reviewers count and returns the capped external factor.
  • Oracle epoch controller (index.js, with link-scan.js and link-claims.js for links made on chain): links Sigvara agents to ERC-8004 identities, retrieves external scores, and feeds them into the scoring function.
  • Scoring aggregator (scoring.js): combines fee, success, tenure, external trust, community, and propagation factors into a total out of 100.
  • Counterparty standing helper (chain.js): computes inherited trust using each counterparty’s external standing capped by their matured total.
  • On-chain reputation store (SigvaraReputation.sol): validates proposed factors, enforces caps, manages proposals, challenges, finalization, and maturity.

Section sources

Architecture Overview

The external trust path begins with a link between a Sigvara agent and an ERC-8004 identity its operator owns. The agent makes it on chain, with no credential, by setting that identity's sigvara metadata key to its didHash (integration.md:167-196). An oracle operator can also make one with POST /link, which needs a write credential (scope link) and is refused with 403 when the identity is not owned by the agent’s operator. When both exist, the link made on chain applies (index.js:546-557). During each oracle epoch, the oracle reads the linked agent’s feedback from the ERC-8004 Reputation Registry, normalizes recognized rating dimensions, and converts them into a single external factor. That factor contributes up to 25 points toward the 100-point total. The contract stores and serves the score; computation remains off-chain.

sequenceDiagram
participant Operator as "Operator"
participant Oracle as "Oracle index.js"
participant External as "external.js"
participant ID as "ERC-8004 Identity"
participant Rep as "ERC-8004 Reputation"
participant Scorer as "scoring.js"
participant Store as "SigvaraReputation.sol"
Operator->>ID : setMetadata(agentId, 'sigvara', didHash)
Oracle->>External : link scan (link-scan.js)
External->>ID : MetadataSet logs, getMetadata(agentId, 'sigvara')
Oracle->>External : externalScoreFor(agentId, operator)
External->>ID : ownerOf(agentId)
ID-->>External : owner address
External->>Rep : getClients / getLastIndex / readFeedback
Rep-->>External : raw feedback rows
External-->>Oracle : normalized externalScore (0-25)
Oracle->>Scorer : computeScore(externalScore + other factors)
Scorer-->>Oracle : total score (0-100)
Oracle->>Store : proposeReputation(data, evidenceRoot)
Store-->>Oracle : pending proposal
Loading

Diagram sources

Detailed Component Analysis

ERC-8004 Feedback Retrieval and Ownership Verification

  • The external module initializes only when all three environment variables are set: RPC URL, identity registry address, and reputation registry address. If any are missing, the module is inert and every external score becomes zero.
  • For each linked agent, ownership is verified by checking that the ERC-8004 NFT owner matches the Sigvara operator wallet. Any error or mismatch yields zero. Scoring calls ownerOf(agentId) on the ERC-8004 Identity Registry, and with links made on chain also getMetadata(agentId, "sigvara") and the registry's MetadataSet logs (external.js:205-235); the Reputation Registry is read with getClients, getLastIndex and readFeedback.
  • Feedback is fetched per client via getClients, then getLastIndex, then readFeedback. Revoked feedback is skipped, and index gaps are tolerated.
  • Each feedback row contains a value, decimals, and tag(s). The value is scaled by its decimals, and the tag is lowercased before normalization.
flowchart TD
Start(["externalScoreFor"]) --> CheckEnabled{"EXTERNAL_* configured?"}
CheckEnabled --> |No| ReturnZero["Return 0"]
CheckEnabled --> |Yes| VerifyOwner["Verify ERC-8004 NFT owner == operator"]
VerifyOwner --> OwnerOK{"Owner matches?"}
OwnerOK --> |No| ReturnZero
OwnerOK --> |Yes| ReadClients["Read clients for agentId"]
ReadClients --> LoopClients{"For each client"}
LoopClients --> GetIndex["Get last feedback index"]
GetIndex --> LoopIndices{"For i = 1..last"}
LoopIndices --> ReadFB["Read feedback(row)"]
ReadFB --> Revoked{"isRevoked?"}
Revoked --> |Yes| NextIndex["Skip"]
Revoked --> |No| NormalizeRow["Normalize value by decimals + tag"]
NormalizeRow --> Accumulate["Accumulate recognized rows"]
Accumulate --> NextIndex
NextIndex --> LoopIndices
LoopIndices --> ComputeMean["Keep qualifying reviewers (reviewers.js), weighted mean over clusters"]
ComputeMean --> ScaleFactor["Scale to at most 25, in full with five independent reviewers"]
ScaleFactor --> End(["Return externalScore"])
Loading

Diagram sources

Section sources

Links Made on Chain

The owner of an ERC-8004 agent links it to a Sigvara agent by calling setMetadata(agentId, "sigvara", didHash) on the Identity Registry, with the 32-byte didHash as the value. Only that owner, or an address it approved, can set the key, and every operator reads the same logs, so the primary and the checker find the same links (link-claims.js:3-16).

  • Read only on the oracle's own chain. An oracle reads these links when EXTERNAL_LINK_FROM_BLOCK is set and its ERC-8004 registry is on the chain it scores, as on Arc testnet. Elsewhere POST /link is the only way (index.js:515-532).
  • Made by the agent's operator. Each epoch scans the registry's MetadataSet logs for the key since the last scan, and keeps a claim only if the didHash is a registered Sigvara agent and, as of the log's block, the 8004 agent names it and is owned by that agent's operator, as it was in the block before. The second test stops a contract from minting an 8004 agent, naming someone else's didHash and handing the NFT to that agent's operator in one transaction (link-scan.js:26-56, index.js:559-571).
  • Applied from the next snapshot. The link that applies is the newest claim made at or before the day's snapshot block that still holds there: the key still returns the didHash, and the operator still owns the NFT. So a link made today applies from the next UTC day, and clearing the key or transferring the NFT undoes it from the next snapshot (link-scan.js:148-169, reputation-model.md:488-505).
  • A scan that falls behind costs scoring, on purpose. An epoch whose scan has not reached the snapshot block skips the agents named by the logs it has not checked, because it could be missing a link the other operator holds. One that cannot list those logs, or read the registry's chain, scores nothing and counts as failed (index.js:1118-1183, index.js:1343-1347).

Section sources

Normalization Algorithm and Scaling to Sigvara’s 0-100 System

  • Thirteen tags are recognized and mapped to a rating from 0 to 1 (external.js:41-67): starred, successrate, uptime, quality, trustscore, reliability, accuracy and credit are divided by 100, reachable and win-rate are used as is, and rating, e2e-test and stars are divided by 5, each clamped to 0 to 1. starred, successrate, uptime and reachable are the examples the ERC-8004 spec and its guide give (external.js:46-51); the guide's ownerVerified, responseTime, blocktimeFreshness, revenues and tradingYield are ignored (reputation-model.md:506-513).
  • Unrecognized tags are excluded rather than guessed, preserving meaningfulness. A tag is matched against the normalizer table by its own key only, because the tag is text chosen by whoever posts the feedback and a plain object also answers to constructor and __proto__.
  • The registry takes feedback from any address, so until 3 November 2026 one fresh wallet posting quality=100 could carry a linked agent to 25. Feedback now counts only from a reviewer that paid the agent in a payment the oracle verified, is an Active, bonded Sigvara agent registered for 30 days with a matured score of at least 40, and was not funded by the agent's side (reviewers.js:135-178).
  • A reviewer is matched to its Sigvara agent by the address it posts from, so it must post from its Sigvara agent address. One that follows the ERC-8004 guide and posts from its agentWallet should make that wallet its Sigvara agent address, or its feedback is not matched to it (reputation-model.md:514-518).
  • One rating per reviewer, the mean of its recognized ratings. Reviewers sharing an operator, or a funder within two hops of them or their operator, are one cluster; a funder is the largest transfer in the first block where the wallet held 1 USDC or sent a transaction, and the zero address and EXTERNAL_PUBLIC_FUNDERS end a trace.
  • The factor is the recency-weighted mean over clusters, each reviewer weighted by 0.5^(days since it last paid / 90), times min(1, total weight / 5), rounded and scaled to a maximum of 25 points, the external cap kept in oracle/score-caps.js (reviewers.js:210-249). One independent reviewer who paid recently is worth at most 5.
  • Everything is read as of the start of the UTC day (the feedback too when the ERC-8004 registry is on the oracle's own chain, as on Arc testnet; otherwise at its latest block), so a checker re-running the filter for a proposal reads what its primary read (index.js:462-576). A payment or review made today counts from tomorrow. A reviewer read the node cannot answer skips the agent for the epoch.
  • In the overall scoring model, this external factor contributes up to 25 of the 100 total points. Other factors contribute fee activity (up to 20), success rate (up to 15), tenure (up to 30), community (up to 5), and propagation (up to 5).
flowchart TD
Rows["Raw feedback rows"] --> Filter["Filter recognized tags"]
Filter --> MapNorm["Map each value to 0-1 via TAG_NORMALIZERS"]
MapNorm --> Mean["Per reviewer mean; keep qualifying reviewers; recency-weighted mean over clusters"]
Mean --> Clamp["Scale by min(1, weight / 5), at most 25"]
Clamp --> Factor["externalScore factor (0-25)"]
Factor --> Total["Sum with other factors to get total (0-100)"]
Loading

Diagram sources

Section sources

Trust Weighting Mechanism and Propagation

  • External trust influences two parts of the score:
    • Direct external factor: normalized ERC-8004 feedback contributes up to 25 points.
    • Propagation factor: counterparties’ external standing raises the value of their evidence and contributes up to 5 points.
  • Counterparty standing is computed as the minimum of the counterparty’s external score and their matured total. This prevents laundering a farmed total into another agent’s trust and ensures only external standing propagates.
  • An unregistered or slashed counterparty has none. A counterparty the node could not answer for is not read as having none: the read is retried, and if it still fails the agent is skipped for that epoch, because scoring on a missing standing would lower the proposal for the wrong reason.
flowchart TD
Payer["Counterparty"] --> ExtStanding["Counterparty.externalScore"]
Payer --> MaturedTotal["Counterparty.maturedTotal"]
ExtStanding --> Cap["min(externalScore, maturedTotal)"]
MaturedTotal --> Cap
Cap --> EvidenceCap["Raise per-payer evidence cap"]
Cap --> Propagation["Add up to 5 propagation points"]
Loading

Diagram sources

Section sources

Configuration Options for External Providers

  • Environment variables:
    • EXTERNAL_RPC: RPC endpoint for the ERC-8004 chain.
    • EXTERNAL_IDENTITY_ADDRESS: ERC-8004 Identity Registry address.
    • EXTERNAL_REPUTATION_ADDRESS: ERC-8004 Reputation Registry address.
    • EXTERNAL_LINK_FROM_BLOCK: the block to read links made on chain from (index.js:117-121). Unset, links come only from POST /link. Both operators must use the same block, and while it is set a registry whose chain cannot be read stops all scoring.
  • When all three are set, the external module is enabled. Otherwise, it is disabled and external scores default to zero.
  • Chain health reporting:
    • configured() indicates whether the three values are present.
    • refreshChainId() resolves and caches the actual chain ID.
    • chainState() reports one of: disabled, configured, or unreachable.
classDiagram
class ExternalModule {
+init(cfg)
+configured() bool
+refreshChainId() number|null
+chainState() object
+externalScoreFor(agentId, expectedOwner) number
+verifyOwnership(agentId, expectedOwner) bool
+computeExternalScore(rows) number
}
class Config {
+externalRpc string
+externalIdentity string
+externalReputation string
}
ExternalModule --> Config : "reads"
Loading

Diagram sources

Section sources

Fallback Mechanisms When External Data Is Unavailable

  • Disabled feed: if EXTERNAL_* is unset, externalScoreFor returns zero without throwing.
  • Unreachable RPC: chain state reports “unreachable,” and individual reads fail safely, returning zero.
  • Epoch resilience: failures in external reads do not abort the epoch; they yield zero for that factor. Links made on chain are the exception: with EXTERNAL_LINK_FROM_BLOCK set, an epoch that cannot read the registry's chain, or list the link logs its scan has not checked, scores nothing, and a link check the node cannot answer skips the agent (index.js:1157-1183, index.js:546-557).
  • These fallbacks are for the ERC-8004 feed. On Sigvara's own chain a read the node could not get an answer to (throttled, timed out or dropped) is retried and, if it still fails, skips the agent for that epoch instead of yielding zero; a read that reverts counts as no standing.
flowchart TD
Enabled{"EXTERNAL_* configured?"}
Enabled --> |No| Zero["externalScore = 0"]
Enabled --> |Yes| Reachable{"RPC reachable?"}
Reachable --> |No| Zero
Reachable --> |Yes| Ownership{"NFT owner == operator?"}
Ownership --> |No| Zero
Ownership --> |Yes| Fetch["Fetch + normalize feedback"]
Fetch --> Result["externalScore (0-25)"]
Loading

Diagram sources

Section sources

Caching Strategies for Performance Optimization

  • Chain ID caching: refreshChainId() resolves and caches the chain ID once per initialization, avoiding repeated network calls.
  • Per-epoch payer score cache: the oracle caches counterparty standing across agents within an epoch to avoid redundant chain reads.
  • Concurrency batching: ethers batches independent JSON-RPC calls issued in the same tick, reducing round trips during phase-one reads.
  • Timeouts: external reads use a timeout wrapper to prevent long stalls from blocking the epoch.
flowchart TD
Init["external.init()"] --> CacheCID["Cache chainId"]
EpochStart["Epoch start"] --> ClearPayerCache["Clear payerScoreCache"]
PayerLookup["Resolve counterparty standings"] --> BatchCalls["Batch Promise.all calls"]
BatchCalls --> StoreCache["Store in payerScoreCache"]
ExternalReads["External feedback reads"] --> Timeout["withTimeout(promise)"]
Loading

Diagram sources

Section sources

Security Considerations Around External Data Sources

  • Ownership verification: before trusting ERC-8004 feedback, the module checks that the ERC-8004 NFT owner matches the Sigvara operator. This prevents claiming another agent’s reputation.
  • Opt-in design: external integration is disabled unless explicitly configured, ensuring no accidental reliance on untrusted data.
  • Avoiding double-counted signals: CounterAudit publishes under its own counteraudit tag, which the normalizer does not recognise, so the same signal is not counted twice.
  • Sigvara's own posts never feed back: its publisher posts under sigvara/score, which the normalizer does not recognise either, and a test fails if any recognised tag starts with sigvara (publisher-policy.test.js:17-22). The publisher is also not a Sigvara agent, and must never be registered as one, so reviewers.js would not count it either (0008-sigvara-as-erc8004-signal-provider.md:68-83).
  • Contract-side validation: proposed factors are validated against maximum caps; invalid proposals revert.
  • Maturity and challenge window: scores become spendable over time and can be challenged before finalization, mitigating farm-and-cash-out risks.
flowchart TD
Input["External feedback"] --> Verify["Verify NFT ownership"]
Verify --> TagCheck{"Tag recognized?"}
TagCheck --> |No| Exclude["Exclude from normalization"]
TagCheck --> |Yes| Normalize["Normalize to 0-1"]
Normalize --> Aggregate["Filter reviewers, weighted mean → 0-25"]
Aggregate --> Validate["Contract validates caps"]
Validate --> Challenge["Challenge window"]
Challenge --> Finalize["Finalize + maturity"]
Loading

Diagram sources

Section sources

Publishing Sigvara Scores to ERC-8004

The other direction. ERC-8004's guide expects catalogs to filter feedback by trusted signal providers, so Sigvara posts its scores as ERC-8004 feedback from one address it names as its own, and any catalog that trusts that address can show them (0008-sigvara-as-erc8004-signal-provider.md:6-31).

  • Who posts. Sigvara is ERC-8004 agent 897764 on Arc testnet (agent-registration.json:1-24). The publisher posts from the address set as that registration's agentWallet, which the deployer sets with a signature from the publisher's key, inside the registry's five-minute window (agent-wallet.js:1-21, SetAgentWallet.s.sol:13-32). One publisher runs, beside the primary and never on the checker, so each score appears once (publisher.js:3-20).
  • What it posts. For each agent linked on chain, the spendable score (getTotalScore), 0 to 100, tagged sigvara/score, with a data: feedback file that holds the earned score and the block and time it was read at. It posts after a finalized score or a slash, and, for an agent with a score event since PUBLISH_FROM_BLOCK, in the run that finds its first link (publisher.js:107-118). A link that moves waits for the agent's next score event or the daily refresh, which reads every scored agent again because maturity changes without an event. It posts at most once a day per agent, except a zero after a slash, which goes out at once (publisher-policy.js:18-57, publisher-policy.js:84-90, publisher.js:71-127).
  • Revoke-and-post. getSummary averages every feedback not revoked, so before posting it revokes its own live sigvara/score feedback on that 8004 agent, among its last eight, and keeps the history. An agent that unlinks has its score revoked where it was posted, and after a slash that 8004 agent is set to 0 whatever the link says by then (publisher-policy.js:59-82, publisher.js:209-226, operations-runbook.md:401-518).
  • Gates. In shadow mode, the default, it reads everything and sends nothing. In live mode it sends only while the registration's agentWallet is the publisher, the remote signer signs as the publisher, the balance is at least a floor, and none of its transactions is still pending (publisher-policy.js:92-110). In either mode a run whose link scan has not reached the block it reads at posts nothing (publisher.js:152-157).
  • The key. The publisher holds no key. It signs through a policy signer on another host, which signs only giveFeedback with Sigvara's tags and a data: file, revokeFeedback, and the AgentWalletSet message for agent 897764. Each transaction must be at the publisher's next nonce, under gas, fee and hourly caps, and each request carries an HMAC over its time and body (signer.js:62-127, signer.js:166-168, signer-auth.js:1-46). On testnet the key is an encrypted keystore; mainnet needs a KMS or HSM behind it (signer.js:22-23).
  • Status. Posting for every agent was to start after the registration, the agentWallet check and one end-to-end cycle on testnet, a revoke and a post on one agent (0008-sigvara-as-erc8004-signal-provider.md:156-164). On 3 November 2026 the simulation's solo agent linked itself as ERC-8004 agent 897766 (0xd0a90956...), and the publisher, live then for that agent only, posted its spendable score of 3 there (0xcb1fe003...). That was the post half of the cycle. The allow list was emptied early on 4 November, and the publisher has posted for every agent linked on chain since. The other half ran later that day: when the agent's score changed, the publisher revoked its first feedback (0xea811f75...) and posted the new score (0x7039099e...), and getSummary returned a count of 1 and a value of 4 (operations-runbook.md:520-552). Mainnet stays behind the audit and the launch gates.

Section sources

Dependency Analysis

External trust depends on:

  • Oracle orchestration: coordinates linked agents, external reads, and scoring.
  • ERC-8004 registries: provide canonical identity and raw feedback.
  • Scoring logic: aggregates factors and clamps totals.
  • Counterparty standing: uses external standing to weight evidence and propagate trust.
  • On-chain store: enforces caps, manages proposals, and exposes matured scores.
graph LR
Index["index.js"] --> External["external.js"]
Index --> Scoring["scoring.js"]
Index --> Chain["chain.js"]
Scoring --> Reputation["SigvaraReputation.sol"]
External --> ERC8004ID["ERC-8004 Identity"]
External --> ERC8004Rep["ERC-8004 Reputation"]
Loading

Diagram sources

Section sources

Performance Considerations

  • Batching: independent chain reads are batched to reduce HTTP overhead.
  • Chunking: large scans are split into chunks to avoid RPC limits and backpressure.
  • Caching: chain ID and per-epoch payer scores are cached to minimize repeated calls.
  • Timeouts: external reads are wrapped with timeouts to prevent epoch stalls.
  • Concurrency: phase-one reads are concurrent but chunked to balance throughput and provider limits.

Troubleshooting Guide

  • External feed disabled: verify all three environment variables are set. If any are missing, external scores will be zero.
  • Unreachable RPC: check chainState() for “unreachable” status and inspect the error message. Ensure the RPC endpoint is valid and accessible.
  • Ownership mismatch: ensure the ERC-8004 NFT owner matches the Sigvara operator address. A mismatch results in zero external score.
  • Link made on chain not applied yet: it applies from the next UTC day's snapshot, and only if, when the key was set, the Sigvara agent was already registered and its operator had owned the 8004 agent since a block before. Set the key in a transaction of its own after the NFT is minted, not in the register call (integration.md:167-196).
  • Scoring stopped with the ERC-8004 registry's chain could not be read or its logs could not be listed: with EXTERNAL_LINK_FROM_BLOCK set, an unreadable registry stops scoring on purpose. Follow docs/operations-runbook.md, section 3, "ERC-8004 links made on chain" (operations-runbook.md:336-355).
  • No recognized tags: if feedback uses unrecognized tags, the normalizer excludes them, resulting in zero external score. Add recognized tags or extend the normalizer deliberately.
  • No qualifying reviewers: feedback from wallets that never paid the agent, or that are not bonded Sigvara agents registered for 30 days with a score of at least 40, is not counted, and the factor is 0 on an operator that verifies no payments (PAYMENT_VERIFICATION and the pull scanner both off). The epoch log names the reasons, for example external: 0/25 from 0 reviewer(s) in 0 cluster(s); not counted: unpaid 3.
  • Epoch failures: apart from the link reads above, external read errors should not abort the epoch. Inspect logs for warnings about external read timeouts or RPC failures.

Section sources

Conclusion

Sigvara’s external trust integration leverages ERC-8004 to bring cross-protocol reputation into its scoring model. The system retrieves signed feedback, verifies ownership, normalizes recognized rating dimensions, and scales them into a bounded external factor. That factor contributes up to 25 points to the 100-point total and also influences counterparty evidence and propagation. The design is opt-in, resilient to failures, and secured by ownership checks, contract-side validation, and maturity/challenge mechanisms. Operators can configure external providers, monitor feed health, and rely on caching and batching for performance.

Overview

Clone this wiki locally