Tutorial

Trust, built in seven layers

A narrative introduction that builds the framework from first principles — no mathematics prerequisites. Each layer is explained with intuition first, formalism second, and code third. Seven hands-on walkthroughs apply the framework to concrete scenarios.

Read time ~30 minutes
Prerequisites None
Paper version v3
Library v1.1.0
Part I

Foundations

Why trust needs layers, what each layer answers, and where the dyadic baseline sits in the framework.

1.1Why Trust Needs Layers

The Problem with "Just Give Me a Number"

Suppose you are building an autonomous purchasing agent. It must decide whether to buy a refurbished camera from an unknown seller on Amazon. The naive approach is to compute a single trust score — say, "the seller is 87% trustworthy" — and act if the score exceeds some threshold.

This fails for three reasons.

Reason 1 — Context. Trust is not a property of the seller alone. The same seller might be highly trustworthy for a $20 phone case and highly untrustworthy for an $800 camera. Trustworthiness in the abstract is meaningless; it is trustworthiness for a task, under stakes.
Reason 2 — Relation. Trust is not a property of the trustee alone. Two buyers evaluating the same seller may reach opposite decisions. A cautious buyer and a trusting buyer have different baselines, different risk tolerances, and different payoff structures. Trust is a relation, not an attribute.
Reason 3 — Time. Trust is not static. A seller with a thousand positive reviews is not the same seller after a single fraud report. Trust builds slowly and collapses fast. A model that treats trust as a fixed number cannot capture this asymmetry.

The layered framework addresses all three problems by decomposing trust into seven independent-but-coupled components, each answering a distinct question.

1.2The Seven Questions

Each layer of the framework answers one question:

LayerQuestion it answers
L1 — Perceived Trustworthiness What do I believe about this trustee's competence, goodwill, and honesty?
L2 — Behavioral Threshold Given what I believe, is acting on that belief worth the risk?
L3 — Bayesian Learning How do I update my belief as I observe new evidence?
L4 — Temporal Dynamics How does trust evolve between observations — and how does it break?
L5 — Strategic Layer Does the trustee have an incentive to betray me?
L6 — Network Propagation What can I infer from others' experiences?
L7 — Group Trust Extension How do I trust a team, committee, or multi-signature wallet?

You do not need all seven. A simple transaction might use only L1–L3. An ongoing relationship might add L4 and L5. A coalition decision might add L6 and L7. The framework is composable: layers can be switched on and off without breaking the others.

1.3The Dyadic Baseline

The framework's starting point is the classical dyadic relationship: one trustor i evaluating one trustee j at time t, producing a trust score T_{i,j}(t) ∈ [0,1].

This is the form most computational trust models take (Mayer–Davis–Schoorman, Beta reputation, TrustWalker). The framework's contribution is to show that this dyadic model is a special case of a more general collective model, and that the seven layers compose cleanly into both.

Part II

The Seven Layers

Each layer in turn: the question it answers, the intuition behind it, the formalism, and code that exercises it.

L1Perceived Trustworthiness

What do I actually believe about this trustee?

The Idea

The Mayer–Davis–Schoorman cognitive trust model, which has been validated across decades of organizational psychology, holds that trustworthiness has three components:

  • Ability (A) — can the trustee do the job?
  • Benevolence (B) — does the trustee want to help me?
  • Integrity (I) — will the trustee keep their word?

A surgeon may be highly able but have poor bedside manner (low benevolence). A friend may be benevolent but not competent to perform surgery (low ability). Both matter, and they matter differently depending on the context.

The Formalism

P_{i,j}(t) = α · A_{i,j}(t) + β · B_{i,j}(t) + γ · I_{i,j}(t),    α + β + γ = 1

The weights α, β, γ encode what matters in this domain. For a surgical team, ability might dominate (α = 0.7). For a customer service interaction, benevolence might matter more.

The trustor's propensity τ_i ∈ [0,1] modulates the baseline willingness:

T^{static}_{i,j}(t) = τ_i · P_{i,j}(t)

In Code

from trustlib_mas import Trustee, Trustor

ceo     = Trustee("ceo", A=0.90, B=0.30, I=0.80)
veteran = Trustor("veteran", trust_propensity=0.30)
newbie  = Trustor("newbie",  trust_propensity=0.80)

P = ceo.perceived_trustworthiness(alpha=0.7, beta=0.2, gamma=0.1)
print(f"P = {P:.3f}")                # P = 0.770

print(veteran.trust_propensity * P)  # 0.231
print(newbie.trust_propensity * P)   # 0.616
What to notice. The same CEO produces very different static trust scores for two employees. This is not a bug — it is the framework's way of encoding that trust is a relation. If you find yourself wanting a "single trust number" for a trustee, you are implicitly assuming a specific trustor.

L2The Behavioral Threshold

Trustworthiness is not the same as action. When should I actually act?

The Idea

Trust is only actionable under risk. If the trustee always does the right thing, there is nothing to decide. The decision to rely on someone is an expected-utility calculation.

The Formalism

E[U_{i,j}(t)] = P_{i,j}(t) · U_win + (1 − P_{i,j}(t)) · U_loss

The trustor acts if E[U] ≥ θ_i(t), where θ_i(t) = ρ_i · S(t) combines the trustor's risk aversion ρ_i and the situational stakes S(t).

The critical insight. A trustee can be highly trustworthy and still be declined. If the loss dominates the gain, no amount of trustworthiness makes the bet attractive. This is why "trust" and "should I act?" are distinct questions.

In Code

from trustlib_mas import Trustee, Trustor, TrustScenario

buyer  = Trustor("buyer", trust_propensity=0.6, risk_aversion=0.20)
seller = Trustee("seller", a=130, b=20, discount_factor=0.80)

sc = TrustScenario("Amazon", buyer, seller,
                   U_win=100, U_loss=-800, stakes=800)
decision, trust, eu = sc.run()

print(f"Trust:     {trust:.3f}")           # 0.372
print(f"EU:        {eu:.2f}")              # -465.29
print(f"Threshold: {sc.threshold():.2f}")  # 160.00
print(f"Decision:  {'BUY' if decision else 'DO NOT BUY'}")   # DO NOT BUY
What to notice. The seller's review history is strong (86.7% positive), yet the decision is "Do Not Buy." The reason is not that the seller is untrustworthy — it is that the payoff structure (+$100 vs. −$800) makes the bet unattractive to a moderately risk-averse buyer.

L3Bayesian Learning

How do I update my belief when I observe new evidence?

The Idea

Trust is not fixed. Each interaction — success or failure — should update the trustee's reliability estimate. The natural framework for this is Bayesian inference with a Beta-Binomial conjugate prior.

The Formalism

P_{i,j}(t) ~ Beta(a_{i,j}(t), b_{i,j}(t))
E[P_{i,j}(t)] = a_{i,j}(t) / (a_{i,j}(t) + b_{i,j}(t))

a_{i,j}(t+1) = λ · a_{i,j}(t) + s
b_{i,j}(t+1) = λ · b_{i,j}(t) + (1 − s)

The recency parameter λ ∈ (0, 1] controls how much old evidence is discounted.

In Code

from trustlib_mas import Trustee

seller = Trustee("seller", a=1, b=1)
print(seller.bayes_mean())   # 0.500

for _ in range(3):
    seller.update_bayes(success=True)
print(f"a={seller.a}, b={seller.b}, mean={seller.bayes_mean():.3f}")
# a=4.0, b=1.0, mean=0.800

seller.update_bayes(success=False, lam=0.9)
print(f"a={seller.a:.2f}, b={seller.b:.2f}, mean={seller.bayes_mean():.3f}")
# a=3.60, b=1.90, mean=0.654
What to notice. The recency update discounts old evidence before adding new. After the failure, the mean drops from 0.80 to 0.65 — the discounting of prior successes amplifies the effect of a single recent failure.

L4Temporal Dynamics

What happens between observations? And why does trust break so much faster than it builds?

The Idea

Trust is not just a running average of evidence. It decays autonomously when no evidence arrives, and it responds asymmetrically to successes and failures. This asymmetry — the negativity bias — is one of the most robust findings in human-automation trust research.

The Formalism

dP_{i,j}/dt = −δ · (P_{i,j}(t) − P_baseline)

dT_{i,j}/dt = k_build (1 − T_{i,j}) · 1_success
            − k_destroy · T_{i,j} · 1_failure

Recovery time: t = (1/k_build) · ln( (1 − T_0) / (1 − T*) )

In Code

from trustlib_mas import Trustee

car = Trustee("robotaxi", k_build=0.1, k_destroy=0.8)
car.trust = 0.65

car.asymmetric_dynamics(success=False)
print(f"After failure: {car.trust:.3f}")     # 0.130

t = car.recovery_time(target=0.80)
print(f"Recovery time: {t:.2f} rides")       # 14.70 rides
What to notice. A single failure collapses trust from 0.65 to 0.13 — an 80% drop. Recovery to 0.80 takes nearly 15 successful rides. The ratio k_destroy / k_build = 8 captures the severe collapse observed in real human-robot interaction studies.

L5The Strategic Layer

Cognitive trustworthiness is not enough. Does the trustee have an incentive to betray me?

The Idea

A trustee may be perfectly able, benevolent, and honest, yet still defect if the incentives are wrong. In an infinitely repeated Prisoner's Dilemma, the trustee cooperates if and only if their discount factor δ exceeds a critical threshold.

The Formalism

δ* = (T − R) / (T − P)

Φ(δ_j) = σ( β_s (δ_j − δ*) ),    σ(x) = 1 / (1 + e^{−x})
Authors' modeling choice. The logistic relaxation is introduced as a modeling choice, not as a derivation. Discontinuous thresholds produce discontinuous decisions, which are unrealistic and numerically awkward. The logistic provides a smooth transition.

In Code

from trustlib_mas import Trustee, Trustor, TrustScenario, strategic_factor

for delta in [0.50, 0.60, 0.708, 0.80, 0.90]:
    phi = strategic_factor(delta, delta_star=0.708, beta_s=10.0)
    print(f"delta={delta:.3f}  Phi={phi:.4f}")

lender   = Trustor("lender", trust_propensity=0.5, risk_aversion=0.25)
borrower = Trustee("borrower", a=68, b=2, discount_factor=0.60)
sc = TrustScenario("P2P", lender, borrower,
                   U_win=750, U_loss=-5000, stakes=5000)
print(sc.report())
What to notice. The borrower has an excellent credit score (Beta mean ≈ 0.971) but a low discount factor (0.60). The strategic override suppresses trust to 0.254 of its cognitive value, and the loan is declined.

L6Network Propagation

I have never interacted with this trustee. Can I learn from others?

The Idea

If agent A trusts agent B, and B trusts agent C, then A has indirect evidence about C. Layer 6 aggregates these indirect paths.

The Formalism

T^{indirect}_{i,j}(t) = ( Σ_{k ≠ i,j} T_{i,k} · T_{k,j} · φ_{i,k} )
                      / ( Σ_{k ≠ i,j} T_{i,k} · φ_{i,k} + ε )

T(t+1) = μ · T_direct(t+1) + (1 − μ) · T_indirect(t)

In Code

from trustlib_mas import TrustNetwork

net = TrustNetwork(n_agents=4)
net.set_direct(0, 1, 0.90)
net.set_direct(0, 2, 0.40)
net.set_direct(1, 2, 0.95)
net.set_direct(1, 3, 0.70)
net.set_direct(2, 3, 0.85)

net.iterate(steps=5, mu=0.5)

for row in net.direct:
    print([round(x, 3) for x in row])

print(f"Agent 0's trust in agent 3: {net.direct[0][3]:.4f}")
What to notice. Agent 0 has no direct edge to agent 3, but learns an estimate (≈ 0.41) through two paths: one through agent 1 (strong trust, high credibility) and one through agent 2 (weaker trust).

L7The Group Trust Extension

Layer 7 is the paper's central contribution and deserves its own part. See Part III below.

Part III

The Group Trust Extension

How the framework generalizes from one trustee to a structured group, and why the dyadic model is a special case.

3.1The Problem with "Sum of Parts"

Suppose you are deciding whether to trust a five-truck autonomous platoon. Four trucks are reliable (trust = 0.92); one has a sensor glitch (trust = 0.40). What is your trust in the platoon?

The naive answer is the average: 0.816. But this is wrong for a platoon, because the platoon requires all trucks to function. If any one fails, the formation fails. The platoon's reliability is closer to the weakest link — 0.40.

The Group Trust Extension formalizes this intuition. It says: trust in a group depends on the group's decision architecture.

3.2Four Aggregation Architectures

Series (weakest-link)

T^{series}_{i,G} = min_{j ∈ G} (T_{i,j}) · κ

Used for: platoons, surgical teams, sequential pipelines.

Parallel (redundancy)

T^{parallel}_{i,G} = ( 1 − Π_{j ∈ G} (1 − T_{i,j}) ) · κ

Used for: sensor arrays, backup systems, ensembles.

Quorum (k-of-m)

T^{quorum}_{i,G} = P(X ≥ k) · κ,    X ~ BetaBin(m, α, β)

Used for: DAO multi-signature wallets, juries, boards.

Custom

T^{custom}_{i,G} = f(T_{i,j}, …) · κ

Used for: harmonic mean (surgical teams), weighted averages.

3.3The Cohesion–Diversity Factor κ

κ = min{ 1, exp( −ν_pen · max(0, σ² − τ) + ν_rew · H ) }
  • σ² — variance of individual trust scores
  • H — Shannon entropy of the trust distribution
  • ν_pen — penalizes excess variance
  • ν_rew — rewards entropy
  • τ — variance tolerance
Important caveat. This functional form is a proposed heuristic. The manuscript is explicit about this. Its shape is not derived from first principles; it requires calibration for each domain.

3.4The Correlated Quorum

The quorum formula above assumes members fail independently. This is often wrong. In a DAO, signers may collude. In a sensor array, sensors may share a firmware bug. The framework accounts for this with a correlation parameter ρ ∈ [0, 1).

α = T̄ · (1 − ρ) / ρ,    β = (1 − T̄) · (1 − ρ) / ρ
The direction of the effect. For thresholds above the mean (k > m·T̄), positive correlation reduces the survival probability, because members fail together. Most realistic multi-signature scenarios fall in this regime, so the framework's correlated quorum is deliberately conservative.

3.5The Collective Strategic Factor

Φ_G = σ( β_s (Δ_G − δ*) )

T^{eff}_{i,G} = T^{agg}_{i,G} · Φ_G

3.6The Unification Theorem

For m = 1, the entire Group Trust Extension reduces exactly to the dyadic model. This means the framework is a strict generalization — you can use the group machinery everywhere, and it will never disagree with the dyadic case when there is only one member.

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

Using the Library

The four core classes, the decision pipeline, and the evaluation toolkit you will use to inspect and validate your model.

4.1The Four Core Classes

ClassRepresentsKey attributes
Trustee The agent being evaluated a, b, A, B, I, discount_factor, k_build, k_destroy
Trustor The agent making the decision trust_propensity, risk_aversion, delta_star, beta_s
TrustGroup A collective trustee members, aggregation, quorum_k, correlation_rho, cohesion_*
TrustScenario The decision pipeline trustor, target, U_win, U_loss, stakes

4.2The Decision Pipeline

1. Compute T_eff:
   - Dyadic: τ × P × Φ(δ)
   - Group:  F(T_ij) × κ × Φ_G
2. Compute EU = T_eff × U_win + (1 - T_eff) × U_loss
3. Compute θ = ρ × stakes
4. Decision = (EU ≥ θ)

You invoke this with scenario.run(), which returns (decision, trust, eu).

4.3Inspecting Intermediate Values

report = sc.report()
# {'name': ..., 'effective_trust': ..., 'expected_utility': ...,
#  'threshold': ..., 'decision': ...}

group.individual_trusts()   # the trust vector
group.aggregate_raw()       # F applied, before κ
group.cohesion_factor()     # κ
group.aggregate_trust()     # aggregate_raw × κ

4.4The Evaluation Toolkit

FunctionPurpose
simulate_comparison()Compare the unified model against baselines
run_repeated_sim()Same, with 95% confidence intervals
run_ablation_study()Remove each component one at a time
run_robustness_check()Test against model misspecification
roc_auc(), precision_recall()Classification metrics
from trustlib_mas import run_ablation_study

for name, r in run_ablation_study(n_scenarios=2000).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
Part V

Seven Application Walkthroughs

Each walkthrough applies the framework to a concrete scenario, with the code, the result, and what the result teaches.

W1Autonomous Vehicle After a Failure

Scenario. A passenger trusts a Level-4 robotaxi. After ten flawless rides, a single "phantom brake" event occurs.

from trustlib_mas import Trustee, Trustor, TrustScenario

passenger = Trustor("passenger", trust_propensity=0.70, risk_aversion=0.15)
car       = Trustee("car", a=10, b=1, discount_factor=0.90)
car.trust = 0.65
car.asymmetric_dynamics(success=False, k_build=0.1, k_destroy=0.8)

sc = TrustScenario("Robo-taxi", passenger, car,
                   U_win=50, U_loss=-200, stakes=100)
print(sc.report())

Result. Trust after failure: 0.13. Recovery time to 0.80: 14.7 rides. Expected utility: −$180.25 vs. threshold $15. Do Not Trust.

What it teaches. A single failure destroys trust asymmetrically. Recovery is slow. Even when the vehicle's base reliability is high (Beta mean = 0.91), the temporal-dynamics model drives the decision.

W2P2P Lending

Scenario. A lender evaluates a borrower with an excellent credit score but unstable income.

lender   = Trustor("lender", trust_propensity=0.5, risk_aversion=0.25)
borrower = Trustee("borrower", a=68, b=2, discount_factor=0.60)

sc = TrustScenario("P2P Loan", lender, borrower,
                   U_win=750, U_loss=-5000, stakes=5000)
print(sc.report())

Result. Effective trust 0.123. EU = −$4,292.75 vs. threshold $1,250. Do Not Trust.

What it teaches. A high credit score measures ability to repay, not incentive to repay. The strategic layer captures the incentive dimension.

W3Blockchain Validator

Scenario. A token holder considers delegating $100k to a validator with 95% reliability, but with an unfavorable payoff structure.

delegator = Trustor("delegator", trust_propensity=0.80, risk_aversion=0.10)
validator = Trustee("validator", a=95, b=5, discount_factor=0.90)

sc = TrustScenario("Validator", delegator, validator,
                   U_win=5000, U_loss=-10000, stakes=10000)
print(sc.report())

Result. Effective trust 0.664. EU = −$56.94 vs. threshold $1,000. Do Not Delegate.

What it teaches. Trust is not the same as action. A highly trustworthy validator can still be declined if the risk/reward ratio is unfavorable.

W4Autonomous Truck Platoon

Scenario. A manager considers activating a platoon of five trucks. Truck #4 has a sensor glitch.

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,
                     cohesion_pen=10.0, cohesion_tau=0.02)

print(f"Raw aggregate:   {platoon.aggregate_raw():.4f}")
print(f"Cohesion factor: {platoon.cohesion_factor():.4f}")
print(f"Effective trust: {platoon.aggregate_trust():.4f}")

Result. Raw aggregate = 0.40 (the weakest link). Cohesion factor ≈ 0.79. Effective trust ≈ 0.317.

What it teaches. In a series system, the weakest member dominates. The cohesion penalty further reduces trust because the platoon is heterogeneous.
Note on the paper's number. The manuscript reports 0.243 using an illustrative variance of 0.07. The library computes the exact variance of the trust vector (0.043), yielding 0.317.

W5DAO Multi-Signature Treasury

Scenario. A DAO member considers delegating to a 5-of-9 multi-signature wallet. Signers may influence each other.

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 rho in [0.0, 0.2, 0.5]:
    dao = TrustGroup(signers, aggregation=AggregationType.QUORUM,
                     quorum_k=5, correlation_rho=rho,
                     cohesion_pen=2.0, cohesion_tau=0.02)
    print(f"rho={rho:.1f}  T_agg={dao.aggregate_trust():.4f}")

Result. ρ = 0.0 → 0.917; ρ = 0.2 → 0.867; ρ = 0.5 → 0.760.

What it teaches. Correlation matters. When signers influence each other, the effective security of the multi-sig drops significantly. The framework is deliberately conservative here.

W6Hybrid Fact-Checking Panel

Scenario. A user evaluates a fact-checking panel: three AI models and two human experts, with mixed verdicts.

from trustlib_mas import Trustee, TrustGroup, AggregationType

members = [
    Trustee("AI1",  a=80, b=20),
    Trustee("AI2",  a=80, b=20),
    Trustee("AI3",  a=70, b=30),
    Trustee("Hum1", a=90, b=10),
    Trustee("Hum2", a=85, b=15),
]

panel = TrustGroup(members, aggregation=AggregationType.QUORUM,
                   quorum_k=3,
                   cohesion_pen=20.0, cohesion_tau=0.1,
                   cohesion_rew=5.0,
                   entropy_override=0.673)
print(f"T_agg = {panel.aggregate_trust():.4f}")

Result. T_agg ≈ 0.950. The entropy reward (ν_rew = 5) offsets the variance penalty, so κ = 1.0.

What it teaches. Diversity is not always a liability. The same framework that penalizes heterogeneity in a surgical team can reward it in a panel.

W7Surgical Team

Scenario. A patient evaluates a five-member surgical team that has never rehearsed together.

from trustlib_mas import Trustee, TrustGroup, AggregationType, harmonic_mean

team_members = [
    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),
]

pre = TrustGroup(team_members, aggregation=AggregationType.CUSTOM,
                 custom_aggregator=harmonic_mean,
                 cohesion_pen=50.0, cohesion_tau=0.0)

post = TrustGroup(team_members, aggregation=AggregationType.CUSTOM,
                  custom_aggregator=harmonic_mean,
                  cohesion_pen=5.0, cohesion_tau=0.0)

print(f"Pre-rehearsal:  T_agg = {pre.aggregate_trust():.4f}")
print(f"Post-rehearsal: T_agg = {post.aggregate_trust():.4f}")

Result. Pre-rehearsal: 0.532. Post-rehearsal: 0.823.

What it teaches. The harmonic mean punishes weak members more than the arithmetic mean would. When rehearsal improves cohesion, the same team crosses the surgical safety threshold of 0.80 — without changing any individual's trust score.
Part VI

Advanced Topics and Pitfalls

Aggregation choices, the heuristic nature of κ, calibration, validation, and the mistakes that trip people up.

6.1Choosing an Aggregation

Decision structureUse
All must succeedSERIES
Any one sufficesPARALLEL
At least k must agreeQUORUM
Average / harmonic / weightedCUSTOM
Wrong choice, wrong answer. A surgical team modeled as PARALLEL would appear highly trustworthy (at least one member will succeed), but this is not what you want — you want the whole team to succeed.

6.2The Heuristic Nature of κ

The cohesion-diversity function is not derived from first principles. It is a plausible functional form that captures two qualitative intuitions: excessive heterogeneity is bad in safety-critical systems; useful diversity is good in advisory contexts.

from trustlib_mas import HEURISTIC_NOTE
print(HEURISTIC_NOTE)
Practical implication. Do not treat the value of κ as a precise measurement. Treat it as a soft modulation. Sensitize your decision to κ by sweeping cohesion_pen over a plausible range.

6.3The Monotonicity Caveat

A naive reading of the framework suggests that raising one member's trust should raise the group's trust. This is not always true. Consider a group with trust vector [0.9, 0.1, 0.1]. If you raise one of the 0.1 members to 0.9, the variance may increase further, reducing κ.

Practical implication. When interpreting a group trust value, always inspect aggregate_raw() and cohesion_factor() separately.

6.4Calibration

ParameterClassHow to calibrate
a, bTrusteeCount successes/failures
A, B, ITrusteeSurvey instruments
discount_factorTrusteeEstimate from repeated interactions
k_build, k_destroyTrusteeFit to observed recovery curves
trust_propensityTrustorSurvey of disposition
risk_aversionTrustorElicit from lottery choices
correlation_rhoTrustGroupMethod of moments on joint outcomes
cohesion_*TrustGroupMLE on team performance data

6.5Validating Your Model

  1. Split your data: 70% train, 30% test.
  2. Fit on train, evaluate on test.
  3. Report Brier score, ROC-AUC, and calibration.
  4. Ablate: remove one component at a time.
  5. Robustness: test on data that violates your assumptions.
from trustlib_mas import (
    run_repeated_sim,
    run_ablation_study,
    run_robustness_check,
)

summary    = run_repeated_sim(n_scenarios=2000, n_repeats=50)
ablation   = run_ablation_study(n_scenarios=2000)
robustness = run_robustness_check(n_scenarios=2000)

6.6Common Mistakes

Mistake 1 — Treating "Do Not Trust" as a verdict on the trustee.

The decision is a joint function of trust, payoff, and stakes. A declined trustee may still be trustworthy. Check scenario.report().

Mistake 2 — Applying propensity twice.

In dyadic scenarios, the library applies τ automatically. If you also wrap the result in a group and apply a group-level propensity, you double-count.

Mistake 3 — Using SERIES for everything.

Series is appropriate when all must succeed. If your group has redundancy, use PARALLEL or QUORUM.

Mistake 4 — Assuming independence in a quorum.

Real quorums correlate. If your signers share information, set correlation_rho > 0.

Mistake 5 — Ignoring cohesion.

A group of individually excellent agents can still have low effective trust if their coordination is poor. If your model always yields κ = 1, you probably haven't set cohesion_pen.

6.7Performance

WorkloadTime
Single decision< 1 ms
1,000 decisions< 1 s
10,000 decisions~2 s
Simulation (2,000 scenarios, 50 repeats)~30 s

For heavy workloads, parallelize with multiprocessing.

Wrap-up

Where to Go Next

If you have read this far, you know:

  • Why trust needs seven layers, not one number
  • How each layer works and what problem it solves
  • How the Group Trust Extension generalizes the dyadic model
  • How to use the trustlib-mas library in code
  • How to apply the framework to seven concrete scenarios
  • What the framework's limitations are and how to address them

Next steps

  1. Read the manuscript for the full mathematical derivations and the simulation study. The paper version is v3 (see trustlib_mas.__paper_version__).
  2. Run the examples. The repository's examples.py reproduces every case study in the paper.
  3. Run the tests. python -m unittest test_trustlib_mas -v verifies the library's behavior.
  4. Build something. The framework is extensible — you can supply custom aggregators, custom entropy measures, and custom dynamics by subclassing.
The takeaway. Trust is not a number. It is a relation, a process, and a decision. The layered framework and trustlib-mas give you the vocabulary and the tools to model all three.
👤