The Credibility Trap
About This Sketch
An animated visualization exploring how credibility can paradoxically trap people in incorrect positions. Nodes with low credibility (small circles) move freely toward truth, while highly credible nodes (large circles with locks) remain trapped by their investment in their original position. Watch as expertise becomes an anchor rather than a compass, making it harder to update beliefs when new evidence emerges.
Algorithm
This sketch visualizes how credibility can trap people in their positions and prevent them from updating toward truth.
The visualization shows nodes (representing people/beliefs) with varying levels of credibility (indicated by size). All nodes start on the left side (wrong position) and truth is represented by a target on the right.
Key mechanics:
- Small nodes (low credibility) can move freely toward truth
- Large nodes (high credibility) are locked in place by their investment in their position
- Lines connect nodes to their starting positions, showing the strength of their commitment
- Lock symbols appear on trapped high-credibility nodes
The sketch demonstrates the counterintuitive reality that expertise and credibility can actually make it harder to reach truth, because the social cost of changing positions increases with credibility.
This accompanies the blog post "The Credibility Trap" which explores how building credibility through consistency creates incentives against updating beliefs when new evidence emerges.
Pseudocode
SETUP:
Initialize canvas (400x300)
Create truth target at center-right position
Generate 9 nodes with varying credibility levels:
- 3 low credibility (0-0.3): free to move
- 3 medium credibility (0.3-0.7): some mobility
- 3 high credibility (0.7-1.0): trapped
EACH FRAME:
Get current theme colors
Clear background
Draw truth target (concentric circles)
For each node:
Calculate mobility = 1 - credibility
If mobile and not at truth:
Move toward truth at speed proportional to mobility
Draw line from starting position (shows investment)
Display node:
- Size based on credibility
- Color based on state (free/transitioning/trapped/reached)
- Lock icon if high credibility and not at truth
Display legend, insights, and progress counter
RESULT:
Low credibility nodes reach truth quickly
High credibility nodes remain trapped at wrong position
Demonstrates: Credibility prevents updating toward truth
Source Code
let sketch = function(p) {
// Visualization: The Credibility Trap
// A network of nodes representing beliefs/positions
// As credibility (node size) increases, the node becomes more rigid
// Unable to move toward truth (represented by a target)
// Small nodes (no credibility) move freely toward truth
// Large nodes (high credibility) are locked in place
let nodes = [];
let truth;
let frame = 0;
class Node {
constructor(x, y, credibility) {
this.x = x;
this.y = y;
this.startX = x;
this.startY = y;
this.credibility = credibility; // 0 to 1
this.size = p.map(credibility, 0, 1, 6, 24);
this.targetX = x;
this.targetY = y;
this.stuck = false;
}
moveTowardTruth(truth) {
// The more credibility, the less able to move
let mobility = 1 - this.credibility;
let speed = mobility * 0.5;
if (speed > 0.01) {
let dx = truth.x - this.x;
let dy = truth.y - this.y;
let dist = p.sqrt(dx * dx + dy * dy);
if (dist > 5) {
let angle = p.atan2(dy, dx);
this.x += p.cos(angle) * speed;
this.y += p.sin(angle) * speed;
} else {
this.stuck = true;
}
}
}
display(colors) {
// Draw connections to starting position (representing investment in position)
if (this.credibility > 0.3) {
p.stroke(...colors.accent2, this.credibility * 100);
p.strokeWeight(this.credibility * 2);
p.line(this.startX, this.startY, this.x, this.y);
}
// Node
p.noStroke();
// High credibility nodes are more opaque and solid
let alpha = p.map(this.credibility, 0, 1, 120, 220);
if (this.stuck) {
// Reached truth - glow effect
p.fill(...colors.accent1, alpha);
} else if (this.credibility > 0.7) {
// Trapped - darker, rigid
p.fill(...colors.accent2, alpha);
} else if (this.credibility > 0.3) {
// Medium credibility - transitioning
let mixRatio = p.map(this.credibility, 0.3, 0.7, 0, 1);
let r = p.lerp(colors.accent1[0], colors.accent2[0], mixRatio);
let g = p.lerp(colors.accent1[1], colors.accent2[1], mixRatio);
let b = p.lerp(colors.accent1[2], colors.accent2[2], mixRatio);
p.fill(r, g, b, alpha);
} else {
// Low credibility - free to move
p.fill(...colors.accent1, alpha);
}
p.circle(this.x, this.y, this.size);
// Draw "lock" symbol on highly credible trapped nodes
if (this.credibility > 0.7 && !this.stuck) {
p.fill(...colors.accent3, 180);
p.textAlign(p.CENTER, p.CENTER);
p.textSize(this.size * 0.5);
p.text('🔒', this.x, this.y);
}
}
distanceToTruth(truth) {
let dx = truth.x - this.x;
let dy = truth.y - this.y;
return p.sqrt(dx * dx + dy * dy);
}
}
p.setup = function() {
p.createCanvas(400, 300);
// Truth location (center-right)
truth = { x: 300, y: 150 };
// Create nodes with varying credibility levels
// Start all on the left side (wrong position)
// Low credibility nodes (can move freely)
for (let i = 0; i < 3; i++) {
nodes.push(new Node(
p.random(50, 100),
p.random(80, 220),
p.random(0, 0.3) // Low credibility
));
}
// Medium credibility nodes (some mobility)
for (let i = 0; i < 3; i++) {
nodes.push(new Node(
p.random(50, 100),
p.random(80, 220),
p.random(0.3, 0.7) // Medium credibility
));
}
// High credibility nodes (trapped)
for (let i = 0; i < 3; i++) {
nodes.push(new Node(
p.random(50, 100),
p.random(80, 220),
p.random(0.7, 1.0) // High credibility
));
}
};
p.draw = function() {
const colors = getThemeColors();
p.background(...colors.bg);
frame++;
// Title
p.fill(...colors.accent3, 200);
p.noStroke();
p.textAlign(p.CENTER);
p.textSize(12);
p.text('The Credibility Trap', 200, 25);
// Draw truth target
p.noFill();
p.stroke(...colors.accent1, 150);
p.strokeWeight(2);
p.circle(truth.x, truth.y, 30);
p.circle(truth.x, truth.y, 40);
p.noStroke();
p.fill(...colors.accent1, 200);
p.circle(truth.x, truth.y, 10);
p.textSize(8);
p.fill(...colors.accent3, 180);
p.textAlign(p.CENTER);
p.text('TRUTH', truth.x, truth.y + 30);
// Update and display nodes
for (let node of nodes) {
if (!node.stuck) {
node.moveTowardTruth(truth);
}
node.display(colors);
}
// Legend
p.textAlign(p.LEFT);
p.textSize(8);
p.fill(...colors.accent3, 180);
p.text('Small = Low credibility (free to update)', 20, 45);
p.text('Large = High credibility (trapped)', 20, 57);
// Bottom text - rotates through insights
p.textAlign(p.CENTER);
p.textSize(7);
p.fill(...colors.accent3, 180);
if (frame < 180) {
p.text('Low credibility nodes move freely toward truth.', 200, 275);
p.text('High credibility nodes are locked to their position.', 200, 285);
} else if (frame < 360) {
p.text('The more credible you are, the harder it becomes to update.', 200, 275);
p.text('Credibility is an anchor, not a compass.', 200, 285);
} else if (frame < 540) {
p.text('Build credibility around method, not positions.', 200, 275);
p.text('Then changing your mind demonstrates the method working.', 200, 285);
} else {
frame = 0; // Reset cycle
}
// Progress indicator
let reached = nodes.filter(n => n.stuck).length;
let total = nodes.length;
p.textSize(8);
p.fill(...colors.accent1, 180);
p.textAlign(p.RIGHT);
p.text(`Reached truth: ${reached}/${total}`, 380, 280);
// Observation: which nodes reach truth
if (frame === 300) {
let lowCred = nodes.filter(n => n.credibility < 0.3 && n.stuck).length;
let highCred = nodes.filter(n => n.credibility > 0.7 && n.stuck).length;
// This would show in console: low credibility nodes reach truth, high ones don't
}
};
};