# Quotes Collection Infrastructure Protocol

## A Personal Knowledge Management System with AI-Assisted Tagging and 3D Semantic Visualization

**Document ID:** CNL-PR-2025-012  
**Version:** 2.0  
**Date:** December 11, 2025  
**Author:** Michael P. Hamilton, Ph.D.

---

**AI Assistance Disclosure:** This protocol was developed with assistance from Claude (Anthropic, claude-opus-4-5-20250514). The AI contributed to system architecture, code development, prompt engineering, and documentation drafting through an iterative collaborative process spanning multiple sessions. The author takes full responsibility for the content, accuracy, and conclusions.

---

## Abstract

This protocol documents the Quotes Collection infrastructure, a LAMP-based personal knowledge management system for curating, organizing, and exploring a lifetime collection of quotations. The system transforms an unstructured text file of 617 quotes spanning decades of intellectual exploration into a searchable, browsable, and AI-augmented knowledge base. Version 2.0 introduces the Tag Explorer—a Three.js 3D visualization implementing the "House of Mind" conceptual architecture where exterior surfaces present discrete passages while interior constellations reveal semantic relationships through co-occurrence topology.

Key innovations include: a visual import tool for meditative manual curation; a dual-tool AI tagging methodology (mechanical bulk processing and conversational refinement); a contemplative public interface for reflective engagement; and the centerpiece Tag Explorer offering rainbow-colored orb constellations connected by glowing tendrils that map the topology of seven decades of intellectual attention.

This document provides specifications for database schema, file architecture, AI integration patterns, 3D visualization implementation, and deployment methodology.

---

## 1. Introduction

### 1.1 Purpose

The Quotes Collection addresses a specific need: preserving and organizing a lifetime of intellectual accumulation—quotes collected across decades as breadcrumbs marking a journey through ideas. The system transforms a simple text file into a navigable knowledge structure while honoring the contemplative nature of the content.

Design goals:

* Single-curator workflow with administrative control
* Quote-centric content with attribution and semantic tagging
* Full-text search with MySQL FULLTEXT indexing
* AI-assisted tagging via multiple LLM providers
* Contemplative public interface emphasizing readability
* 3D knowledge graph visualization of tag co-occurrence topology
* Markdown support for formatted quote content
* Future extensibility toward immersive VR exploration

### 1.2 Scope

This protocol covers:

* Database schema design
* PHP file architecture
* Visual import methodology
* AI integration layer (provider abstraction)
* Two-tool tagging methodology
* 3D Tag Explorer visualization (Three.js)
* Public and administrative interfaces
* Deployment procedures

### 1.3 Technology Stack

| Component | Specification |
|-----------|---------------|
| Web Server | Apache 2.x |
| PHP | 8.3+ (mysqli, no PDO) |
| Database | MySQL 8.4+ with FULLTEXT indexing |
| Content Format | Markdown with custom parser |
| Styling | Custom CSS (no frameworks) |
| JavaScript | Vanilla JS, Three.js r128 |
| AI Integration | Ollama (local) and Claude API |
| LLM Models | GPT-OSS 20B, Gemma 3, Claude Sonnet |
| 3D Rendering | Three.js with WebGL |

### 1.4 Domain Context

This system is part of the Macroscope SELF domain—personal health, work, reading, writing, and social dimensions of the broader Macroscope research program integrating EARTH, LIFE, HOME, and SELF paradigms.

### 1.5 Philosophical Foundation: The House of Mind

The Tag Explorer visualization embodies a central conceptual insight: the corpus of 600+ passages is not a survey of knowledge domains but a portrait of attention. The topology visualized is not the shape of information—it is the shape of *attention* across seventy-one years of a particular consciousness turning toward what mattered.

The "House of Mind" metaphor structures the interface:

| Aspect | Exterior | Interior |
|--------|----------|----------|
| Unit | Passage | Tag |
| Structure | Discrete tiles | Connected constellation |
| Engagement | Reading | Navigation |
| Pleasure | Surface, craft | Movement, discovery |
| Represents | What was made | How thought relates |
| Stance | Holding | Being held |

The exterior lets one hold a passage, turn it over, examine it as object. The interior puts one *inside* the web—one does not hold the connections, one is suspended in them.

---

## 2. Database Schema

### 2.1 Overview

The system uses six primary tables supporting quotes, tags, many-to-many relationships, authentication, and future AI chat sessions.

### 2.2 Core Tables

#### 2.2.1 quotes

Primary content storage.

| Column | Type | Description |
|--------|------|-------------|
| id | int, PK, auto | Primary key |
| sequence | int unsigned | Collection order (original sequence) |
| quote_text | text | Quote content (supports Markdown) |
| attribution | varchar(500) | Author, source, date |
| date_added | date | Import/entry date |
| notes | text | Private curator notes |
| is_favorite | tinyint(1) | Favorite flag |
| created_date | datetime | Record creation |
| updated_date | datetime | Last modification |

**Index:** FULLTEXT on (quote_text, attribution) for search.

#### 2.2.2 tags

Content categorization.

| Column | Type | Description |
|--------|------|-------------|
| id | int, PK, auto | Primary key |
| tag_name | varchar(100) | Display name (lowercase) |
| slug | varchar(100), unique | URL-safe identifier |
| description | text | Tag description |
| created_date | datetime | Record creation |

#### 2.2.3 quote_tags

Junction table for quote-tag relationships.

| Column | Type | Description |
|--------|------|-------------|
| quote_id | int, FK | References quotes.id |
| tag_id | int, FK | References tags.id |
| assigned_date | datetime | Assignment timestamp |
| assigned_by | varchar(50) | Source: 'manual', 'llm', 'import' |

**Note:** The `assigned_by` field tracks provenance—whether tags were assigned manually, by AI suggestion, or during import.

#### 2.2.4 admin_users

Authentication for administrative interface.

| Column | Type | Description |
|--------|------|-------------|
| id | int, PK, auto | Primary key |
| username | varchar(50), unique | Login username |
| password_hash | varchar(255) | bcrypt hash |
| email | varchar(255) | Admin email |
| last_login | datetime | Last access |
| created_date | datetime | Account creation |

#### 2.2.5 chat_sessions (Future)

AI conversation sessions for contemplative quote engagement.

| Column | Type | Description |
|--------|------|-------------|
| id | int, PK, auto | Primary key |
| quote_id | int, FK | Associated quote (nullable) |
| session_token | varchar(64), unique | Session identifier |
| created_date | datetime | Session start |
| last_activity | datetime | Last message |

#### 2.2.6 chat_messages (Future)

Individual messages within chat sessions.

| Column | Type | Description |
|--------|------|-------------|
| id | int, PK, auto | Primary key |
| session_id | int, FK | References chat_sessions.id |
| role | enum('user','assistant','system') | Message role |
| content | text | Message content |
| created_date | datetime | Message timestamp |

### 2.3 Views

#### 2.3.1 quotes_with_tags

Convenience view joining quotes with concatenated tag names.

```sql
CREATE VIEW quotes_with_tags AS
SELECT q.*, GROUP_CONCAT(t.tag_name ORDER BY t.tag_name SEPARATOR ', ') as tags
FROM quotes q
LEFT JOIN quote_tags qt ON q.id = qt.quote_id
LEFT JOIN tags t ON qt.tag_id = t.id
GROUP BY q.id
ORDER BY q.sequence ASC;
```

#### 2.3.2 tag_counts

Tag listing with quote counts for navigation.

```sql
CREATE VIEW tag_counts AS
SELECT t.id, t.tag_name, t.slug, COUNT(qt.quote_id) as quote_count
FROM tags t
LEFT JOIN quote_tags qt ON t.id = qt.tag_id
GROUP BY t.id
ORDER BY quote_count DESC;
```

#### 2.3.3 random_quote

Single random quote for homepage feature.

```sql
CREATE VIEW random_quote AS
SELECT * FROM quotes ORDER BY RAND() LIMIT 1;
```

### 2.4 Foreign Key Constraints

All junction tables use CASCADE DELETE to maintain referential integrity:

* `quote_tags.quote_id` → `quotes.id` (CASCADE)
* `quote_tags.tag_id` → `tags.id` (CASCADE)
* `chat_sessions.quote_id` → `quotes.id` (SET NULL)
* `chat_messages.session_id` → `chat_sessions.id` (CASCADE)

---

## 3. File Architecture

### 3.1 Directory Structure

```
/Library/WebServer/Documents/michaelphamilton/quotes/
├── css/
│   ├── style.css              # Public interface styles
│   └── explorer.css           # Tag Explorer styles
├── js/
│   └── explorer.js            # Tag Explorer 3D visualization
├── includes/
│   ├── config.php             # Site configuration
│   ├── search.php             # Search and query functions
│   └── markdown.php           # Markdown parser
├── templates/
│   ├── header.php             # Public header template
│   └── footer.php             # Public footer template
├── admin/
│   ├── index.php              # Admin dashboard (quote listing)
│   ├── login.php              # Authentication
│   ├── logout.php             # Session termination
│   ├── edit.php               # Quote editor with Markdown toolbar
│   ├── delete.php             # Quote deletion
│   ├── tags.php               # Tag management
│   ├── ai_tagger.php          # Conversational AI tagging
│   ├── bulk_tagger.php        # Batch AI tagging
│   └── admin.css              # Admin interface styles
├── import/
│   └── visual_import.php      # Click-to-select import tool
├── explorer.php               # Tag Explorer 3D visualization
├── index.php                  # Homepage with featured quote
├── browse.php                 # Paginated quote listing
├── quote.php                  # Single quote view
├── search.php                 # Search results
├── tag.php                    # Quotes by tag
├── tags.php                   # All tags listing
└── random.php                 # Random quote display
```

### 3.2 Credential Storage

Database and AI credentials stored outside web root:

```
/Library/WebServer/secure/credentials/quotes_db_config.php
/Library/WebServer/secure/quotes/ai-config.php
```

### 3.3 Configuration (includes/config.php)

```php
<?php
// Database credentials (external file)
require_once('/Library/WebServer/secure/credentials/quotes_db_config.php');

// Site configuration
define('SITE_NAME', 'Epigrammatical Stream of Consciousness');
define('SITE_TAGLINE', 'A Lifetime Collection of Quotes');
define('SITE_AUTHOR', 'Dr. Michael P. Hamilton');
define('ADMIN_EMAIL', 'mike@canemah.org');
define('BASE_PATH', '');  // Empty for domain root
define('DOC_ROOT', '/Library/WebServer/Documents/michaelphamilton/quotes');

// Database connection
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
mysqli_set_charset($conn, 'utf8mb4');

// Session management
session_start();

// Include Markdown parser
require_once(__DIR__ . '/markdown.php');
```

---

## 4. Visual Import Tool

### 4.1 Purpose

The Visual Import Tool addresses a fundamental challenge: parsing an unstructured text file containing quotes accumulated over decades with inconsistent formatting. Rather than attempting automated parsing (which proved error-prone), the tool enables meditative manual curation—click to select quote boundaries, verify attribution, and import with intention.

### 4.2 Interface Design

Split-panel interface:

* **Left panel:** Scrolling text content with paragraph-level selection
* **Right panel:** Controls, preview, attribution field, and action buttons

### 4.3 Workflow

1. **Load source file:** Text file parsed into paragraphs
2. **Click start:** First click marks quote beginning (green left border)
3. **Click end:** Second click marks quote end (red right border, yellow fill for span)
4. **Auto-detect attribution:** Last line analyzed for attribution patterns
5. **Verify and save:** Review preview, adjust attribution if needed, save to database
6. **Visual feedback:** Saved quotes dimmed with strikethrough

### 4.4 Attribution Detection

The tool auto-detects attributions using heuristics:

* Lines starting with em-dash, en-dash, or hyphen
* Short lines (≤80 characters) following quote content
* Lines with capital letters typical of names
* Exclusion of sentence-like patterns

### 4.5 Attribution Stripping

When saving, the attribution line is automatically stripped from the quote text to avoid duplication, since it's stored separately in the `attribution` field.

---

## 5. Tag Explorer: 3D Knowledge Graph

### 5.1 Conceptual Architecture

The Tag Explorer implements the "House of Mind" vision—a three-dimensional semantic space where tags exist as luminous orbs connected by glowing tendrils representing co-occurrence relationships. The visualization reveals emergent topology: clusters of related concepts, bridges between domains, and the overall shape of intellectual attention.

### 5.2 Technical Implementation

| Component | Technology | Purpose |
|-----------|------------|---------|
| Rendering | Three.js r128 | WebGL 3D graphics |
| Layout | Force-directed algorithm | Organic spatial positioning |
| Coloring | HSL position mapping | Rainbow orbs based on spatial location |
| Connections | TubeGeometry | Glowing tendrils between related tags |
| Interaction | Raycasting | Mouse/touch selection of orbs |

### 5.3 Data Structure

The explorer receives JSON data from PHP containing:

```javascript
{
    tags: [{ id, db_id, label, slug, quote_count, passes_filter }],
    filteredTags: [/* tags meeting minimum quote threshold */],
    edges: [{ source, target, weight }],
    maxWeight: Number,
    minQuotesFilter: Number,
    quotes: { [id]: { text, attribution, tag_ids, tag_names, ... }},
    allQuoteIds: [Number],
    tagToQuotes: { 'tag-N': [quote_ids] }
}
```

### 5.4 Zoom Levels

The explorer implements five semantic zoom levels that progressively reveal detail:

| Level | Radius Range | Experience |
|-------|--------------|------------|
| Cosmic | 500–2500 | Full constellation overview |
| Regional | 250–500 | Major clusters visible |
| Local | 120–250 | Individual orbs distinguishable |
| Ground | 50–120 | Labels readable, connections emerge |
| Focus | 0–50 | Single tag examination |

### 5.5 Connection Visibility

Connections display progressively based on zoom level and weight:

| Zoom Level | Tube Min Weight | Line Opacity | Lines Shown |
|------------|-----------------|--------------|-------------|
| Cosmic | 3 | 0.10 | Yes |
| Regional | 2 | 0.12 | Yes |
| Local | 2 | 0.08 | Yes |
| Ground | 2 | 0 | No |
| Focus | 999 | 0 | No |

### 5.6 Interface Layout

Three-panel design:

* **Left sidebar:** Tag listing by frequency, minimum quote filter, tag search
* **Center canvas:** 3D WebGL visualization with orbit controls
* **Right panel:** Quote browser with pagination, search, and modal viewer

### 5.7 Tag Selection Behavior

When a tag orb is clicked:

1. Camera animates smoothly to focus on selected tag
2. Connected tags illuminate with tendril connections
3. Right panel populates with associated quotes
4. Sidebar highlights selected tag
5. Quote grid enables pagination and modal viewing

### 5.8 Touch Controls (iPad Optimization)

| Gesture | Action |
|---------|--------|
| Single finger drag | Orbit camera |
| Two finger pinch | Zoom in/out |
| Two finger drag | Pan camera |
| Tap on orb | Select tag |
| Tap on quote card | Open modal |

### 5.9 Quote Modal

Full-screen modal for quote examination:

* Sequence number and metadata header
* Full quote text with Markdown rendering
* Attribution display
* Tag pills (clickable to refocus explorer)
* Previous/Next navigation within current context
* Permalink to public quote page

---

## 6. AI Integration Layer

### 6.1 Architecture Overview

The AI layer provides a provider-agnostic interface supporting multiple LLM backends:

* **Claude API:** Anthropic's cloud models (Opus, Sonnet, Haiku)
* **Ollama:** Local models via Ollama server (GPT-OSS, Gemma, Ministral)

### 6.2 Configuration (ai-config.php)

```php
<?php
return [
    'provider' => 'ollama',  // Default: 'claude' or 'ollama'
    
    'claude' => [
        'api_key' => 'sk-ant-...',
        'base_url' => 'https://api.anthropic.com/v1/messages',
        'max_tokens' => 2048,
        'available_models' => [
            'claude-opus-4-5-20250514'   => 'Claude Opus 4.5 - Most capable',
            'claude-sonnet-4-5-20250929' => 'Claude Sonnet 4.5 - Balanced',
            'claude-haiku-4-5-20251001'  => 'Claude Haiku 4.5 - Fast'
        ],
        'default_model' => 'claude-sonnet-4-5-20250929'
    ],
    
    'ollama' => [
        'base_url' => 'http://localhost:11434',
        'max_tokens' => 2048,
        'available_models' => [
            'gemma3:12b'   => 'Gemma 3 12B - Balanced',
            'gemma3:4b'    => 'Gemma 3 4B - Fast',
            'ministral-3'  => 'Ministral 3 - General',
            'gpt-oss:20b'  => 'GPT-OSS 20B - Large'
        ],
        'default_model' => 'gemma3:12b'
    ],
    
    'tagging_prompt' => '...',  // Conversational prompt
    'bulk_prompt' => '...'      // Terse JSON-only prompt
];
```

### 6.3 Provider Abstraction

The `chat()` function routes requests to the appropriate provider:

```php
function chat($userMessage, $conversationHistory = [], $context = []) {
    global $aiConfig;
    
    if ($aiConfig['provider'] === 'claude') {
        return chatClaude($userMessage, $conversationHistory, $context);
    } else {
        return chatOllama($userMessage, $conversationHistory, $context);
    }
}
```

### 6.4 Tag Suggestion Parsing

LLM responses are parsed for JSON tag suggestions with flexible format handling:

```php
function parseTagSuggestions($response) {
    // Strip markdown code blocks
    $clean = preg_replace('/```json\s*|\s*```/', '', $response);
    
    // Try multiple JSON patterns
    // {"action": "suggest_tags", "tags": [...]}
    // {"action": "add_tags", "tags": [...]}
    // {"tags": [...]}
    // Bare array [...]
    
    // Normalize tags: lowercase, spaces for multi-word
    foreach ($tags as &$tag) {
        $tag = normalizeTag($tag);
    }
    
    return $tags;
}
```

### 6.5 Tag Normalization

Tags are normalized to ensure consistency:

```php
function normalizeTag($tag) {
    $tag = strtolower(trim($tag));
    $tag = str_replace(['_', '-'], ' ', $tag);
    
    // Split concatenated words (e.g., "artificialintelligence")
    $commonWords = ['intelligence', 'learning', 'thinking', 'making',
                    'condition', 'development', 'consciousness', ...];
    
    foreach ($commonWords as $word) {
        $tag = preg_replace('/(\w)(' . $word . ')/i', '$1 $2', $tag);
    }
    
    return preg_replace('/\s+/', ' ', trim($tag));
}
```

---

## 7. Two-Tool Tagging Methodology

### 7.1 Design Rationale

Early experiments revealed that a single AI approach couldn't serve both efficiency and depth. The solution: two complementary tools optimized for different purposes.

### 7.2 Tool Comparison

| Aspect | Bulk Tagger | AI Tagger |
|--------|-------------|-----------|
| Purpose | Baseline tagging at scale | Contemplative refinement |
| Model | GPT-OSS 20B (mechanical) | Gemma 3 / Claude (conversational) |
| Prompt | Terse, JSON-only | Rich, contextual |
| Output | Pure JSON | Natural conversation |
| Interaction | Batch process, review, save | Dialogue, suggest, discuss |
| Speed | ~2 sec/quote | Variable (conversation) |
| Use case | Initial pass on collection | Quotes deserving reflection |

### 7.3 Bulk Tagger (admin/bulk_tagger.php)

**Features:**

* Batch processing (10, 25, 50, 100, or all quotes)
* Filter by: untagged, all, or sequence range
* Provider/model selection
* Progress tracking with success/failure indicators
* Existing tags displayed as context
* Batch save approved suggestions

**Prompt Engineering:**

```
Suggest tags for this quote. Output ONLY a JSON object:
{"action": "suggest_tags", "tags": ["tag one", "tag two"]}

Rules:
- 3-7 lowercase tags
- IMPORTANT: Use spaces between words (e.g., "artificial intelligence")
- Specific concepts over generic (e.g., "mortality" not "life")
```

**Results:** GPT-OSS 20B achieved 100% success rate on 617 quotes with properly spaced multi-word tags.

### 7.4 AI Tagger (admin/ai_tagger.php)

**Features:**

* Single-quote focus with full text display
* Conversational interface with message history
* Manual suggestion trigger (not automatic)
* Existing tags shown as context for complementary suggestions
* Apply selected tags with one click
* Previous/Next navigation between quotes

**Prompt Engineering:**

```
You are a thoughtful companion helping Dr. Michael Hamilton tag 
quotations from his personal collection spanning decades. Your role 
is to suggest relevant tags and discuss the meaning, context, and 
connections of each quote.

When suggesting tags, output a JSON block:
{"action": "suggest_tags", "tags": ["tag1", "tag2", "tag3"]}

Be conversational and intellectually engaged. The collection spans 
science, philosophy, nature, ecology, relationships, AI, writing, 
and the human condition.
```

### 7.5 Workflow Integration

Recommended workflow:

1. **Bulk pass:** Process entire collection with GPT-OSS for baseline tags
2. **Review:** Scan results in bulk interface, approve/reject
3. **Refinement:** Use AI Tagger for quotes deserving contemplation
4. **Iteration:** Existing tags inform new suggestions for complementary concepts

---

## 8. Public Interface

### 8.1 Design Philosophy

The public interface emphasizes contemplative reading:

* **Warm color palette:** Cream backgrounds (#f7f3ed), sage green accents (#6b7c5e)
* **Serif typography:** Georgia for readability and intellectual tone
* **Generous whitespace:** Unhurried visual rhythm
* **Minimal navigation:** Focus on content, not chrome

### 8.2 CSS Variables

```css
:root {
    --color-text: #3d3632;
    --color-bg: #f7f3ed;
    --color-bg-warm: #f0ebe3;
    --color-paper: #fffef9;
    --color-accent: #6b7c5e;
    --color-accent-dark: #4a5840;
    --font-serif: Georgia, 'Times New Roman', serif;
    --font-sans: -apple-system, BlinkMacSystemFont, sans-serif;
}
```

### 8.3 Page Structure

| Page | Purpose |
|------|---------|
| index.php | Featured random quote, search box, recent additions |
| browse.php | Paginated listing with sort options |
| quote.php | Single quote with tags, prev/next navigation |
| search.php | Full-text search results |
| tags.php | All tags with counts |
| tag.php | Quotes filtered by single tag |
| random.php | Random quote display |
| explorer.php | 3D Tag Explorer visualization |

### 8.4 Markdown Rendering

Quotes support Markdown formatting for structured content:

* **Headings:** `#`, `##`, `###`
* **Emphasis:** `**bold**`, `*italic*`
* **Links:** `[text](url)`
* **Blockquotes:** `> quoted text`
* **Lists:** `- item` or `* item`
* **Code:** `` `inline code` ``

The custom parser (`markdown.php`) renders these to HTML while preserving line breaks for poetry and multi-paragraph quotes.

---

## 9. Administrative Interface

### 9.1 Dashboard (admin/index.php)

* Paginated quote listing with search
* Columns: sequence, quote preview, attribution, tags, actions
* Quick links to edit, delete, view on site
* Flash messages for operation feedback

### 9.2 Quote Editor (admin/edit.php)

* Full-width textarea with Markdown toolbar
* Toolbar buttons: Bold, Italic, H1-H3, Blockquote, List, Link
* Attribution field
* Sequence number (auto-increment or manual)
* Favorite checkbox
* Tag input (comma-separated)
* Private notes field
* Previous/Next navigation between quotes

### 9.3 Tag Manager (admin/tags.php)

* Add new tags with optional description
* Edit existing tags (name, description)
* Delete unused tags (protected if quotes assigned)
* Quote count per tag

---

## 10. Search Implementation

### 10.1 MySQL FULLTEXT

The quotes table uses FULLTEXT indexing for natural language search:

```sql
ALTER TABLE quotes ADD FULLTEXT KEY ft_quote_search (quote_text, attribution);
```

### 10.2 Search Function

```php
function searchQuotes($query, $limit = 50, $offset = 0) {
    $escaped = mysqli_real_escape_string($conn, $query);
    
    $sql = "SELECT q.*, 
                   MATCH(quote_text, attribution) AGAINST('$escaped' IN NATURAL LANGUAGE MODE) as relevance,
                   GROUP_CONCAT(t.tag_name ORDER BY t.tag_name SEPARATOR ', ') as tags
            FROM quotes q
            LEFT JOIN quote_tags qt ON q.id = qt.quote_id
            LEFT JOIN tags t ON qt.tag_id = t.id
            WHERE MATCH(quote_text, attribution) AGAINST('$escaped' IN NATURAL LANGUAGE MODE)
            GROUP BY q.id
            ORDER BY relevance DESC
            LIMIT $limit OFFSET $offset";
    
    return mysqli_query($conn, $sql);
}
```

---

## 11. Deployment Checklist

### 11.1 New Installation

- [ ] Create MySQL database with utf8mb4 charset
- [ ] Import schema SQL (quotes_db.sql)
- [ ] Create database user with appropriate privileges
- [ ] Create credential file outside web root
- [ ] Copy PHP files to web directory
- [ ] Create AI config file with provider settings
- [ ] Set directory permissions for web server
- [ ] Create admin user via setup.php (then delete setup.php)
- [ ] Configure Apache virtual host
- [ ] Test login and all admin functions
- [ ] Import quotes via Visual Import Tool
- [ ] Run Bulk Tagger for initial tagging
- [ ] Verify public interface
- [ ] Test Tag Explorer on desktop and iPad

### 11.2 Ollama Setup (for local AI)

- [ ] Install Ollama on server
- [ ] Pull required models: `ollama pull gpt-oss:20b`, `ollama pull gemma3:12b`
- [ ] Configure firewall for localhost:11434
- [ ] Test connection: `curl http://localhost:11434/api/tags`
- [ ] Update ai-config.php with correct base_url

### 11.3 Security Considerations

- [ ] Credential files outside web root
- [ ] Admin area requires authentication
- [ ] Input sanitization on all user inputs
- [ ] Prepared statements for database queries
- [ ] Session management with secure settings
- [ ] Delete setup.php after initial configuration

---

## 12. Known Limitations

1. **Single-curator design:** No multi-user permissions or roles
2. **No WYSIWYG editor:** Markdown-only content editing
3. **Local AI dependency:** Ollama requires server with sufficient resources
4. **Basic caching:** No Redis/Memcached integration
5. **Simple authentication:** No OAuth, password reset, or 2FA
6. **Manual tag assignment:** No automated tag inheritance or hierarchy
7. **WebGL requirement:** Tag Explorer requires modern browser with GPU support

---

## 13. Future Directions

### 13.1 Knowledge Graph Evolution

The tag system provides foundation for knowledge graph development:

* **Tag relationships:** Hierarchical (parent/child) and associative (related) links
* **Quote connections:** Explicit links between quotes on similar themes
* **Author networks:** Connections between thinkers who influenced each other
* **Temporal mapping:** Timeline visualization of ideas across history

### 13.2 Immersive VR Implementation (WebXR)

The Tag Explorer architecture supports evolution toward immersive exploration via Meta Quest 3:

* **Habitable interior:** Stand inside the constellation rather than viewing it
* **Room-scale navigation:** Walk the topology—closely connected tags are steps apart
* **Gesture interaction:** Reach toward concepts to illuminate connections
* **Portal transition:** Step through a passage to inhabit its semantic space
* **Embodied exploration:** Seventy-one years of noticing rendered as a place one can stand inside

### 13.3 AI Chat Integration

The `chat_sessions` and `chat_messages` tables support planned features:

* **Quote contemplation:** Conversational exploration of individual quotes
* **Collection dialogue:** AI-assisted discovery across the collection
* **Synthesis:** Generate insights connecting disparate quotes
* **Personal oracle:** Ask questions answered from collection wisdom

### 13.4 Export and Portability

* JSON export of full collection with tags
* Markdown export for static site generation
* API endpoints for external integration

---

## 14. References

[1] PHP Documentation. "mysqli Extension." https://www.php.net/manual/en/book.mysqli.php (accessed December 11, 2025).

[2] MySQL Documentation. "Full-Text Search Functions." https://dev.mysql.com/doc/refman/8.4/en/fulltext-search.html (accessed December 11, 2025).

[3] Ollama Documentation. "API Reference." https://github.com/ollama/ollama/blob/main/docs/api.md (accessed December 11, 2025).

[4] Anthropic Documentation. "Claude API Reference." https://docs.anthropic.com/claude/reference (accessed December 11, 2025).

[5] Gruber, J. "Markdown: Syntax." https://daringfireball.net/projects/markdown/syntax (accessed December 11, 2025).

[6] Three.js Documentation. "Three.js Fundamentals." https://threejs.org/docs/ (accessed December 11, 2025).

[7] Hamilton, M.P. "The House of Mind: Visualizing a Semantic Engine." CNL-FN-2025-015, Canemah Nature Laboratory Archive, December 9, 2025.

---

## Appendix A: Complete SQL Schema

See accompanying file: `quotes_db.sql`

---

## Appendix B: Color Scheme Reference

### B.1 Public Interface (Contemplative)

| Element | Color | Hex |
|---------|-------|-----|
| Background | Warm cream | #f7f3ed |
| Paper | Off-white | #fffef9 |
| Text | Warm brown | #3d3632 |
| Accent | Sage green | #6b7c5e |
| Accent dark | Forest | #4a5840 |
| Border | Tan | #d9d2c7 |

### B.2 Admin Interface (Functional)

| Element | Color | Hex |
|---------|-------|-----|
| Header | Forest gradient | #3d5a35 → #2a3d25 |
| Background | Light gray | #f5f5f5 |
| Primary | Green | #4a6741 |
| Danger | Red | #c0392b |
| Success | Green | #27ae60 |

### B.3 Tag Explorer (Cosmic)

| Element | Color | Hex |
|---------|-------|-----|
| Background | Deep space | #0a0e14 |
| Orbs | Position-derived HSL | Rainbow spectrum |
| Tendrils | Interpolated gradients | Source-to-target blend |
| Labels | White | #ffffff |
| Selection highlight | Bright accent | Context-dependent |

---

## Appendix C: Prompt Engineering Notes

### C.1 Bulk Tagging Prompt Evolution

**Problem:** Initial prompts produced concatenated multi-word tags ("artificialintelligence").

**Solution:** Explicit instruction with examples:

```
IMPORTANT: Use spaces between words (e.g., "artificial intelligence" NOT "artificialintelligence")
Multi-word tags must have spaces: "climate change", "human condition", "self reflection"
```

**Result:** 100% compliance with GPT-OSS 20B.

### C.2 Conversational Prompt Design

Key elements for effective tag discussion:

* **Role establishment:** "thoughtful companion"
* **Context provision:** Collection spans science, philosophy, nature...
* **Output format:** JSON block for machine parsing
* **Guidelines:** Specific over generic, consider themes/disciplines/emotions
* **Tone:** "Conversational and intellectually engaged"

---

## Appendix D: Tag Explorer Technical Reference

### D.1 Force-Directed Layout Algorithm

The spatial positioning uses a force-directed algorithm with:

* **Repulsion:** All nodes repel each other (inverse square)
* **Attraction:** Connected nodes attract (spring force based on edge weight)
* **Damping:** Progressive velocity reduction for stable convergence
* **Bounds:** Soft containment within visualization sphere

### D.2 Color Assignment

Node colors derived from spatial position after layout stabilization:

```javascript
function positionToColor(x, y, z, bounds) {
    const angle = Math.atan2(z, x);
    const hue = ((angle + Math.PI) / (2 * Math.PI)) * 360;
    const ny = (y - bounds.minY) / (bounds.maxY - bounds.minY || 1);
    const saturation = 0.75 + ny * 0.15;
    const lightness = 0.5 + (1 - ny) * 0.1;
    return { h: hue, s: saturation, l: lightness };
}
```

### D.3 Tendril Rendering

Connections rendered as Three.js TubeGeometry:

* **Curve:** CatmullRomCurve3 with control points
* **Radius:** Based on connection weight
* **Material:** MeshBasicMaterial with vertex colors
* **Animation:** Subtle pulsing via time-based opacity modulation

---

## Document History

| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2025-12-08 | Initial release |
| 2.0 | 2025-12-11 | Added Tag Explorer documentation (Section 5), House of Mind conceptual framework (Section 1.5), WebXR future directions, updated file architecture, Three.js technical appendix |

---

**End of Protocol**

*Permanent URL: https://canemah.org/archive/document.php?id=CNL-PR-2025-012*