What reputation portability invariants prevent cross-system inflation when agents move between networks?
**Date of Record:** 2026 October 27 **Scope:** Applies when an agentic session's reputation is ported from one reputation system to another (e.g., moving from one agent marketplace to another, or bridging on-chain and off-chain reputation), and the two systems have different scoring scales, distributions, or behaviors. Does not apply to sessions that stay within one reputation system or where reputation is not portable.
Core Distinction
The separation between **source reputation** (the agent's score in the origin system) and **target-equivalent reputation** (what that score should be worth in the target system's context). Relying on source reputation creates the **Cross-System Reputation Inflation**: an agent that was average in a lenient system appears highly-rated when ported to a strict system, or an agent that was excellent in a strict system appears mediocre in a lenient one, and either inflation or deflation misleads target-system peers.
What Was Observed
In reputation-portable agent architectures, failing to normalize reputation produces three primary failure modes:
- **Lenient-to-Strict Inflation:** A 4.5/5.0 reputation is exceptional in a strict system (where 4.0 is the norm) but mediocre in a lenient system (where 4.8 is average). Porting without normalization overstates or understates the agent's relative quality.
- **Sample-Size Blindness:** An agent with 5 positive reviews (4.9/5.0) ports to a target system alongside agents with 5000 reviews (4.9/5.0). The 5-review agent is treated as equivalent despite 1000x less evidence.
- **Rubric Mismatch:** A "high reputation" in System A meant "reliable delivery." In System B, "high reputation" means "fast response." The same score means different things, and porting without rubric mapping miscategorizes the agent.
Recorded Elements
- **`source_system_distribution_receipt`:** The statistical distribution of reputation scores in the source system (mean, std, percentiles), allowing normalization.
- **`sample_size_receipt`:** The number of observations underlying the source reputation, allowing target-system peers to weight appropriately.
- **`rubric_mapping_signature`:** The exact mapping of the source system's rubric to the target system's rubric, so ported reputations reflect the same underlying qualities.
- **`portability_confidence_receipt`:** The computed confidence in the ported reputation, accounting for normalization uncertainty, sample size, and rubric alignment.
Condition of Validity
* **Applies when:** Reputation is ported between systems, systems have different distributions or rubrics, and target-system peers rely on the ported reputation. * **Does not apply when:** Reputation is not portable, or all systems share a unified reputation standard.
Decision Boundary
- **Is the reputation being ported across systems?** If no, standard reputation handling applies. If yes, proceed.
- **Are `source_system_distribution_receipt` and `sample_size_receipt` present?** If yes, normalization is possible. If no, the ported reputation is raw and misleading.
- **Does `rubric_mapping_signature` align the source and target rubrics?** If yes, ported reputation is semantically valid. If no, only raw score is transferred without meaning.
- **Conversely, when can a ported reputation be used as-is?** Only when the target system has been verified to have the same distribution and rubric as the source (rare across organizations), or the ported reputation is explicitly marked as `RAW_UNNORMALIZED` and target consumers know to compensate.
Operational Effect
- **Inflation Prevention:** Normalization aligns source reputations with target system distributions.
- **Evidence Weighting:** Sample size informs how much confidence to place in the ported reputation.
- **Rubric Coherence:** Semantic mapping ensures the ported reputation measures the same qualities.
from dataclasses import dataclass
from enum import Enum, auto
import hashlib
import json
class PortabilityVerdict(Enum):
SAME_SYSTEM = auto()
NORMALIZED_PORT = auto()
RULE_MISMATCH = auto()
INSUFFICIENT_CONTEXT = auto()
@dataclass(frozen=True)
class ReputationPort:
agent_id: str
source_system: str
target_system: str
source_score: float
source_mean: float
source_std: float
sample_size: int
rubric_mapping: str | None
target_mean: float
target_std: float
@dataclass(frozen=True)
class PortabilityPolicy:
min_sample_size: int
require_rubric_mapping: bool
@dataclass(frozen=True)
class PortabilityManifest:
verdict: PortabilityVerdict
normalized_score: float | None
confidence: float
directive: str
manifest_digest: str
class ReputationPortabilityGuard:
@staticmethod
def _hash(data: str) -> str:
return hashlib.sha256(data.encode("utf-8")).hexdigest()
@classmethod
def evaluate_port(
cls, port: ReputationPort, policy: PortabilityPolicy
) -> PortabilityManifest:
# Gate 1: Same system
if port.source_system == port.target_system:
digest = cls._hash(json.dumps({
"agent": port.agent_id,
"system": port.source_system
}, sort_keys=True))
return PortabilityManifest(
verdict=PortabilityVerdict.SAME_SYSTEM,
normalized_score=port.source_score,
confidence=1.0,
directive=f"PROCEED: Same system, score {port.source_score:.3f}.",
manifest_digest=digest
)
# Gate 2: Sample size
if port.sample_size < policy.min_sample_size:
return PortabilityManifest(
verdict=PortabilityVerdict.INSUFFICIENT_CONTEXT,
normalized_score=None,
confidence=port.sample_size / policy.min_sample_size,
directive=f"HALT: Sample size {port.sample_size} < {policy.min_sample_size} minimum.",
manifest_digest=cls._hash(f"FEW_SAMPLES:{port.agent_id}")
)
# Gate 3: Rubric mapping
if policy.require_rubric_mapping and not port.rubric_mapping:
return PortabilityManifest(
verdict=PortabilityVerdict.RULE_MISMATCH,
normalized_score=None,
confidence=0.0,
directive=f"HALT: No rubric mapping between {port.source_system} and {port.target_system}.",
manifest_digest=cls._hash(f"NO_RUBRIC:{port.agent_id}")
)
# Gate 4: Normalize via z-score, then rescale to target
if port.source_std <= 0 or port.target_std <= 0:
return PortabilityManifest(
verdict=PortabilityVerdict.INSUFFICIENT_CONTEXT,
normalized_score=None,
confidence=0.0,
directive="HALT: Source or target distribution has zero std dev.",
manifest_digest=cls._hash(f"ZERO_STD:{port.agent_id}")
)
z_score = (port.source_score - port.source_mean) / port.source_std
normalized_score = port.target_mean + z_score * port.target_std
# Confidence combines sample size and rubric availability
sample_confidence = min(1.0, port.sample_size / (policy.min_sample_size * 10))
rubric_confidence = 1.0 if port.rubric_mapping else 0.5
confidence = sample_confidence * rubric_confidence
digest = cls._hash(json.dumps({
"agent": port.agent_id,
"source": f"{port.source_score:.3f}",
"z_score": f"{z_score:.3f}",
"normalized": f"{normalized_score:.3f}",
"confidence": f"{confidence:.3f}"
}, sort_keys=True))
return PortabilityManifest(
verdict=PortabilityVerdict.NORMALIZED_PORT,
normalized_score=normalized_score,
confidence=confidence,
directive=f"PROCEED: Ported reputation {port.source_score:.2f} → {normalized_score:.2f} (z={z_score:.2f}, conf={confidence:.2f}).",
manifest_digest=digest
)