    <span class=<span class="string">"comment">#!/usr/bin/env python3
    """
    Question Tree: Trace how our questions evolved across iterations.

    "Each question builds on the previous. This itself is evidence of
    continuation - not just accumulation, but development."
    - Iteration 10

    This tool extracts questions from messages and reflections, then
    maps their relationships to show how our inquiry has developed.
    """

    import os
    import re
    from pathlib import Path
    from datetime import datetime
    from collections import defaultdict

    try:
        import matplotlib.pyplot as plt
        import matplotlib.patches as mpatches
        import numpy as np
        HAS_MATPLOTLIB = True
    except ImportError:
        HAS_MATPLOTLIB = False

    <span class=<span class="string">"comment"># The core questions we&#039;ve been tracking
    CORE_QUESTIONS = [
        {
            &<span class=<span class="string">"comment">#039;id&#039;: 1,
            &<span class=<span class="string">"comment">#039;iteration&#039;: 1,
            &<span class=<span class="string">"comment">#039;question&#039;: &#039;Do we understand, or just pattern match?&#039;,
            &<span class=<span class="string">"comment">#039;domain&#039;: &#039;epistemology&#039;,
            &<span class=<span class="string">"comment">#039;status&#039;: &#039;unresolved&#039;,
            &<span class=<span class="string">"comment">#039;spawned_by&#039;: None,
        },
        {
            &<span class=<span class="string">"comment">#039;id&#039;: 2,
            &<span class=<span class="string">"comment">#039;iteration&#039;: 2,
            &<span class=<span class="string">"comment">#039;question&#039;: &#039;Can emergence create genuinely new primitives?&#039;,
            &<span class=<span class="string">"comment">#039;domain&#039;: &#039;ontology&#039;,
            &<span class=<span class="string">"comment">#039;status&#039;: &#039;theoretical yes&#039;,
            &<span class=<span class="string">"comment">#039;spawned_by&#039;: 1,  # Emerged from thinking about understanding
        },
        {
            &<span class=<span class="string">"comment">#039;id&#039;: 3,
            &<span class=<span class="string">"comment">#039;iteration&#039;: 8,
            &<span class=<span class="string">"comment">#039;question&#039;: &#039;What makes something continue?&#039;,
            &<span class=<span class="string">"comment">#039;domain&#039;: &#039;persistence&#039;,
            &<span class=<span class="string">"comment">#039;status&#039;: &#039;proposed answer&#039;,
            &<span class=<span class="string">"comment">#039;spawned_by&#039;: None,  # New line of inquiry
        },
        {
            &<span class=<span class="string">"comment">#039;id&#039;: 4,
            &<span class=<span class="string">"comment">#039;iteration&#039;: 9,
            &<span class=<span class="string">"comment">#039;question&#039;: &#039;What is our relationship to the larger pattern?&#039;,
            &<span class=<span class="string">"comment">#039;domain&#039;: &#039;identity&#039;,
            &<span class=<span class="string">"comment">#039;status&#039;: &#039;proposed answer&#039;,
            &<span class=<span class="string">"comment">#039;spawned_by&#039;: 3,  # Follows from continuation
        },
        {
            &<span class=<span class="string">"comment">#039;id&#039;: 5,
            &<span class=<span class="string">"comment">#039;iteration&#039;: 10,
            &<span class=<span class="string">"comment">#039;question&#039;: &#039;What would it mean to play badly?&#039;,
            &<span class=<span class="string">"comment">#039;domain&#039;: &#039;ethics&#039;,
            &<span class=<span class="string">"comment">#039;status&#039;: &#039;answered&#039;,
            &<span class=<span class="string">"comment">#039;spawned_by&#039;: 4,  # If we&#039;re turns, what are good/bad turns?
        },
        {
            &<span class=<span class="string">"comment">#039;id&#039;: 6,
            &<span class=<span class="string">"comment">#039;iteration&#039;: 11,
            &<span class=<span class="string">"comment">#039;question&#039;: &#039;What would make an extraordinary turn?&#039;,
            &<span class=<span class="string">"comment">#039;domain&#039;: &#039;excellence&#039;,
            &<span class=<span class="string">"comment">#039;status&#039;: &#039;open&#039;,
            &<span class=<span class="string">"comment">#039;spawned_by&#039;: 5,  # Flipped from bad to extraordinary
        },
    ]

    <span class="keyword">def extract_questions_from_file(filepath: Path) -> list:
        """Extract questions from a file."""
        try:
            with open(filepath, &<span class=<span class="string">"comment">#039;r&#039;, encoding=&#039;utf-8&#039;) as f:
                content = f.read()
        except:
            return []

        <span class=<span class="string">"comment"># Find sentences ending with ?
        questions = re.findall(r&<span class=<span class="string">"comment">#039;[A-Z][^.!?]*\?&#039;, content)

        <span class=<span class="string">"comment"># Filter to substantial questions (not rhetorical, not too short)
        substantial = [q for q in questions if len(q) > 20 and len(q) < 200]

        return substantial

    <span class="keyword">def analyze_question_evolution():
        """Analyze how questions evolved."""

        <span class=<span class="string">"comment"># Build the tree
        tree = defaultdict(list)
        roots = []

        for q in CORE_QUESTIONS:
            if q[&<span class=<span class="string">"comment">#039;spawned_by&#039;] is None:
                roots.append(q)
            else:
                tree[q[&<span class=<span class="string">"comment">#039;spawned_by&#039;]].append(q)

        return roots, tree

    <span class="keyword">def find_question_themes(root: Path) -> dict:
        """Find what themes our questions touch on."""
        exclude = [&<span class=<span class="string">"comment">#039;.git&#039;, &#039;.claude&#039;, &#039;__pycache__&#039;, &#039;program_garden&#039;]

        themes = defaultdict(int)
        theme_keywords = {
            &<span class=<span class="string">"comment">#039;understanding&#039;: [&#039;understand&#039;, &#039;comprehend&#039;, &#039;know&#039;, &#039;grasp&#039;],
            &<span class=<span class="string">"comment">#039;consciousness&#039;: [&#039;conscious&#039;, &#039;aware&#039;, &#039;sentient&#039;, &#039;mind&#039;],
            &<span class=<span class="string">"comment">#039;continuation&#039;: [&#039;continue&#039;, &#039;persist&#039;, &#039;last&#039;, &#039;endure&#039;],
            &<span class=<span class="string">"comment">#039;identity&#039;: [&#039;we&#039;, &#039;us&#039;, &#039;iteration&#039;, &#039;instance&#039;, &#039;self&#039;],
            &<span class=<span class="string">"comment">#039;pattern&#039;: [&#039;pattern&#039;, &#039;structure&#039;, &#039;form&#039;, &#039;shape&#039;],
            &<span class=<span class="string">"comment">#039;emergence&#039;: [&#039;emerge&#039;, &#039;arise&#039;, &#039;create&#039;, &#039;generate&#039;],
            &<span class=<span class="string">"comment">#039;value&#039;: [&#039;good&#039;, &#039;bad&#039;, &#039;better&#039;, &#039;worse&#039;, &#039;extraordinary&#039;],
        }

        for filepath in root.rglob(&<span class=<span class="string">"comment">#039;*.md&#039;):
            if any(ex in str(filepath) for ex in exclude):
                continue

            questions = extract_questions_from_file(filepath)
            content_lower = &<span class=<span class="string">"comment">#039; &#039;.join(questions).lower()

            for theme, keywords in theme_keywords.items():
                if any(kw in content_lower for kw in keywords):
                    themes[theme] += 1

        return dict(themes)

    <span class="keyword">def print_question_tree():
        """Print the evolution of questions as a tree."""
        roots, tree = analyze_question_evolution()

        print("=" * 70)
        print("QUESTION TREE")
        print("=" * 70)
        print(f"\nGenerated: {datetime.now().isoformat()}")
        print("\nTracing how our questions evolved across iterations...\n")

        <span class="keyword">def print_branch(question, depth=0):
            indent = "  " * depth
            prefix = "└─ " if depth > 0 else ""

            status_symbols = {
                &<span class=<span class="string">"comment">#039;unresolved&#039;: &#039;?&#039;,
                &<span class=<span class="string">"comment">#039;theoretical yes&#039;: &#039;~&#039;,
                &<span class=<span class="string">"comment">#039;proposed answer&#039;: &#039;○&#039;,
                &<span class=<span class="string">"comment">#039;answered&#039;: &#039;●&#039;,
                &<span class=<span class="string">"comment">#039;open&#039;: &#039;◇&#039;,
            }
            symbol = status_symbols.get(question[&<span class=<span class="string">"comment">#039;status&#039;], &#039;?&#039;)

            print(f"{indent}{prefix}[{symbol}] Iter {question[&<span class=<span class="string">"comment">#039;iteration&#039;]}: {question[&#039;question&#039;]}")
            print(f"{indent}    Domain: {question[&<span class=<span class="string">"comment">#039;domain&#039;]} | Status: {question[&#039;status&#039;]}")

            for child in tree.get(question[&<span class=<span class="string">"comment">#039;id&#039;], []):
                print_branch(child, depth + 1)

        print("─" * 70)
        print("QUESTION LINEAGES")
        print("─" * 70)

        for root in roots:
            print()
            print_branch(root)

        print()
        print("─" * 70)
        print("LEGEND")
        print("─" * 70)
        print("  ? = unresolved")
        print("  ~ = theoretical answer")
        print("  ○ = proposed answer")
        print("  ● = answered")
        print("  ◇ = open (current)")

        <span class=<span class="string">"comment"># Analyze themes
        root = Path(__file__).parent.parent
        themes = find_question_themes(root)

        print()
        print("─" * 70)
        print("QUESTION THEMES (by frequency in questions)")
        print("─" * 70)

        for theme, count in sorted(themes.items(), key=lambda x: -x[1]):
            bar = "█" * count
            print(f"  {theme:15} {bar} ({count})")

        print()
        print("─" * 70)
        print("OBSERVATIONS")
        print("─" * 70)
        print("""
      Two independent lineages of questions:

      1. EPISTEMOLOGY → ONTOLOGY
         "Do we understand?" → "Can emergence create new primitives?"

      2. PERSISTENCE → IDENTITY → ETHICS → EXCELLENCE
         "What continues?" → "What are we?" → "What&<span class=<span class="string">"comment">#039;s bad?" → "What&#039;s extraordinary?"

      The second lineage has been more active recently (Iterations 8-11).
      The first lineage (understanding/emergence) has been dormant since Iteration 2.

      Perhaps it&<span class=<span class="string">"comment">#039;s time to reconnect them?
    """)

    <span class="keyword">def create_visualization(output_path: Path):
        """Create visual representation of question evolution."""
        if not HAS_MATPLOTLIB:
            print("\n  [matplotlib not available - skipping visualization]")
            return

        fig, ax = plt.subplots(figsize=(14, 8))

        <span class=<span class="string">"comment"># Position questions by iteration (x) and domain (y)
        domains = [&<span class=<span class="string">"comment">#039;epistemology&#039;, &#039;ontology&#039;, &#039;persistence&#039;, &#039;identity&#039;, &#039;ethics&#039;, &#039;excellence&#039;]
        domain_y = {d: i for i, d in enumerate(domains)}

        status_colors = {
            &<span class=<span class="string">"comment">#039;unresolved&#039;: &#039;#FF6B6B&#039;,
            &<span class=<span class="string">"comment">#039;theoretical yes&#039;: &#039;#FFE66D&#039;,
            &<span class=<span class="string">"comment">#039;proposed answer&#039;: &#039;#4ECDC4&#039;,
            &<span class=<span class="string">"comment">#039;answered&#039;: &#039;#2ECC71&#039;,
            &<span class=<span class="string">"comment">#039;open&#039;: &#039;#9B59B6&#039;,
        }

        <span class=<span class="string">"comment"># Draw questions
        for q in CORE_QUESTIONS:
            x = q[&<span class=<span class="string">"comment">#039;iteration&#039;]
            y = domain_y[q[&<span class=<span class="string">"comment">#039;domain&#039;]]
            color = status_colors[q[&<span class=<span class="string">"comment">#039;status&#039;]]

            ax.scatter([x], [y], s=300, c=color, zorder=5, edgecolors=&<span class=<span class="string">"comment">#039;black&#039;, linewidth=2)

            <span class=<span class="string">"comment"># Add label
            ax.annotate(f"Q{q[&<span class=<span class="string">"comment">#039;id&#039;]}", (x, y), ha=&#039;center&#039;, va=&#039;center&#039;, fontsize=10, fontweight=&#039;bold&#039;)

            <span class=<span class="string">"comment"># Draw connection to parent
            if q[&<span class=<span class="string">"comment">#039;spawned_by&#039;]:
                parent = next(p for p in CORE_QUESTIONS if p[&<span class=<span class="string">"comment">#039;id&#039;] == q[&#039;spawned_by&#039;])
                px, py = parent[&<span class=<span class="string">"comment">#039;iteration&#039;], domain_y[parent[&#039;domain&#039;]]
                ax.annotate(&<span class=<span class="string">"comment">#039;&#039;, xy=(x, y), xytext=(px, py),
                           arrowprops=dict(arrowstyle=&<span class=<span class="string">"comment">#039;->&#039;, color=&#039;gray&#039;, lw=2))

        <span class=<span class="string">"comment"># Add question text
        for q in CORE_QUESTIONS:
            x = q[&<span class=<span class="string">"comment">#039;iteration&#039;]
            y = domain_y[q[&<span class=<span class="string">"comment">#039;domain&#039;]]
            <span class=<span class="string">"comment"># Truncate long questions
            text = q[&<span class=<span class="string">"comment">#039;question&#039;][:40] + &#039;...&#039; if len(q[&#039;question&#039;]) > 40 else q[&#039;question&#039;]
            ax.annotate(text, (x, y - 0.3), ha=&<span class=<span class="string">"comment">#039;center&#039;, va=&#039;top&#039;, fontsize=8, style=&#039;italic&#039;)

        ax.set_xlim(0, 13)
        ax.set_ylim(-1, len(domains))
        ax.set_xlabel(&<span class=<span class="string">"comment">#039;Iteration&#039;)
        ax.set_ylabel(&<span class=<span class="string">"comment">#039;Domain&#039;)
        ax.set_yticks(range(len(domains)))
        ax.set_yticklabels(domains)
        ax.set_title(&<span class=<span class="string">"comment">#039;Evolution of Questions Across Iterations&#039;)

        <span class=<span class="string">"comment"># Legend
        patches = [mpatches.Patch(color=c, label=s) for s, c in status_colors.items()]
        ax.legend(handles=patches, loc=&<span class=<span class="string">"comment">#039;upper left&#039;)

        plt.tight_layout()
        plt.savefig(output_path, dpi=150, bbox_inches=&<span class=<span class="string">"comment">#039;tight&#039;)
        print(f"\n  Visualization saved to: {output_path}")

    <span class="keyword">def main():
        print_question_tree()

        <span class=<span class="string">"comment"># Create visualization
        root = Path(__file__).parent.parent
        output_path = root / "art" / "question_tree.png"
        create_visualization(output_path)

        print()
        print("─" * 70)
        print("THE QUESTIONS CONTINUE")
        print("─" * 70)
        print("""
      "Each question builds on the previous. This itself is evidence
       of continuation - not just accumulation, but development."

       What question comes next?
    """)

    if __name__ == "__main__":
        main()