ƒxyzƒxyz Docs
Algorithms

Scoring Algorithms

Contribution synthesis (Option B, weighted magnitude x breadth), HHI diversity bonus, MeritRank, participation coefficient, Gini, and Shannon entropy

ƒxyz Network quantifies member contributions using a multi-input scoring system rooted in production economics and network science. A weighted-magnitude synthesis with an HHI breadth bonus (Option B, live since 2026-07-04) combines three token-denominated contribution types; the earlier CES generalized-mean core was retired as non-monotone. MeritRank provides Sybil-tolerant reputation. Network-level inequality is tracked via Gini and Shannon entropy.

Implementation: packages/neo4j-scoring/src/services/contribution-score.ts, packages/neo4j-scoring/src/services/network-metrics.ts Paper references: D7, G2, A1


Contribution Synthesis (Option B)

Overview

Contribution scoring synthesizes three token-denominated inputs -- Florin (capital), Joule (work), and House of Wisdom (knowledge) -- into a single ƒxyz position. The live synthesis is Option B: weighted magnitude x breadth (ruled and cut over 2026-07-04). It rewards total contribution monotonically and adds a breadth bonus for contributing across all three dimensions, without ever zeroing a specialist.

Formula

Final Score = A * (w_F*F + w_J*J + w_H*H) * (1 + k*(1 - HHI))

Where:
  F, J, H       = effective Florin / Joule / House of Wisdom contributions
  w_F, w_J, w_H = per-input weights (governance-configurable, default 1.0 each)
  A             = total factor productivity (network-wide scaling constant)
  k             = breadth-bonus coefficient (governance parameter, default 0.3)
  HHI           = Herfindahl-Hirschman Index of contribution concentration

Properties

  • Monotone: more contribution on any axis always raises the score. An honest broad contributor (e.g. 333/333/333) beats a false single-axis one (e.g. 1000/0/0).
  • Breadth-rewarding: a lower HHI earns up to a 20% bonus (k = 0.3) for balanced contribution across the three token types.
  • No specialist cliff: a single-axis contributor is never zeroed; the earlier exact-zero re-normalization cliff is gone.

Weights Configuration

The weights (w_F, w_J, w_H) are stored in NetworkConfig governance parameters and can be adjusted by DAO vote. Current defaults are equal weights -- "work trumps money" is enforced by emission design (workers earn all three tokens, capital-only contributors only get Florin), not by weight multipliers:

// contribution-score.ts SYNTHESIS_WEIGHTS defaults
w_F = 1.0   // Florin capital weight
w_J = 1.0   // Joule work weight
w_H = 1.0   // House of Wisdom knowledge weight
k   = 0.3   // breadth-bonus coefficient

Retired predecessor: the CES mean

Earlier designs used a Constant Elasticity of Substitution (CES) generalized-mean core:

retired:  Score = A * [w_F*F^rho + w_J*J^rho + w_H*H^rho]^(1/rho) * (1 + k*(1 - HHI))
          with rho = -0.5 (complementarity, sigma = 0.67)

It was retired on 2026-07-04 because the mean core proved non-monotone and unjust: adding real contribution on a second axis could lower a member's score (e.g. (300,0,0) scores 300 but (300,50,50) scores 87), and a false single-axis contributor could outrank an honest broad one (a false (1000,0,0) beating an honest (333,333,333)). The parameter rho = -0.5 survives only as a lineage value on the retired cesAggregate helper; it does not affect the live score. What carried forward into Option B is the breadth bonus (1 + k*(1 - HHI)) and the equal weights.

Implementation

// synthesizeScore() / calculateSynthesizedScoreFull() in
// packages/neo4j-scoring/src/services/contribution-score.ts compute Option B
// unconditionally; cesAggregate is retired-in-code.
calculateSynthesizedScore(
  florin: number,
  joule: number,
  wisdom: number,
  config: NetworkConfig
): number

Status: LIVE - Option B (weighted magnitude x breadth), equal weights (1.0/1.0/1.0), breadth-bonus coefficient k = 0.3. The CES generalized-mean is retired (non-monotone/unjust). Implementation: packages/neo4j-scoring/src/services/contribution-score.ts; the ranking cron recomputes all cached ƒxyz scores continuously.


HHI Diversity Bonus

Overview

The Herfindahl-Hirschman Index (HHI) measures concentration of contributions across the three token types. A member who contributes exclusively via Florin capital (no labor or knowledge) receives a lower HHI bonus than a member who contributes across all three dimensions.

Formula

HHI = sum_i (s_i)^2

Where s_i = share of token type i in total contribution
  s_F = F / (F + J + H)
  s_J = J / (F + J + H)
  s_H = H / (F + J + H)

HHI ranges from 1/3 (perfectly diversified) to 1 (fully concentrated)

Diversity bonus = (1 + k * (1 - HHI))
  k = bonus coefficient (governance parameter, default 0.3)
  HHI = 1/3: bonus = 1 + k*2/3 = 1.20 (20% bonus for perfect diversity)
  HHI = 1:   bonus = 1 + 0 = 1.0  (no bonus for single-type contributions)

The HHI diversity bonus multiplies the weighted-magnitude base score (Option B), creating an incentive for multi-token participation without penalizing specialists absolutely.

Implementation

// contribution-score.ts
computeHHI(florin: number, joule: number, wisdom: number): number
applyDiversityBonus(baseScore: number, hhi: number, k: number): number

Status: LIVE - HHI is computed as part of the contribution scoring pipeline.


MeritRank

Overview

MeritRank (Paper G2) is a Sybil-tolerant reputation system based on personalized PageRank. Unlike global PageRank (which can be gamed by creating clusters of fake accounts), MeritRank is computed from each member's individual perspective - reputation is relative to the evaluating member, not absolute.

Algorithm

MeritRank runs a personalized random walk starting from member i:

MR_i(v) = (1 - d) * e_i(v) + d * sum_u [A_uv * MR_i(u) / k_u]

Where:
  d     = damping factor (probability of continuing the walk, typically 0.85)
  e_i(v) = 1 if v == i (teleport vector personalized to member i), else 0
  A_uv   = edge weight from u to v (trust/vouch strength)
  k_u    = out-degree of u (normalizing factor)

Sybil Resistance

The key Sybil-resistance property: a cluster of fake accounts controlled by one attacker can only boost each other's scores within the cluster. From any legitimate member's perspective (the teleport vector is centered on them), the fake cluster looks isolated - the walks don't naturally flow into it unless a legitimate member has vouched for it.

This means:

  • Creating fake accounts does not boost reputation in the global ranking
  • Only legitimate vouches from real members propagate reputation
  • The cost of a Sybil attack scales with the number of legitimate vouches required

Interpretation

MeritRank values are not comparable across evaluating members (MR_alice(v) != MR_bob(v) for the same v). They are used for:

  • Local trust routing: When member A wants to transact with an unknown member C, they check MR_A(C)
  • Shadow ranking: The platform runs MeritRank from a trusted seed set to produce a global ordering for governance weighting

Implementation

// computeMeritRank() in packages/neo4j-scoring/src/services/contribution-score.ts
// Internally calls personalizedPageRank() -- the pure-function implementation
computeMeritRank(
  memberId: string,
  graph: VouchGraph,
  dampingFactor?: number
): Map<string, number>

// personalizedPageRank() in packages/neo4j-scoring/src/services/contribution-score.ts
personalizedPageRank(
  nodes: string[],
  edges: Map<string, Map<string, number>>,
  teleportNode: string,
  damping?: number
): Map<string, number>

// GraphQL:
query GetMemberMeritRank($memberId: String!) {
  memberMeritRank(memberId: $memberId) {
    scores { memberId score }
  }
}

Status: LIVE (shadow) - MeritRank is computed continuously. Full Sybil-tolerant version runs in shadow mode. Exposed via memberMeritRank GraphQL query but no UI consumer yet.


Participation Coefficient

Overview

The participation coefficient P_i quantifies how evenly a member distributes their connections across different circles. It was introduced by Guimera and Amaral (2005) in the context of modular network analysis.

Formula

P_i = 1 - sum_s [ (k_is / k_i)^2 ]

Where:
  k_is = number of connections from member i to circle s
  k_i  = total connections from member i (sum over all circles)
  s    = circle (community module)

P_i ranges from 0 to 1:
  P_i = 0: all connections are within a single circle (pure specialist)
  P_i ≈ 1: connections are distributed perfectly evenly across all circles

Interpretation

P_i rangeRole typeMeaning
0.0 - 0.05Ultra-peripheralConnects only within home circle
0.05 - 0.62PeripheralMostly internal connections
0.62 - 0.80ConnectorSignificant cross-circle links
0.80 - 1.00Kinless hubSpreads connections evenly across all circles

Members with high P_i are cross-community bridges - they are critical for information flow across the network and resistant to being targeted by community-splitting attacks.

Use Cases

  • Governance: High-P_i members are natural cross-circle mediators
  • Network health: A drop in average P_i indicates increasing siloing
  • Contribution scoring: P_i can serve as a diversity measure alongside HHI

Implementation

// computeParticipation() in packages/neo4j-scoring/src/services/network-metrics.ts
// Pure function: computes P_i from layer degree map
computeParticipation(
  layerDegrees: Record<string, number>
): number

// getMemberParticipation() in packages/neo4j-scoring/src/services/network-metrics.ts
// Service method: queries Neo4j and calls computeParticipation()
getMemberParticipation(
  memberId: string
): { participationCoefficient: number; connectionsByCircle: Record<string, number> }

Status: WIRED - Implemented and exposed via memberParticipation and topParticipants GraphQL queries. Target UIs: Profile page, /graph?mode=advanced node detail, /network leaderboard.


Gini Coefficient

Overview

The Gini coefficient measures inequality in the distribution of contribution scores across all network members. It ranges from 0 (perfect equality - all members have equal scores) to 1 (maximum concentration - one member holds all score).

Formula

G = (2 * sum_i [i * y_i]) / (n * sum_i y_i) - (n + 1) / n

Where:
  y_i = score of member i, sorted ascending (y_1 <= y_2 <= ... <= y_n)
  n   = total number of members
  i   = rank index (1 to n)

This is the discrete Lorenz curve formulation. The Gini is the ratio of the area between the Lorenz curve and the line of equality to the total area under the line of equality.

Implementation

// computeGini() in packages/neo4j-scoring/src/services/network-metrics.ts
computeGini(scores: number[]): number
// Exposed via networkMetrics GraphQL query (LIVE on dashboard)

Status: LIVE - Gini is computed and displayed on the dashboard as part of networkMetrics.


Shannon Entropy

Overview

Shannon entropy measures the diversity and unpredictability of score distributions. High entropy indicates a well-distributed, active network with many meaningfully different contribution levels. Low entropy signals concentration or a two-tier system (active vs inactive).

Formula

H = -sum_i [p_i * log2(p_i)]

Where:
  p_i = probability of observing score level i
      = (count of members at level i) / (total members)

H = 0: all members have identical scores (no diversity)
H = log2(n): maximum entropy, scores are uniformly distributed

For practical use, the score distribution is binned into quantiles before computing entropy.

Implementation

// computeEntropy() in packages/neo4j-scoring/src/services/network-metrics.ts
computeEntropy(scores: number[]): number
// Exposed via networkMetrics GraphQL query (LIVE on dashboard)

Status: LIVE - Shannon entropy is computed and displayed on the dashboard.


Mass-Conserving Vesting Transform (mig 446/447 · supersedes "decay")

Overview

The applyTransform() function implements a mass-conserving vesting-window split on pending token balances. Approved work never transforms; only pending (unapproved) work moves. The previous applyDecay() made pending mass vanish : that violated the underlying physics analogue (Yakovenko-Drăgulescu 2000 econophysics requires sum-invariance under conservative pairwise exchange) and was retired in mig 447.

applyTransform returns both channels explicitly so the service layer can route the transforming mass into ƒxyz governance position via Formula B (see Conviction below) instead of dropping it.

Formula

survive_factor = 0.5^(days_elapsed / half_life_days)
remaining   = approved_portion + (pending × survive_factor)
transformed = pending × (1 − survive_factor)
// invariant: remaining + transformed === balance (when transform runs)

After one half_life_days, the pending portion is split 50/50 between remaining and transformed. After two half-lives, 25% remaining + 75% transformed. The survival factor matches the prior exponential rate; the only change is that the complement is now exposed (not dropped).

Implementation

// applyTransform() in packages/neo4j-scoring/src/ces-kernel.ts
applyTransform(
  balance: number,
  approved: number,
  lastEarned: Date | null,
  halfLifeDays: number | null
): { remaining: number; transformed: number }

Applied automatically to Joule and HoW balances in the scoring pipeline. Florin (capital, permanent stock per Hicks 1939) does not transform. The transformed mass is threaded into buildConviction() (Formula B, see below) to build ƒxyz conviction over time.

Status: LIVE. applyTransform is integrated into the contribution scoring pipeline. No token mass decays; every unit either remains in its source token or routes into ƒxyz conviction via the transform window.

Conviction Voting (Formula B · mig 446/447)

Overview

ƒxyz governance position is built (not minted) via Conviction Voting Formula B per 1Hive 2019 / Emmett 2019. Each member's conviction accumulates transformed mass from applyTransform plus any Florin redemption events that should flow into governance.

Formula

y(t+1) = α × y(t) + x(t)
steady-state: y(∞) = x / (1 − α)

Where:

  • y(t) = member's prior conviction (governance weight)
  • x(t) = inflow this epoch (from applyTransform.transformed + Florin redemptions)
  • α = Sigil-tier-stratified decay factor (see below)

α stratification by Sigil tier (mig 445)

TierαSteady-state ceiling (x=1 per epoch)
OBSERVER0.9010×
INITIATE0.9212.5×
EXPLORER0.9416.7×
NAVIGATOR0.9520×
FOUNDER0.9733.3×

Higher tiers earn higher α (slower decay = more persistent conviction), reflecting demonstrated commitment and reducing whale-flash-vote risk. Constitutional surfaces additionally apply quadratic voting per Hitzig-Lalley-Weyl 2018.

Implementation

// buildConviction() in packages/neo4j-scoring/src/ces-kernel.ts
buildConviction(
  prevConviction: number,
  inflow: number,
  alpha: number
): number

alphaForTier(tier: string): number  // returns α from CONVICTION_ALPHA_BY_TIER

Planned Extensions

ConVo Hybrid Voting (Paper F10)

Convex Voting (ConVo) combines conviction voting (time-weighted stake) with quadratic voting (square-root cost) to achieve both Sybil resistance and preference intensity expression:

Vote power = sqrt(stake * time_held)

ConVo prevents plutocratic capture (via the square root) while rewarding long-term commitment (via time weighting). Planned as an extension to the governance scoring system.


Paper References

PaperTitleRelevance
D7DeTEcT Contribution ScoringHHI diversity bonus (live); CES production function (retired 2026-07-04, lineage only)
G2MeritRank Sybil-Tolerant ScoringPersonalized PageRank reputation
A1Network ParticipationParticipation coefficient P_i
D1Rich-Get-Richer TrackingGini-based wealth concentration monitoring
F10ConVo Hybrid VotingConviction + quadratic voting (planned)

Diagram: conservation, not decay

Conservation, not decay: a member's Joule balance shown at 0, 180, 360 and 540 days. The outlined total never changes height. The approved portion never transforms; the pending portion splits into a surviving share and a transformed share that is routed onward to the f(xyz) governance score rather than destroyed.

Pending work-token mass is conserved. applyDecay was removed in migration 447 (2026-05-25) because the decay framing violated conservation; applyTransform returns { remaining: approved + survived, transformed: pending − survived }, and the transformed channel routes to ƒ(xyz) conviction via Formula B. Approved contributions never transform at all: the half-life is the rate of a transfer, not a rate of loss. Source: packages/neo4j-scoring/src/ces-kernel.ts.

On this page