Where ideas percolate and thoughts brew

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
        }
    };
};