# Design Philosophy

The principles and values guiding KOGRAL design and implementation.

## Core Tenets

### 1. Config-Driven, Not Hardcoded

**Principle**: All behavior should be configurable via schemas, not baked into code.

**Why**: Flexibility without code changes. Users adapt KOGRAL to their workflows, not vice versa.

**Example**:

```rust
// ❌ Bad: Hardcoded
impl EmbeddingProvider {
    fn new() -> Self {
        FastEmbedProvider::new("BAAI/bge-small-en-v1.5") // Can't change
    }
}

// ✅ Good: Config-driven
impl EmbeddingProvider {
    fn from_config(config: &EmbeddingConfig) -> Result<Box<dyn EmbeddingProvider>> {
        match config.provider {
            'fastembed => Ok(Box::new(FastEmbedProvider::new(&config.model)?)),
            'openai => Ok(Box::new(OpenAIProvider::new(&config.model)?)),
        }
    }
}
```

**Benefits**:
- Switch embedding providers without recompilation
- Different configs for dev/prod
- User choice, not developer mandate

### 2. Type-Safe Configuration

**Principle**: Validate configuration before runtime, not during.

**Why**: Catch errors early, reduce runtime failures.

**Implementation**: Nickel contracts + serde validation = double validation

```nickel
# Schema defines valid values
EmbeddingProvider = [| 'openai, 'claude, 'fastembed |]

# Typo caught at export time, not runtime
{ provider = 'opena1 }  # Error: Invalid variant
```

**Benefits**:
- Errors found during `nickel export`, not during execution
- Self-documenting: schema is the spec
- Refactoring safe: change schema, find all usages

### 3. Local-First, Cloud-Optional

**Principle**: Core functionality works offline, cloud is enhancement.

**Why**: Privacy, cost control, offline development.

**Examples**:

| Feature | Local | Cloud |
| --------- | ------- | ------- |
| Storage | Filesystem | SurrealDB |
| Embeddings | fastembed | OpenAI/Claude |
| Search | Text-based | Semantic |

**Benefits**:
- Works on planes, trains, areas with poor internet
- No API costs for small projects
- Privacy-sensitive projects keep data local
- Production can use cloud for scale

### 4. Git-Friendly by Default

**Principle**: Knowledge should version alongside code.

**Why**: Knowledge describes code, should evolve with it.

**Implementation**:
- Markdown + YAML frontmatter (text-based, diffable)
- One file per node (granular commits)
- Wikilinks preserved (works in Logseq, Obsidian)

**Benefits**:

```bash
# Review knowledge changes in PRs
git diff .kogral/decisions/

# Knowledge follows branches
git checkout feature-x
# .kogral/ reflects feature-x decisions

# Knowledge merges
git merge feature-x
# Merge conflicts = knowledge conflicts (resolve intentionally)
```

### 5. AI-Native, Human-Readable

**Principle**: Optimized for AI consumption, readable by humans.

**Why**: Best of both worlds - AI-assisted discovery, human verification.

**Implementation**:
- **Structured**: YAML frontmatter for AI parsing
- **Semantic**: Embeddings for AI queries
- **Readable**: Markdown for human consumption
- **Linked**: Typed relationships for AI traversal

**Example**:

```markdown
---
id: note-auth
type: note
title: Authentication Implementation
tags: [security, auth]
relates_to: [guideline-security, pattern-jwt]
---

# Authentication Implementation

Humans read this markdown normally.

AI can:
- Parse frontmatter for metadata
- Extract tags for filtering
- Follow relates_to links
- Generate embeddings for semantic search
```

### 6. Composition Over Inheritance

**Principle**: Build systems by composing small, focused components.

**Why**: Flexibility, testability, maintainability.

**Implementation**:

```rust
// Small, focused traits
trait Storage { ... }
trait EmbeddingProvider { ... }
trait TemplateEngine { ... }

// Compose into systems
struct KnowledgeBase {
    storage: Box<dyn Storage>,
    embeddings: Option<Box<dyn EmbeddingProvider>>,
    templates: TemplateEngine,
}
```

**Benefits**:
- Swap storage without affecting embeddings
- Disable embeddings without breaking storage
- Test components in isolation
- Add new providers by implementing trait

### 7. Fail Fast, Fail Clearly

**Principle**: Detect errors early, provide clear messages.

**Why**: Developer experience - fast feedback, actionable errors.

**Implementation**:

```rust
// ❌ Bad: Silent failure
fn load_config(path: &Path) -> Option<Config> {
    std::fs::read_to_string(path)
        .ok()
        .and_then(|s| serde_json::from_str(&s).ok())
}

// ✅ Good: Explicit errors
fn load_config(path: &Path) -> Result<Config, ConfigError> {
    let content = std::fs::read_to_string(path)
        .map_err(|e| ConfigError::ReadFailed(path.to_path_buf(), e))?;

    serde_json::from_str(&content)
        .map_err(|e| ConfigError::ParseFailed(path.to_path_buf(), e))
}
```

**Error messages**:

```text
❌ "Failed to load config"
✅ "Failed to read config file '/path/to/config.ncl': Permission denied"
```

### 8. Convention Over Configuration (With Escape Hatches)

**Principle**: Sane defaults, but everything customizable.

**Why**: Easy to start, flexible as you grow.

**Examples**:

```nickel
# Minimal config (uses conventions)
{ graph = { name = "my-project" } }
# Defaults: filesystem storage, no embeddings, standard templates

# Full config (explicit everything)
{
  graph = { name = "my-project" },
  storage = { primary = 'surrealdb, /* ... */ },
  embeddings = { provider = 'openai, /* ... */ },
  templates = { templates_dir = "custom" },
}
```

**Conventions**:
- `.kogral/` directory in project root
- Filesystem storage by default
- YAML frontmatter + markdown body
- Standard template names (note.md.tera, decision.md.tera)

**Escape hatches**:
- `--kogral-dir` to use different location
- Configure alternative storage backends
- Custom frontmatter schemas
- Override any template

### 9. Documentation as Code

**Principle**: Documentation lives with code, versioned together.

**Why**: Outdated docs are worse than no docs.

**Implementation**:
- ADRs in `.kogral/decisions/` (alongside code)
- Guidelines in `.kogral/guidelines/` (versioned with code)
- Patterns in `.kogral/patterns/` (evolve with implementations)

**Benefits**:

```bash
# Code and docs branch together
git checkout old-version
# .kogral/ reflects that version's decisions

# Code and docs merge together
git merge feature
# Merge includes new patterns, updated guidelines

# Code and docs reviewed together
# PR shows code + decision + guideline updates
```

### 10. Optimize for Discoverability

**Principle**: Knowledge is useless if you can't find it.

**Why**: The point is to **use** knowledge, not just store it.

**Features**:
- **Text search**: Find exact keywords
- **Semantic search**: Find related concepts
- **Graph traversal**: Follow relationships
- **Tag filtering**: Narrow by category
- **MCP integration**: AI-assisted discovery

**Example**:

User doesn't remember exact term, but knows the concept:

```text
"Find anything about handling errors gracefully"
```

KOGRAL finds (semantically):
- "Error Handling with thiserror" (pattern)
- "Result Type Best Practices" (guideline)
- "Panic Recovery" (note)
- "Graceful Degradation" (pattern)

No exact keyword match needed, concept match sufficient.

### 11. Build for Humans, Enable AI

**Principle**: Humans are the primary users, AI is the assistant.

**Why**: AI should enhance human workflows, not replace them.

**Implementation**:
- **Human-readable formats**: Markdown, YAML
- **Human-editable**: Any text editor works
- **Human-discoverable**: `ls .kogral/notes/` shows files
- **AI-enhanced**: MCP for AI-assisted queries

**Example**:

```bash
# Human workflow
vim .kogral/notes/my-note.md    # Edit directly
git add .kogral/notes/my-note.md
git commit -m "Add note about X"

# AI-enhanced workflow
# (in Claude Code)
"Add a note about X with tags Y, Z"
# AI creates file, human reviews
```

### 12. Embrace the Graph

**Principle**: Knowledge is interconnected, embrace the relationships.

**Why**: Context comes from connections, not isolation.

**Implementation**:
- Typed relationships (not just "related")
- Bidirectional traversal
- Relationship strength (0.0-1.0)
- Multi-hop queries

**Example**:

```text
Find all patterns that:
  - Are implemented by current project
  - Depend on shared guidelines
  - Were added in the last 6 months

# Graph query, not sequential file search
```

## Anti-Patterns to Avoid

### 1. ❌ Hardcoding Behavior

```rust
// Don't
const EMBEDDING_MODEL: &str = "BAAI/bge-small-en-v1.5";

// Do
let model = config.embeddings.model.as_str();
```

### 2. ❌ Runtime Schema Validation

```nickel
// Don't validate at runtime
let provider = config.provider; // Might be invalid

// Do validate at export time (Nickel contracts)
provider | [| 'openai, 'claude, 'fastembed |]
```

### 3. ❌ Opaque Errors

```rust
// Don't
Err("Failed".into())

// Do
Err(KbError::NodeNotFound(id.to_string()))
```

### 4. ❌ Coupling Components

```rust
// Don't
impl KnowledgeBase {
    fn search(&self) -> Vec<Node> {
        let embeddings = FastEmbedProvider::new(); // Hardcoded!
        // ...
    }
}

// Do
impl KnowledgeBase {
    fn search(&self) -> Vec<Node> {
        if let Some(provider) = &self.embeddings {
            // Use configured provider
        }
    }
}
```

### 5. ❌ Proprietary Formats

```text
// Don't
Binary blob: [0x4B, 0x42, 0x01, ...]

// Do
Markdown + YAML:
---
id: note-1
---
# Content
```

## Influences

KOGRAL draws inspiration from:

- **Logseq**: Outliner, graph view, wikilinks
- **Obsidian**: Markdown-first, local storage, plugins
- **Zettelkasten**: Atomic notes, links, emergence
- **ADR**: Decision records, context preservation
- **Git**: Version control, branching, merging
- **Nickel**: Type-safe configuration, contracts
- **MCP**: AI integration protocol
- **SurrealDB**: Graph database, relationships

## Implementation Principles

### Rust

- Zero unsafe code (`#![forbid(unsafe_code)]`)
- No `unwrap()` in production code
- Always use `Result<T>` for fallibility
- Comprehensive error types with `thiserror`
- Full test coverage (100+ tests)

### Nickel

- Contracts for validation
- Defaults in schemas
- Documentation in contracts
- Composition via imports

### NuShell

- Structured data pipelines
- Error handling in scripts
- Colored output for UX
- Dry-run modes

## Evolution Strategy

KOGRAL follows these guidelines for evolution:

1. **Backward Compatibility**: Don't break existing configs
2. **Deprecation Period**: Warn before removal (1 major version)
3. **Migration Tools**: Provide automated migrations
4. **Semantic Versioning**: MAJOR.MINOR.PATCH strictly

## Conclusion

These principles guide every decision:

✅ **Config-driven**: Behavior in schemas, not code
✅ **Type-safe**: Validate before runtime
✅ **Local-first**: Works offline, cloud optional
✅ **Git-friendly**: Knowledge versions with code
✅ **AI-native**: Optimized for AI, readable by humans
✅ **Composable**: Small pieces, loosely coupled
✅ **Fast feedback**: Fail early, clear errors
✅ **Discoverable**: Easy to find what you need

The goal: **Knowledge management that developers actually use.**

## Next Steps

- **See it in action**: [Use Cases](../guides/use-cases.md)
- **Understand architecture**: [System Overview](../architecture/overview.md)
- **Start using**: [Quick Start](../guides/quickstart.md)
