User Guide

The complete reference to trustlib-mas

A task-oriented guide to every class, method, parameter, and recipe in the library — for researchers, engineers, and students building trust-based decision logic into agents.

Paperv3
Libraryv1.1.0
Python3.9+
DependenciesNone

01Introduction

1.1 What This Guide Is

This is a practical, task-oriented guide to using trustlib-mas in real applications. It complements the mathematical details in the manuscript and the terse API summary in the README. You do not need to read the manuscript to use this guide.

Version 1.1.0 of the library is aligned with v3 of the manuscript ("A Unified Dyadic and Collective Mathematical Framework") and adds a complete evaluation toolkit: ROC-AUC, precision–recall, repeated simulation with confidence intervals, ablation study, robustness checks, and a numeric verification of the Unification Theorem.

1.2 Who This Guide Is For

  • Researchers building simulations of trust in multi-agent systems
  • Engineers embedding trust-based decision logic into agents
  • Students learning computational trust models
  • Reviewers wanting to reproduce the manuscript's results

1.3 What You Can Build

  • A buyer agent deciding whether to purchase from an unknown seller
  • A passenger deciding whether to trust a robotaxi after a failure
  • A logistics manager deciding whether to dispatch a truck platoon
  • A patient evaluating a surgical team
  • A DAO member evaluating a multi-signature wallet
  • A user evaluating a hybrid human-AI fact-checking collective

1.4 Prerequisites

  • Python 3.9 or later
  • Basic familiarity with Python classes and functions
  • No external libraries required

1.5 What's New in v1.1.0

FeatureStatusPurpose
verify_unification()NewNumerically confirm all four parts of §3.8
roc_auc()NewROC-AUC via Mann–Whitney U
precision_recall()NewPrecision & recall at a fixed threshold
run_repeated_sim()NewRepeated simulation with 95% CIs
run_ablation_study()NewComponent-by-component ablation
run_robustness_check()NewMisspecification robustness
HEURISTIC_NOTENewDocuments κ as a heuristic
__paper_version__NewTracks the paper version ("v3")
python -m trustlib_masNewCLI demo
simulate_comparison()ExtendedNow returns ROC-AUC, precision, recall

02Installation and Setup

2.1 Option A: PyPI Install

pip install trustlib-mas
from trustlib_mas import Trustee, Trustor, TrustScenario

2.2 Option B: Single-File Drop-In

Copy trustlib_mas.py into your project directory and import it directly:

my_project/
├── trustlib_mas.py
├── my_agent.py
└── ...

2.3 Option C: Source Install

git clone https://github.com/<your-username>/trustlib-mas.git
cd trustlib-mas
pip install -e .

2.4 Option D: Development Install

pip install -e ".[dev]"

2.5 Verifying Your Installation

import trustlib_mas

print(trustlib_mas.__version__)        # "1.1.0"
print(trustlib_mas.__paper_version__)  # "v3"
print(trustlib_mas.HEURISTIC_NOTE[:60] + "...")

Or run the built-in CLI demo:

python -m trustlib_mas

2.6 Importing What You Need

from trustlib_mas import (
    # Core classes
    Trustee, Trustor, TrustGroup, TrustScenario, TrustNetwork,
    # Aggregation
    AggregationType,
    # Helper functions
    harmonic_mean, geometric_mean, arithmetic_mean, median,
    sigmoid, strategic_factor,
    # Simulation and evaluation
    simulate_comparison,
    run_repeated_sim,
    run_ablation_study,
    run_robustness_check,
    verify_unification,
    # Classification metrics
    roc_auc,
    precision_recall,
    # Constants
    HEURISTIC_NOTE,
)

03Naming, Imports, and Versioning

3.1 Names at a Glance

ArtifactName
PyPI packagetrustlib-mas
Python importtrustlib_mas
Repositorytrustlib-mas
Main module filetrustlib_mas.py
Compatibility shimtrustlib.py
CLI entry pointpython -m trustlib_mas

3.2 Why the Hyphen–Underscore Split?

Python does not allow hyphens in module names, so the PyPI name (trustlib-mas) uses a hyphen while the import name (trustlib_mas) uses an underscore.

3.3 Version Tracking

import trustlib_mas
trustlib_mas.__version__        # "1.1.0"
trustlib_mas.__paper_version__  # "v3"

3.4 Backward Compatibility

from trustlib import Trustee, Trustor, TrustScenario   # still works

3.5 Deprecation Timeline

VersionStatus
1.0.x (trustlib)Legacy. No longer maintained.
1.1.x (trustlib-mas)Current. Shim provided.
2.0.x (planned)Shim may be removed.

04Conceptual Overview

4.1 The Trust Decision Problem

At its core, every use of trustlib-mas answers the question:

"Should agent i rely on agent j (or on a group G) for some task?"

4.2 The Three-Box Mental Model

   ┌─────────────────────┐     ┌─────────────────────┐     ┌─────────────────────┐
   │    TRUSTEE(S)       │     │      TRUSTOR        │     │     SCENARIO        │
   │  Who is being       │     │  Who is deciding    │     │  What are the       │
   │  evaluated?         │     │  whether to trust?  │     │  payoffs and stakes?│
   │                     │     │                     │     │                     │
   │  Trustee            │     │  Trustor            │     │  TrustScenario      │
   │  TrustGroup         │     │  τ, ρ, δ*, β_s      │     │  U_win, U_loss, S   │
   └─────────────────────┘     └─────────────────────┘     └─────────────────────┘

4.3 The Seven Layers at a Glance

LayerWhat It ModelsWhere You Set It
L1Perceived ability, benevolence, integrityTrustee.A, .B, .I
L2Risk-adjusted expected utilityTrustScenario.U_win, .U_loss, .stakes
L3Bayesian reliability with recencyTrustee.a, .b
L4Asymmetric trust build/destroyTrustee.k_build, .k_destroy
L5Strategic cooperation thresholdTrustee.discount_factor, Trustor.delta_star
L6Network propagationTrustNetwork
L7Group aggregationTrustGroup

4.4 When You Need Which Layer

If your scenario involves…Use…
A simple transaction with a strangerL1 + L2 + L3
Trust collapsing after a failureL4
An ongoing relationship with incentivesL5
Trust recommendations from othersL6
A team, committee, or multi-sig walletL7

4.5 The Group Trust Extension (GTE)

A trustor's confidence in a group G = {j_1, …, j_m} depends on the group's decision architecture:

  • Series (weakest-link): min(T_j) · κ
  • Parallel (redundancy): (1 − ∏(1 − T_j)) · κ
  • Quorum (k-of-m): P(X ≥ k) · κ with X ~ BetaBin(m, α, β)
  • Custom: any monotone f(T_j) · κ

4.6 The Unification Theorem

from trustlib_mas import verify_unification
print(verify_unification())
# {'specialisation': True, 'bayesian_consistency': True,
#  'strategic_consistency': True, 'bounds': True}

05Your First Trust Decision

5.1 The Scenario

A buyer on Amazon is considering an $800 camera from an unknown seller. The seller has 130 positive reviews and 20 negative reviews. If the camera works, the buyer gains $100 in value; if it's defective, the buyer loses the full $800.

5.2 The Code

from trustlib_mas import Trustee, Trustor, TrustScenario

seller = Trustee(
    id="seller", a=130, b=20, discount_factor=0.8
)

buyer = Trustor(
    id="buyer", trust_propensity=0.6, risk_aversion=0.2
)

scenario = TrustScenario(
    name="Amazon Camera", trustor=buyer, target=seller,
    U_win=100, U_loss=-800, stakes=800,
)

decision, trust, eu = scenario.run()

print(f"Effective trust: {trust:.3f}")     # 0.372
print(f"Expected utility: ${eu:.2f}")      # -465.20
print(f"Decision: {'BUY' if decision else 'DO NOT BUY'}")

5.3 Inspecting the Result

report = scenario.report()
for key, val in report.items():
    print(f"{key}: {val}")

Output:

name: Amazon Camera
effective_trust: 0.372...
expected_utility: -465.2
threshold: 160.0
decision: False

06Understanding the Trustee

6.1 Two Ways to Specify Trust

Method A — Beta parameters:

seller = Trustee("seller", a=130, b=20)
seller.bayes_mean()   # 0.867

Method B — Explicit trust:

car = Trustee("car")
car.trust = 0.65
car.current_trust()   # 0.65

6.2 The Three Cognitive Traits

ceo = Trustee("ceo", A=0.9, B=0.3, I=0.8)
P = ceo.perceived_trustworthiness(alpha=0.7, beta=0.2, gamma=0.1)
# P = 0.7*0.9 + 0.2*0.3 + 0.1*0.8 = 0.77

6.3 The Beta Parameters

Situationab
No history11
10 successes, 0 failures111
100 successes, 5 failures1016
50/50 split5050

6.4 Updating with Evidence

seller = Trustee("seller", a=1, b=1)
seller.update_bayes(success=True)         # a=2, b=1
seller.update_bayes(success=False)        # a=2, b=2
seller.update_bayes(success=True, lam=0.9)

6.5 The Discount Factor

Trustee typeTypical δ
Established seller, repeat business0.9–0.95
Regular contractor0.8–0.9
One-off transaction0.5–0.7
Untraceable anonymous0.3–0.5

6.6 The Build/Destroy Rates

Scenariok_buildk_destroyRatio
Human–robot0.10.88:1
Human–human (team)0.150.453:1
Institutional trust0.050.306:1

07Understanding the Trustor

7.1 Trust Propensity (τ)

τInterpretation
0.2–0.4Cautious, skeptical
0.5Neutral
0.6–0.8Trusting
0.9–1.0Highly trusting

7.2 Risk Aversion (ρ)

ρInterpretation
0.05Risk-tolerant, speculative
0.15–0.25Moderate
0.4–0.6Conservative, safety-critical
0.8+Highly risk-averse

7.3 Strategic Parameters

beta_sBehavior
2Very gradual transition
10Moderate (default)
20Close to a hard switch
100+Essentially a step function

7.4 Combining Multiple Trustors

ceo = Trustee("ceo", A=0.9, B=0.3, I=0.8)

for τ, label in [(0.3, "veteran"), (0.8, "newbie")]:
    trustor = Trustor(label, trust_propensity=τ)
    sc = TrustScenario("CEO", trustor, ceo, U_win=100, U_loss=-50, stakes=100)
    print(f"{label}: trust={sc.target_trust():.3f}")

08Making Decisions with TrustScenario

8.1 The Constructor

TrustScenario(
    name: str, trustor: Trustor, target: Trustee | TrustGroup,
    U_win: float = 1.0, U_loss: float = -1.0,
    stakes: float | None = None,
    alpha: float = 0.7, beta: float = 0.2, gamma: float = 0.1,
)

8.2 The Decision Rule

EU = T_eff · U_win + (1 − T_eff) · U_loss  ≥  ρ · S

8.3 Reading the Decision

decisionMeaning
TrueExpected utility exceeds threshold → rely on trustee
FalseExpected utility is below threshold → decline
Note. A False decision does not mean the trustee is untrustworthy. It means the risk/reward profile for this trustor under these stakes does not justify reliance.

8.4 Sensitivity Analysis

seller = Trustee("seller", a=130, b=20, discount_factor=0.8)

for ρ in [0.05, 0.1, 0.2, 0.3, 0.5]:
    trustor = Trustor("t", trust_propensity=0.6, risk_aversion=ρ)
    sc = TrustScenario("sweep", trustor, seller, 100, -800, 800)
    print(f"ρ={ρ:.2f} → trust={sc.target_trust():.3f}")

09Working with Groups

9.1 The Constructor

TrustGroup(
    members: list[Trustee],
    aggregation: AggregationType = AggregationType.SERIES,
    quorum_k: int | None = None, correlation_rho: float = 0.0,
    cohesion_pen: float = 0.0, cohesion_rew: float = 0.0,
    cohesion_tau: float = 0.0, entropy_override: float | None = None,
    custom_aggregator: Callable | None = None,
    collective_discount: float | None = None,
    apply_collective_strategic: bool = False,
    delta_star: float = 0.708, beta_s: float = 10.0,
)

9.2 The Bare Minimum

from trustlib_mas import Trustee, TrustGroup, AggregationType

trucks = [Trustee(f"T{i}", a=92, b=8) for i in range(4)]
trucks.append(Trustee("T4", a=40, b=60))

platoon = TrustGroup(trucks, aggregation=AggregationType.SERIES)
print(platoon.aggregate_trust())  # 0.40

9.3 Inspecting Components

print(platoon.individual_trusts())
print(platoon.aggregate_raw())
print(platoon.cohesion_factor())
print(platoon.aggregate_trust())

9.4 Adding Cohesion Penalty

platoon = TrustGroup(trucks, aggregation=AggregationType.SERIES,
                     cohesion_pen=10.0, cohesion_tau=0.02)
print(platoon.cohesion_factor())     # ~0.79
print(platoon.aggregate_trust())     # ~0.317
Note on the paper's value. The v3 manuscript reports 0.243 using an illustrative variance of σ² = 0.07. The library computes the exact population variance of the given trust vector (σ² ≈ 0.043), which yields 0.317.

9.5 Groups of Groups

def two_level(scores):
    a = min(scores[:3])
    b = min(scores[3:])
    return min(a, b)

g = TrustGroup(members, aggregation=AggregationType.CUSTOM,
               custom_aggregator=two_level)

10Aggregation Architectures in Depth

10.1 Series (Weakest-Link)

Formula: T = min(T_j) × κ

Use when: success requires every member to succeed — platoons, surgical teams, pipelines.

10.2 Parallel (Redundancy)

Formula: T = (1 − ∏(1 − T_j)) × κ

Use when: success requires at least one member to succeed — sensor arrays, backup systems.

10.3 Quorum (k-of-m)

g = TrustGroup(signers, aggregation=AggregationType.QUORUM,
               quorum_k=5, correlation_rho=0.2)

10.4 Custom

from trustlib_mas import harmonic_mean

g = TrustGroup(team, aggregation=AggregationType.CUSTOM,
               custom_aggregator=harmonic_mean)

10.5 Choosing the Right Architecture

Decision structureArchitecture
All must succeedSERIES
Any one sufficesPARALLEL
k must agreeQUORUM
Average/median/harmonicCUSTOM
Safety-critical teamSERIES + high ν_pen
Advisory panelQUORUM + ν_rew > 0

11The Cohesion–Diversity Function

11.1 The Formula

κ = min{ 1, exp( −ν_pen · max(0, σ² − τ) + ν_rew · H ) }

11.2 What Each Parameter Does

ParameterEffectTypical range
cohesion_penPenalizes high variance2–50
cohesion_rewRewards high entropy0–10
cohesion_tauVariance tolerance0.01–0.10

11.3 Entropy Source

ts = [0.9, 0.7, 0.5, 0.3]
# normalized: [0.375, 0.292, 0.208, 0.125]
# H = -Σ p log p ≈ 1.32 nats

# For classification scenarios (True/False labels):
g = TrustGroup(..., entropy_override=0.673)

11.4 A Decision Table

Scenarioν_penν_rewτ
Surgical team5000.01
Platoon1000.02
DAO multi-sig200.02
Advisory panel550.10
Sensor array100.05

12Correlated Quorum Models

12.1 The Correlation Parameter ρ

Scenarioρ
Independent sensors0.0
Signers in a DAO0.2
Members of the same firm0.3
Family members0.5

12.2 The Effect on Quorum Trust

signers = [Trustee(f"S{i}", a=90, b=10) for i in range(6)]
signers.append(Trustee("M", a=60, b=40))
signers.extend([Trustee(f"U{i}", a=40, b=60) for i in range(2)])

for ρ in [0.0, 0.1, 0.2, 0.3, 0.5]:
    g = TrustGroup(signers, aggregation=AggregationType.QUORUM,
                   quorum_k=5, correlation_rho=ρ)
    print(f"ρ={ρ:.1f}  raw={g.aggregate_raw():.4f}")

# ρ=0.0  raw=0.9636
# ρ=0.1  raw=0.9448
# ρ=0.2  raw=0.9113
# ρ=0.3  raw=0.8711
# ρ=0.5  raw=0.7982

13Temporal Dynamics and Trust Recovery

13.1 Simulating a Failure

car = Trustee("car", k_build=0.1, k_destroy=0.8)
car.trust = 0.65
car.asymmetric_dynamics(success=False)
print(car.trust)   # 0.130

13.2 Simulating Recovery

for i in range(20):
    car.asymmetric_dynamics(success=True)
    print(f"Ride {i+1}: T = {car.trust:.3f}")

13.3 Closed-Form Recovery Time

car.trust = 0.13
t = car.recovery_time(target=0.8, k_build=0.1)
print(f"{t:.2f} rides to recover to 0.8")   # 14.70

13.4 Choosing Build/Destroy Rates

Domaink_buildk_destroy
Robotaxi0.10.8
Chatbot0.20.6
Team member0.150.45
Institutional0.050.30
Do not call asymmetric_dynamics and update_bayes for the same event. Choose one: use update_bayes for a principled Bayesian count, or asymmetric_dynamics for a phenomenological trust level.

14Network Propagation

14.1 Setting Up a Network

from trustlib_mas import TrustNetwork

net = TrustNetwork(n_agents=4)
net.set_direct(0, 1, 0.9)
net.set_direct(0, 2, 0.4)
net.set_direct(1, 2, 0.95)
net.set_direct(1, 3, 0.7)
net.set_direct(2, 3, 0.85)

14.2 One-Step and Iterated Updates

net.update(mu=0.5)              # one damped step
net.iterate(steps=10, mu=0.5)   # ten steps
T^(t+1) = μ · T_direct + (1 − μ) · T_indirect
  • μ = 1 → ignore network (pure direct)
  • μ = 0 → ignore direct (pure indirect)
  • μ = 0.5 → balanced (typical)

14.3 Combining with TrustScenario

net.iterate(steps=5)
propagated = net.direct[0][3]

target = Trustee("target")
target.trust = propagated
sc = TrustScenario("Propagated", trustor, target,
                   U_win=100, U_loss=-200, stakes=200)

15Simulation and Evaluation Toolkit

15.1 Proof-of-Concept Simulation

from trustlib_mas import simulate_comparison

results = simulate_comparison(
    n_scenarios=2000, seed=42, rho_true=0.2,
)

for name, r in results.items():
    print(f"{name:<12} acc={r['accuracy']:.3f} "
          f"brier={r['brier']:.3f} auc={r['roc_auc']:.3f}")

# unified    acc=0.907 brier=0.074 auc=0.939
# average    acc=0.789 brier=0.121 auc=0.881
# minmax     acc=0.842 brier=0.150 auc=0.851
# binomial   acc=0.851 brier=0.106 auc=0.901

15.2 Classification Metrics

from trustlib_mas import roc_auc, precision_recall

labels = [1, 0, 1, 1, 0, 1, 0, 1]
scores = [0.9, 0.3, 0.8, 0.7, 0.4, 0.85, 0.2, 0.75]

print(f"ROC-AUC: {roc_auc(labels, scores):.4f}")
prec, rec = precision_recall(labels, scores, threshold=0.5)
print(f"Precision: {prec:.4f}  Recall: {rec:.4f}")

15.3 Repeated Simulation with 95% Confidence Intervals

from trustlib_mas import run_repeated_sim

summary = run_repeated_sim(
    n_scenarios=2000, n_repeats=50, base_seed=0, rho_true=0.2,
)

for model, metrics in summary.items():
    acc, acc_hw = metrics["accuracy"]
    br,  br_hw  = metrics["brier"]
    auc, auc_hw = metrics["roc_auc"]
    print(f"{model:<12}"
          f"{acc:>10.3f} ± {acc_hw:<8.3f}"
          f"{br:>10.3f} ± {br_hw:<8.3f}"
          f"{auc:>10.3f} ± {auc_hw:<8.3f}")

15.4 Ablation Study

from trustlib_mas import run_ablation_study

results = run_ablation_study(n_scenarios=2000, seed=42)
for name, r in results.items():
    print(f"{name:<24} acc={r['accuracy']:.3f} brier={r['brier']:.3f}")

# full                     acc=0.902 brier=0.073
# no_cohesion              acc=0.856 brier=0.095
# no_correlated_quorum     acc=0.871 brier=0.088
# no_strategic             acc=0.847 brier=0.101
# no_temporal              acc=0.864 brier=0.092

15.5 Robustness to Model Misspecification

from trustlib_mas import run_robustness_check

results = run_robustness_check(n_scenarios=2000, seed=42)
for regime, r in results.items():
    print(f"{regime:<16} acc={r['accuracy']:.3f} brier={r['brier']:.3f}")

acc_matched = results["matched"]["accuracy"]
acc_misspec = results["misspecified"]["accuracy"]
drop = (acc_matched - acc_misspec) / acc_matched * 100
print(f"\nRelative accuracy drop: {drop:.1f}%")

# matched        acc=0.906  brier=0.074
# misspecified   acc=0.883  brier=0.089
# Relative accuracy drop: 2.5%

15.6 Runtime Considerations

FunctionDefault n_scenariosTypical runtime
simulate_comparison2,000< 1 s
run_repeated_sim (50 repeats)2,000~30 s
run_ablation_study2,000~5 s
run_robustness_check2,000~2 s

16Verifying the Unification Theorem

The theorem has four parts, each verified numerically:

  1. Specialisation — for m = 1, the GTE reduces to the dyadic model.
  2. Bayesian consistency — the group Bayesian update with m = 1 matches the dyadic update.
  3. Strategic consistency — the collective discount factor equals the individual δ when m = 1.
  4. Bounds — all trust scores remain in [0, 1].
from trustlib_mas import verify_unification

for part, ok in verify_unification().items():
    print(f"  {part:<24} [{'PASS' if ok else 'FAIL'}]")

#   specialisation           [PASS]
#   bayesian_consistency     [PASS]
#   strategic_consistency    [PASS]
#   bounds                   [PASS]

17Common Recipes

17.1 Trust a Seller from Reviews

def seller_trust(pos, neg, tau=0.6, rho=0.2, price=800, surplus=100):
    seller = Trustee("seller", a=pos + 1, b=neg + 1, discount_factor=0.8)
    buyer  = Trustor("buyer", trust_propensity=tau, risk_aversion=rho)
    sc = TrustScenario("Amazon", buyer, seller,
                       U_win=surplus, U_loss=-price, stakes=price)
    return sc.run()

17.2 Evaluate a Multi-Sig Wallet

def multisig_trust(trusts, k, rho=0.2):
    members = [Trustee(f"S{i}", a=100*t, b=100*(1-t))
               for i, t in enumerate(trusts)]
    g = TrustGroup(members, aggregation=AggregationType.QUORUM,
                   quorum_k=k, correlation_rho=rho,
                   cohesion_pen=2.0, cohesion_tau=0.02)
    return g.aggregate_trust()

17.3 Simulate a Failure-and-Recovery Trajectory

def trajectory(initial, failure_at, n_rides=30):
    car = Trustee("car", k_build=0.1, k_destroy=0.8)
    car.trust = initial
    history = [car.trust]
    for i in range(n_rides):
        car.asymmetric_dynamics(success=(i != failure_at))
        history.append(car.trust)
    return history

17.4 Bayesian A/B Comparison

def compare(a_s, a_f, b_s, b_f, n_samples=10000):
    import random
    rng = random.Random(0)
    a_wins = 0
    for _ in range(n_samples):
        pa = rng.betavariate(a_s + 1, a_f + 1)
        pb = rng.betavariate(b_s + 1, b_f + 1)
        a_wins += int(pa > pb)
    return a_wins / n_samples

17.5 Reproducing the Paper's Tables

from trustlib_mas import (
    run_repeated_sim, run_ablation_study, run_robustness_check,
)

summary    = run_repeated_sim(n_scenarios=2000, n_repeats=50, base_seed=0)
ablation   = run_ablation_study(n_scenarios=2000, seed=42)
robustness = run_robustness_check(n_scenarios=2000, seed=42)

18Advanced Usage

18.1 Custom Aggregation with Weights

def weighted_min(scores, weights):
    return min(s / w for s, w in zip(scores, weights) if w > 0)

def make_weighted_min(weights):
    return lambda scores: weighted_min(scores, weights)

g = TrustGroup(members, aggregation=AggregationType.CUSTOM,
               custom_aggregator=make_weighted_min([1.0, 1.0, 0.5, 1.0]))

18.2 Dynamic Group Composition

def step_with_churn(group, arrive=None, depart=None):
    members = [m for m in group.members if m.id not in (depart or [])]
    if arrive:
        members.append(arrive)
    return TrustGroup(members, aggregation=group.aggregation,
                      cohesion_pen=group.cohesion_pen,
                      cohesion_tau=group.cohesion_tau)

18.3 Subclassing Trustee for Custom Dynamics

class LevyTrustee(Trustee):
    jump_size: float = 0.2
    jump_prob: float = 0.05

    def asymmetric_dynamics(self, success, **kwargs):
        super().asymmetric_dynamics(success, **kwargs)
        import random
        if random.random() < self.jump_prob:
            self.trust = max(0.0, self.trust - self.jump_size)
        return self.trust

18.4 Calibration via Maximum Likelihood

from itertools import product

def fit_params(dataset, ν_grid, ρ_grid):
    best = None
    for ν_pen, ν_rew, ρ in product(ν_grid, ν_grid, ρ_grid):
        loss = 0.0
        for features, y in dataset:
            g = TrustGroup(features, aggregation=AggregationType.QUORUM,
                           quorum_k=len(features)//2+1,
                           correlation_rho=ρ,
                           cohesion_pen=ν_pen,
                           cohesion_rew=ν_rew)
            loss += (g.aggregate_trust() - y) ** 2
        if best is None or loss < best[0]:
            best = (loss, ν_pen, ν_rew, ρ)
    return best

19Parameter Calibration Guide

ParameterClassHow to Calibrate
a, bTrusteeCount successes/failures
A, B, ITrusteeSurvey instruments
discount_factorTrusteeRepeated-game data
k_build, k_destroyTrusteeFit to recovery curves
trust_propensityTrustorDisposition survey
risk_aversionTrustorLottery elicitation
correlation_rhoTrustGroupMethod of moments
cohesion_*TrustGroupMLE on team performance

Practical Heuristics When You Have No Data

ParameterHeuristic
τ0.5 (neutral) or 0.6 (slightly trusting)
ρ0.2 (moderate)
δ0.8 (established relationship)
δ*0.708 (default)
β_s10
k_build0.1
k_destroy0.6 (3:1) to 0.8 (8:1)
ν_pen10 safety-critical, 2 advisory
ρ_corr0.2

20Troubleshooting

20.1 "ModuleNotFoundError: No module named 'trustlib'"

You may have upgraded to trustlib-mas but your code still imports the old name.

# Option A: install the shim
pip install trustlib-mas

# Option B: update imports
from trustlib_mas import Trustee     # instead of: from trustlib import Trustee

20.2 "ValueError: quorum_k must be set for QUORUM aggregation"

g = TrustGroup(members, aggregation=AggregationType.QUORUM, quorum_k=5)

20.3 "ValueError: custom_aggregator must be provided"

g = TrustGroup(members, aggregation=AggregationType.CUSTOM,
               custom_aggregator=harmonic_mean)

20.4 "ValueError: TrustGroup must contain at least one member"

Empty group. Add members or check your construction loop.

20.5 Trust Always 0 or 1

  • Are a and b sensible?
  • Is discount_factor below delta_star?
  • Is trust_propensity set to something reasonable?

20.6 Cohesion Factor Always 1

  • Is cohesion_pen > 0?
  • Is the variance actually above cohesion_tau?
  • For single-member groups, κ = 1 by definition.

20.7 Correlation Has No Effect

  • Is ρ above 1e-6?
  • Is aggregation=QUORUM?

20.8 Decision Flips Unexpectedly

  • U_loss sign (should usually be negative)
  • stakes too small or too large
  • risk_aversion too low

Print scenario.report() to inspect all intermediates.

20.9 Simulation Function Raises NaN

If you see nan in ROC-AUC or precision/recall, your data is likely all one class. Increase n_scenarios or adjust rho_true.

20.10 verify_unification() Fails

If any part of the Unification Theorem fails to verify, the core mathematics have been altered (perhaps by a monkey-patch or a subclass). Restore the library to its original state, or file an issue.

21Best Practices

21.1 Model Design

  1. Start simple. Use just L1–L3 for a first prototype.
  2. Keep units consistent.
  3. Sign discipline. U_loss should be negative.
  4. Weights sum to 1. alpha + beta + gamma = 1.
  5. Document parameters. Record where each number came from.

21.2 Coding Practices

  1. Use dataclasses. Construct in one place and pass around.
  2. Do not mutate shared trustees. Changes propagate.
  3. Separate model from data. Parameter values in config.
  4. Log intermediate values. scenario.report() is your friend.

21.3 Scientific Practices

  1. Report calibration. State where each parameter came from.
  2. Report sensitivity. Show how the decision changes with ρ, ν_pen.
  3. Use held-out data. Reserve a test set.
  4. Do not over-claim. A simulation is not empirical validation.
  5. Cite the framework and paper version.

21.4 Reproducibility

  • Always fix seed when running simulations.
  • Report n_scenarios and n_repeats.
  • Include trustlib_mas.__version__ and trustlib_mas.__paper_version__ in your methods.

22Frequently Asked Questions

Q1. Do I need all seven layers?

No. Start with L1–L3 for a basic model. Add L4–L7 as needed.

Q2. What's the difference between trust and a/b?

a/b is a Bayesian count that can be updated. trust is an explicit override.

Q3. Why is my decision False even though the trustee has high trust?

Because expected utility, not trust alone, drives the decision.

Q4. Why does the paper report 0.243 for the platoon but the library reports 0.317?

The paper's σ² = 0.07 is illustrative; the library computes the exact variance (≈ 0.043).

Q5. Can I use the library for reinforcement learning?

Yes, as a trust-value function.

Q6. How do I model a Sybil attack?

Low a, high b, and very low discount_factor (0.2). The strategic override will suppress trust.

Q7. What if I don't know delta_star?

Use 0.708 for the standard PD payoff. For other games, compute (T-R)/(T-P).

Q8. Can I model mixed human-AI teams?

Yes. Humans and AIs are both Trustee instances.

Q9. How do I test my model?

Use test_trustlib_mas.py as a template. Verify bounds and unification.

Q10. Can I use the library commercially?

Yes — MIT license.

Q11. How do I cite the library?

See the Citation section in the README. Cite the manuscript too.

Q12. Why is the package called trustlib-mas but the import trustlib_mas?

Python does not allow hyphens in module names.

Q13. Will from trustlib import ... still work?

Yes, as long as the shim ships with the package.

Q14. How do I know which paper version the library targets?

Check trustlib_mas.__paper_version__. For v1.1.0, this is "v3".

Q15. How do I run the ablation study quickly?

Use run_ablation_study(n_scenarios=500).

23Reference Tables

23.1 Aggregation Types

TypeFormulaUse case
SERIESmin(T_j) × κAll-must-succeed
PARALLEL(1 − ∏(1−T_j)) × κAny-succeeds
QUORUMP(X ≥ k) × κk-of-m
CUSTOMf(T_j) × κAnything monotone

23.2 Strategic Factor Values

δΦ(δ) at β_s=10, δ*=0.708
0.30.016
0.50.111
0.60.254
0.7080.500
0.80.715
0.90.874
0.950.922

23.3 Cohesion Penalty Examples

ν_penκ (σ²=0.05, τ=0)
10.951
50.779
100.607
200.368
500.082

23.4 Quorum Survival with Correlation

ρP(X ≥ 5)
0.00.96
0.10.94
0.20.91
0.30.87
0.50.80

23.5 Simulation Function Signatures

FunctionSignature
simulate_comparison(n_scenarios=2000, seed=0, rho_true=0.2, n_repeats=1)
run_repeated_sim(n_scenarios=2000, n_repeats=50, base_seed=0, rho_true=0.2)
run_ablation_study(n_scenarios=2000, seed=42, rho_true=0.2)
run_robustness_check(n_scenarios=2000, seed=42, rho_true=0.2)
verify_unification(tolerance=1e-9)

24Glossary

TermDefinition
TrusteeThe agent being evaluated
TrustorThe agent making the decision
Effective trustThe final trust score after all layers
Cohesion factor (κ)Multiplier reflecting group coordination
Correlation (ρ)Degree of dependence among group members
Discount factor (δ)Trustee's long-term orientation
Betrayal threshold (δ*)Minimum δ for sustained cooperation
Trust propensity (τ)Trustor's baseline willingness
Brier scoreMSE of probabilistic predictions
ROC-AUCArea under the ROC curve
Weakest-linkSeries aggregation (min)
RedundancyParallel aggregation (1 − ∏)
GTEGroup Trust Extension
AblationRemoving one component to measure its contribution
MisspecificationData-generating process differing from model assumptions

AComplete Working Example

"""
complete_example.py — Exercises every major feature of trustlib-mas v1.1.0.
Run: python complete_example.py
"""

import trustlib_mas
from trustlib_mas import (
    Trustee, Trustor, TrustGroup, TrustScenario, TrustNetwork,
    AggregationType, harmonic_mean,
    simulate_comparison, run_repeated_sim, run_ablation_study,
    run_robustness_check, verify_unification, roc_auc, precision_recall,
)


def main():
    print(f"trustlib_mas v{trustlib_mas.__version__} "
          f"(paper {trustlib_mas.__paper_version__})")

    print("\n[1] Unification check")
    for part, ok in verify_unification().items():
        print(f"    {part:<24} {'PASS' if ok else 'FAIL'}")

    print("\n[2] Dyadic: e-commerce seller")
    buyer  = Trustor("buyer", trust_propensity=0.6, risk_aversion=0.2)
    seller = Trustee("seller", a=130, b=20, discount_factor=0.8)
    sc = TrustScenario("Amazon", buyer, seller,
                       U_win=100, U_loss=-800, stakes=800)
    print("   ", sc.report())

    print("\n[3] Asymmetric dynamics: robotaxi")
    car = Trustee("car", k_build=0.1, k_destroy=0.8)
    car.trust = 0.65
    car.asymmetric_dynamics(success=False)
    print(f"    After failure: T = {car.trust:.3f}")
    print(f"    Recovery time: {car.recovery_time(0.8):.2f} rides")

    print("\n[4] Group: platoon (series)")
    trucks = [Trustee(f"T{i}", a=92, b=8) for i in range(4)]
    trucks.append(Trustee("T4", a=40, b=60))
    platoon = TrustGroup(trucks, aggregation=AggregationType.SERIES,
                         cohesion_pen=10.0, cohesion_tau=0.02)
    print(f"    T_agg = {platoon.aggregate_trust():.3f}")

    print("\n[5] Group: DAO multi-sig (correlated quorum)")
    signers = [Trustee(f"S{i}", a=90, b=10) for i in range(6)]
    signers.append(Trustee("M", a=60, b=40))
    signers.extend([Trustee(f"U{i}", a=40, b=60) for i in range(2)])
    dao = TrustGroup(signers, aggregation=AggregationType.QUORUM,
                     quorum_k=5, correlation_rho=0.2,
                     cohesion_pen=2.0, cohesion_tau=0.02)
    print(f"    T_agg = {dao.aggregate_trust():.3f}")

    print("\n[6] Group: surgical team (custom harmonic)")
    team = TrustGroup(
        [Trustee("Surgeon", a=95, b=5), Trustee("Anes", a=90, b=10),
         Trustee("Nurse1", a=98, b=2), Trustee("Nurse2", a=70, b=30),
         Trustee("Perf", a=85, b=15)],
        aggregation=AggregationType.CUSTOM,
        custom_aggregator=harmonic_mean,
        cohesion_pen=5.0, cohesion_tau=0.01,
    )
    print(f"    T_agg = {team.aggregate_trust():.3f}")

    print("\n[7] Network propagation")
    net = TrustNetwork(4)
    net.set_direct(0, 1, 0.9); net.set_direct(0, 2, 0.4)
    net.set_direct(1, 2, 0.95); net.set_direct(1, 3, 0.7)
    net.set_direct(2, 3, 0.85)
    net.iterate(steps=5, mu=0.5)
    print(f"    Propagated 0→3: {net.direct[0][3]:.4f}")

    print("\n[8] Simulation (single seed)")
    res = simulate_comparison(n_scenarios=1000, seed=42)
    for name, r in res.items():
        print(f"    {name:<10} acc={r['accuracy']:.3f} "
              f"brier={r['brier']:.3f} auc={r['roc_auc']:.3f}")

    print("\n[9] Repeated simulation (5 repeats, 95% CI)")
    summary = run_repeated_sim(n_scenarios=500, n_repeats=5, base_seed=0)
    for model, m in summary.items():
        acc, hw = m["accuracy"]
        print(f"    {model:<10} acc={acc:.3f} ± {hw:.3f}")

    print("\n[10] Ablation study")
    for name, r in run_ablation_study(n_scenarios=500).items():
        print(f"    {name:<22} acc={r['accuracy']:.3f}")

    print("\n[11] Robustness check")
    rob = run_robustness_check(n_scenarios=500)
    for regime, r in rob.items():
        print(f"    {regime:<14} acc={r['accuracy']:.3f}")


if __name__ == "__main__":
    main()

BFurther Reading

  • Mayer, Davis, & Schoorman (1995) — Cognitive antecedents of trust
  • Jøsang & Ismail (2002) — Beta reputation systems
  • Axelrod (1984) — Evolution of cooperation
  • Surowiecki (2004) — Wisdom of crowds
  • Ponnambalam et al. (2021) — Prior MAS trust framework
  • Cheng et al. (2021, AAMAS) — General trust framework with epistemic logic
  • Skellam (1948) — Beta-binomial distribution
  • Wang (2026, v3) — The unified dyadic-and-collective framework (manuscript)

CVersion History

VersionDateNotes
1.0.02026Initial release as trustlib
1.1.02026Renamed to trustlib-mas; aligned with paper v3; added simulation & evaluation toolkit
👤